せっかく書いたスクリプトの使い方を忘れるのでツールを作った

色々なタスクを効率化するために小さなスクリプトを書くことが多いんですが、久しぶりに使おうとすると引数の取り方を忘れて実行できなかったり、そもそもスクリプトが見つからなかったり、 もはやスクリプトを書いたことを思い出せない …なんてことがあります。

特定のプロジェクトに関するものであれば、makeだったりnpm scriptで良いんですが、個人用に作ったスクリプト達をどうしようか悩んでました。 で、スニペットツールで何とかしようと思ったのですが、引数渡せなかったり、ワンライナーで書くのが辛かったり、手厚いヘルプが書けなかったりと、少しだけリッチなスクリプトを扱うには向いていない感じでしたので、自作しました。

作ったもの

置き場: https://github.com/tanksuzuki/jig

jigという軽量なタスクランナーで、実行するスクリプトはTOMLでヘルプ情報と共に定義します。 シェルスクリプトで書いた処理を、jigのサブコマンドとして追加していく使用感です。 jig自体はGolangで書いてます。

シェルスクリプトのカジュアルに書ける感じと、コマンドラインツール並のUIが同居できたら嬉しい的な意図で作ってます。

インストール

LinuxとLinux on Windowsな方はリリースページからダウンロードしてくださいませ。
Macな方はbrewでインストールできます。

brew tap tanksuzuki/jig
brew install jig

使い方

まずは下記のサンプルTOMLを、~/jig.tomlとして保存します。

[[script]]
name = "example" # 必須
args = "<arg1> <arg2>"
description = """
サンプルスクリプトです。1行目はリストで表示されます。
descriptionの2行目以降は、jig -h <script_name>で表示されます。
"""
exec = """
echo '$#': $#
echo '$0': $0
echo '$1': $1
echo '$2': $2
"""

[[script]]
name = "edit"
description = "~/jig.tomlをvimで編集"
exec = "vim ~/jig.toml"

jigだけで実行すると、実行可能なスクリプトのリストが表示されます。

$ jig

edit                     ~/jig.tomlをvimで編集
example <arg1> <arg2>    サンプルスクリプトです。1行目はリストで表示されます。

スクリプトの使い方を忘れて困った時は、jig -h <script_name>で詳細を表示できます。 descriptionの全文が表示されるので、引数の例や、スクリプトを使う前の前提条件を書いておくと便利です。

NOTE: -hは必ず スクリプト名より前 に指定してください。

$ jig -h example

Usage:
  jig example <arg1> <arg2>

サンプルスクリプトです。1行目はリストで表示されます。
descriptionの2行目以降は、jig -h <script_name>で表示されます。

スクリプトはjig <script_name>で実行できます。

$ jig example hello tanksuzuki

$#: 2
$0: example
$1: hello
$2: tanksuzuki

スクリプト名より後に渡した引数は、スクリプトに引数として渡されます。 通常$0は実行コマンド名になりますが、jigの場合はスクリプト名になります。 また、jigの終了コードはスクリプトの終了コードを引き継ぎます。

以上のサンプルは~/jig.tomlを読み込んで実行しましたが、 パスを変更したい場合は、-c|--configオプションで指定するか、$JIG_CONFIGにパスを設定してください。

TOMLから別のTOMLを読み込む

TOMLが巨大になって扱いづらい場合は、下記のように別のTOMLを読み込むことができます。

[[import]]
path = "~/.jig/child.toml"
prefix = "child_" # child.tomlの各スクリプト名にchild_を付与します(オプション)

タブ補完

下記を.bashrcあたりに書いておくと、スクリプト名がタブ補完できて幸せになります。

_jig()
{
  local cur=${COMP_WORDS[COMP_CWORD]}
  local prev=${COMP_WORDS[`expr $COMP_CWORD - 1`]}

  case "$prev" in
  "jig" | "-h" | "--help" )
    COMPREPLY=( $(compgen -W "`echo $(jig | awk '{print$1}')`" -- $cur) );;
  * )
    COMPREPLY=( $(compgen -f $cur) );;
  esac
}
complete -F _jig jig

今後の改良について

細かな使い勝手の点は改善していきますが、無闇に太らせて複雑にしたくないので機能追加については考えていません。 不足している機能は、スクリプトを追加すれば大体のことは解決するので(サンプルのeditのように)、 個々の好みに応じて育てていくのが良いんじゃないかなと思っています。