おはげようございます。朝の三分雑ハッキングのお時間です。
追記
以下のようにスクリプトをモジュールとして利用することでワンライナーっぽいことが出来るようになった。ちょっとうれしい。
#!/usr/bin/env python import re import sys def foo(): for line in sys.stdin: match = re.match(r'^([a-z\-]*):(?:.*)#\s*(.*)$', line) if match: print match.group(1).ljust(12) + '....... ' +match.group(2)
以下のように...。
% python -c 'from make_tasks import foo; foo()' < Makefile all ....... Execute all tasks hello ....... Execute hello(タスクの説明) world ....... Execute world(タスクの説明)
Makefile には以下のように組み込んでおく。
default: @echo Makefile for MyTask @echo @echo Usage: make [task] @echo @echo Tasks: @python -c 'from make_tasks import foo; foo()' < Makefile all: hello world # Execute all tasks hello: # Execute hello(タスクの説明) @./hello.sh && { echo "success!" ; exit 0; } || { echo "failure!" | ./notification.sh ; exit 1; } world: hello # Execute world(タスクの説明) @./world.sh && { echo "success!" | ./notification.sh ; exit 0; } || { echo "failure!" | ./notification.sh ; exit 1; }
make
を叩くと以下のようになる。
% make Makefile for MyTask Usage: make [task] Tasks: all ....... Execute all tasks hello ....... Execute hello(タスクの説明) world ....... Execute world(タスクの説明)
おお、「一応」ワンライナーいけた。
tl;dr
幾つかのスクリプトをタスクとして make コマンドで実行するようにしてみたけど、make
だけ叩いた時には実行可能なタスク一覧を表示するようにしたいなと思ってトライした。(rake -T
でタスク一覧がザザって出力されるようにしたい!)
既に(参考)
以下のように実装されている方がいらっしゃったので、これを参考にさせて頂いて Python を利用して実装してみた。
上記の例では Ruby のワンライナーが炸裂しているが、流石に Python のワンライナーは個人的に敷居が高かったのが悔やまれる。
memo
以下のような Makefile で進める
default: @echo Makefile for MyTask @echo @echo Usage: make [task] @echo @echo Tasks: @./make_tasks.py < Makefile all: hello world # Execute all tasks hello: # Execute hello(タスクの説明) @./hello.sh && { echo "success!" ; exit 0; } || { echo "failure!" | ./notification.sh ; exit 1; } world: hello # Execute world(タスクの説明) @./world.sh && { echo "success!" | ./notification.sh ; exit 0; } || { echo "failure!" | ./notification.sh ; exit 1; }
各タスク名の後ろの #
以降にタスクの説明を記載する。
make だけ叩いた場合の挙動
- 一番冒頭に定義しているタスクが実行される
- これを利用する
default タスク
参考にさせて頂いて make
だけ叩かれた際に実行されるタスクを default
タスクとして以下のように定義。
default: @echo Makefile for MyTask @echo @echo Usage: make [task] @echo @echo Tasks: @./make_tasks.py < Makefile
タスク一覧出力を担うのは最終行の ./make_tasks.py < Makefile
の部分。雑な Python スクリプトに Makefile 自身を読み込ませている。
雑な Python スクリプト
#!/usr/bin/env python import re import sys for line in sys.stdin: match = re.match(r'^([a-z\-]*):(?:.*)#\s*(.*)$', line) if match: print match.group(1).ljust(12) + '....... ' +match.group(2)
re
のmatch
メソッドを利用して標準入力からタスク名だけを抽出- マッチしない行は
None
となる - マッチした行の内容は
group
メソッドで出力することが出来る - また、
group
メソッドに添字をつけてマッチした文字列を抽出することも出来る
実際にスクリプトだけを実行すると以下のように出力される。
% ./make_tasks.py < Makefile
all ....... Execute all tasks
hello ....... Execute hello(タスクの説明)
world ....... Execute world(タスクの説明)
また、マッチしない行も出力するようにしてみると以下のように出力される。
% ./make_tasks.py < Makefile None None None None None None None None <_sre.SRE_Match object at 0x101045580> None <_sre.SRE_Match object at 0x101045580> None None <_sre.SRE_Match object at 0x101045608> None
マッチしている部分がオブジェクトとして出力されている。
実際に make だけを叩いてみる
満を持して叩いてみる。
% make Makefile for MyTask Usage: make [task] Tasks: all ....... Execute all tasks hello ....... Execute hello(タスクの説明) world ....... Execute world(タスクの説明)
おお、それっぽい感じになった。