注意
- 既にHomebrewが使える状態になっていることが前提
- zshやbash周りの整理も終わっている人向け
用語
formulae
formulaの複数形
formulaはHomebrew内でのパッケージ名のようなもの
zsh、bash
zsh
Z shellはUnixのコマンドシェルの1つである。 対話的なログインコマンドシェルとしても、強力なシェルスクリプトコマンドのインタープリターとしても使うことができる。 zsh は数多くの改良を含んだBourne Shellの拡張版という見方もできる。
- Wikipedia
bash
BashはUnixシェルかつコマンド言語であり、GNUプロジェクトにおけるBourne Shellのフリーソフトウェアによる代替としてブライアン・フォックスによって作成された。
- Wikipedia
Homebrewでいつもやることといえば
- Homebrewのアップデート
- formulaeのアップデート
- 期限切れのformulaeの削除
- ドクター!
上記のことを自動化したい。
なぜなら、私の環境のせいかもしれないが異様に時間がかかるのだ。
ずっと見張っているわけにもいかないし、ちょくちょくみるのも面倒くさい。
ということで、全部自動化して終わったら通知を送信してくれるような感じにしておきたいと思ったのだ。
Homebrewのコマンド集め
Homebrewのアップデート
brew update
formulaeのアップデート
brew upgrade
期限切れformulaeの削除
brew cleanup
ドクターを呼ぶ
brew doctor
applescriptの核
まずはどれくらい時間がかかるかわからないのでタイムアウトを設定
with timeout of (60 * 60 * 6) seconds
end timeout
まあ、6時間ぐらい設定してれば余裕でしょっていう
次に、各brewコマンドを実行する
tell application "Terminal"
do script "brew update" in window 1
do script "brew upgrade" in window 1
do script "brew cleanup" in window 1
do script "brew doctor" in window 1
end tell
ここで問題になるのが、それぞれの処理がどれくらい時間がかかるかわからないという点だ。
連続して実行しようとすると大変なことになる…と思う。
そこで対策として、Terminalのタイトルを取得して対策してみようということ。
実行部分の問題点の解決
最初のウィンドウの名前を取得してからそれを格納する。
get name of window 1 --Terminalに対するtellの中
set firstTitle to result
次にループ処理をして、現在のウィンドウタイトルを取得して比較、最初のウィンドウタイトルになったら処理を続行する。
repeat
get name of window 1
set nowTitle to result
if firstTitle is nowTitle then exit repeat
delay 1
end repeat
スクリプト中に何回も書くと読みにくいのでこれを関数化する
on waitForComplete(firstTitle)
delay 3
tell application "Terminal"
repeat
get name of window 1
set nowTitle to result
if firstTitle is nowTitle then exit repeat
delay 1
end repeat
end tell
end waitForComplete
最初のdelayはすぐに取得すると実行前のウィンドウタイトルを取得する可能性があるからだ。
なので、brewコマンド実行部分はこうなる
tell application "Terminal"
do script "brew update" in window 1
my waitForComplete(firstTitle)
do script "brew upgrade" in window 1
my waitForComplete(firstTitle)
do script "brew cleanup" in window 1
my waitForComplete(firstTitle)
do script "brew doctor" in window 1
my waitForComplete(firstTitle)
end tell
処理の完成
今までのものと、最初にterminalで新しいウィンドウを開く処理、最後にダイアログを表示する処理をして終了。
with timeout of (60 * 60 * 6) seconds
tell application "Terminal"
do script ""
activate
delay 2
get name of window 1
set firstTitle to result
end tell
delay 1
tell application "Terminal"
do script "brew update" in window 1
my waitForComplete(firstTitle)
do script "brew upgrade" in window 1
my waitForComplete(firstTitle)
do script "brew cleanup" in window 1
my waitForComplete(firstTitle)
do script "brew doctor" in window 1
my waitForComplete(firstTitle)
display alert "処理終了"
end tell
end timeout
on waitForComplete(firstTitle)
delay 3
tell application "Terminal"
repeat
get name of window 1
set nowTitle to result
if firstTitle is nowTitle then exit repeat
delay 1
end repeat
end tell
end waitForComplete
実行すると、4つの処理が終了してから"処理終了"と表示されたダイアログが表示されるはずだ。
これをアプリとして書き出せば、ダブルクリックだけでbrew周りのめんどくさい処理が終わる。
備考
変数名がいいのを思いつかなくて、関数での受け取り変数とコード本文中の変数名を同じにしてしまったが、いいのが思いつく人は変えたほうがいいと思う。
だいぶ無駄なコードも書いたかなと思いもするが、まあ動くし、保守もあまり必要ないはずなので(もし使い物にならなくなったらゴミ箱にポイしていいしね)いいかなと言う感じ。
ホントはもっときれいに書くべきだとは思うのだけれど、記事を書きながら組んだので、これをまたクリーンアップしていくのが正直面倒くさい。
のでやらない。
注意
このコードを動かしている最中は他の作業はしていいが、Terminalを使ってはいけない。
これにはウィンドウサイズの変更なんかも含まれる。
おわり。