NSTaskで対話型コマンドを呼出す¶
ditzをCocoaから呼出す方法を調べていた。 ditzはユーザーと対話しながら実行するサブコマンドが多い。
そのためNSTaskで実装するには、ユーザーからの入力を偽装するNSPipeをNSTaskに接続し、適切なタイミングで文字列を流し込む必要がある。
その正攻法では面倒だし、コードが判りにくいと思っていたら面白いUnixコマンドを見つけた。
"expect"と呼ばれるunixコマンドです。このexpectは対話型のUnixコマンドを操作する為のunixコマンドと言うべき物でした。
詳細は以下のURLを参照してください。
ditzをexceptを使って操作すれば、NSTaskへ投げっぱなしで問題なく実行出来そうだ。
例えば、以下のようなditzでissueを追加するラッパーを作った。
コマンド名 |
addIssue.sh |
引数1 |
タイトル |
引数2 |
詳細 |
引数3 |
bugか機能かタスクか |
引数4 |
作成者名 |
引数5 |
コメント |
呼出し方はこう
$ ./addIssue.sh すごいバグ 詳しく説明 b mymail@address 色々とコメント
ソースコードはこう
#!/bin/sh
TITLE=$1
DESCRIPTION=$2
BFT=$3
CREATOR=$4
COMMENT=$5
expect -c "
set timeout 5
spawn ditz add
expect \"Title:\"
send $TITLE
send \"\n\"
expect \"Description (\*):\"
send $DESCRIPTION
send \"\n\"
send \".\"
send \"\n\"
expect \"Is this a (b)ugfix, a (f)eature, or a (t)ask? \"
send $BFT
send \"\n\"
expect \"Issue creator (enter for \*):\"
send $CREATOR
send \"\n\"
expect \"Comments (\*):\"
send $COMMENT
send \"\n\"
send \".\"
send \"\n\"
interact
"
こんなコマンドをbundleに持たせて、NSTaskで呼出せばCocoaでややこしいプログラムを組まなくて良さそうです。
ついでに、issueの追加ではなくてtaskの追加専用のコマンドにしてみたり、エラーチェックを追加してみた。。
#!/bin/sh
####################
# 事前条件チェック
####################
# 引数の数をチェック
if [ $# -ne 4 ]
then
echo "指定された引数は$#個です。" 1>&2
echo "実行するには4個の引数が必要です。" 1>&2
exit 1
fi
# ditzが実行パス中に有るかチェック
which ditz >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "ditzがインストールされていません。" 1>&2
exit 1
fi
# ditzのバージョンをチェック
VERSION=`ditz --version | cut -d ' ' -f 2`
if [ $VERSION != "0.5" ]
then
echo "インストールされているditzのバージョンは{$VERSION}です。" 1>&2
echo "対応しているditzのバージョンは0.5です。" 1>&2
exit 1
fi
# 引数を判り易い変数名にしておく
TITLE=$1
DESCRIPTION=$2
CREATOR=$3
COMMENT=$4
expect -c "
set timeout 5
spawn ditz add
expect {
default {exit 2}
\"Title:\" {send $TITLE; send \"\n\"}
}
expect {
default {exit 3}
\"Description (\*):\" {send $DESCRIPTION; send \"\n.\n\"}
}
expect {
default {exit 4}
\"Is this a (b)ugfix, a (f)eature, or a (t)ask? \" {send \"t\n\"}
}
expect {
default {exit 5}
\"Issue creator (enter for \*):\" {send $CREATOR; send \"\n\"}
}
expect {
default {exit 6}
\"Comments (\*):\" {send $COMMENT; send \"\n.\n\"}
}
expect eof
"
case "$?" in
0) exit 0 ;;
2) echo "Titleの入力がエラーです。" 1>&2 ; exit 1 ;;
3) echo "Descriptionの入力がエラーです。" 1>&2 ; exit 1 ;;
4) echo "Issue typeの入力がエラーです。" 1>&2 ; exit 1 ;;
5) echo "Issue creatorの入力がエラーです。" 1>&2 ; exit 1 ;;
6) echo "Commentsの入力がエラーです。" 1>&2 ; exit 1 ;;
*) echo "不明なエラーです。" 1>&2 ; exit 1 ;;
esac
exit 0
DitzのGUIフロントエンドを作るにあたって、後調べなければならない事はファイルのアップデートのタイミングを知る為の"FSEvent"を調査する必要がある。
Comments
comments powered by Disqus