"clenv" というシェルスクリプトのモジュール管理ツールを引き続き作っている
上の記事を書いたのが3ヶ月前ですね。
趣味で作っているのでだいぶ波があるのですが、初コミットからは5ヶ月ほど経ちました。
- "clenv" って何?
- "clam" モジュール
- NEW - "cload" コマンドと "cllib" 関数
- NEW - shims/ に shim を置くことにした
- Travis CI で継続的にテストできるようにした
- clenv 環境で使える Bash 用の Logger モジュールを書いてみた
- 今後
- 脚注
"clenv" って何?
https://github.com/key-amb/clenv です。
説明は上の記事に書きましたが、一応こちらでもかんたんに。
私が趣味で作っているツールで、シェルスクリプトの実行ファイルやライブラリをモジュール化して管理できるようにしてくれるものです。
名前はお察しの通り、rbenv など 〜env が由来です。
"version" という語ではなく "environment" という語を使っています。
"version" だと異なるバージョンのシェルをビルドしてインストールして…のようなことを連想されそうだな、と思いまして。
そういうのをできるツールがあってもいいとは思いますが、それをやる気はない。
"clam" モジュール
これも冒頭の記事に書いたのですが、clenv で使うモジュールを "clam" モジュールと呼ぶことにしました。
git の URL か、ローカルのファイルシステムからインストールできます。
モジュール側では clam.spec
というファイルを用意しておく必要があります。
これのファイル形式が v0.3 で少し変わりました*1。
まあ、詳しくは README や脚注の PR をご覧くださいということで。
NEW - "cload" コマンドと "cllib" 関数
v0.2 で導入しました。
.
or source
相当ですが、 CLOAD_PATH
という環境変数の path を見て、そこからの相対パスで読み込めるものです。
これで ruby や perl の require 相当のことができる、と考えました。
面倒なのは、これをシェルの関数で提供しなければならないことです。
スクリプティングにおいては、シェル関数を読み込むコードを一行足すか、 eval
実行する必要があります。
使い方としては、下のようになります。
# 例1 eval $(cload "mylib") eval $(cload "mylib/foo") # 例2 eval $(cload -) cllib "mylib" cllib "mylib/foo"
ここで、 cllib
が "cload" のシェル関数版です。
eval $(cload -)
をやってくれるラッパーコマンドを作ればいいじゃないか、と思う人もいるかもしれませんが、そうすると実行スクリプトを .
または source
して実行せざるを得なくなる気がします。
ので、厳しそう。
NEW - shims/ に shim を置くことにした
v0.2 までは、 shims => environments/$CLENV_ENVIRONMENT/bin
と symlink していただけですが、 rbenv を参考にランチャーとなるシェルスクリプトの実体を置くことにしました。
clam install
するときに、下のようなファイルを実行ファイルと同じ名前で shims/ 以下にコピーしています。
#!/usr/bin/env bash set -euo pipefail [[ ${CLENV_DEBUG:-} ]] && set -x program="${0##*/}" exec "${CLENV_ROOT}/bin/clenv" exec "$program" "$@"
だいたい rbenv や plenv と同様で、clenv exec
で対象のコマンドを探して exec します。
Travis CI で継続的にテストできるようにした
シェルスクリプトでどうやるのかな、と思っていたところ、 b4b4r07/enhancd で Travis が設定されていたので、参考になりました。
実行ファイル系は Bash 前提で書いていますが、シェル関数で機能提供するものは POSIX シェルで動くように書いています。
ので、 make test
タスクもそんな感じで書いています。
いま CI 環境 だと、Ubuntu v12.04 のコンテナで sh
, bash
, dash
で CI が走っています。
あらゆる環境で動作保証するものではないけど、まあ、だいたい動くんじゃないかな、というところ。
※テスト足りてないところは色々あります。
clenv 環境で使える Bash 用の Logger モジュールを書いてみた
https://github.com/key-amb/bash-logger
これです。これ自体は bash スクリプト1枚なので、これだけダウンロードして単独で使うこともできます。
clenv 環境にインストールするには clam https://github.com/key-amb/bash-logger.git
で。
clenv 環境でこれを使うサンプルコードは下のようになります。
# myapp.bash eval $(cload logger.bashrc) log.info "foo" log.warn "warn"
実行すると下のようになります。
% ./myapp.bash 2016-09-19 08:47:35 [INFO] foo 2016-09-19 08:47:35 [WARN] warn
(本当はログレベルに応じて色が変わります。)
まあ、こういうことがやりたいわけです。
つまり、再利用性のあるライブラリを書いて、再利用して楽にスクリプティングしたい。
今後
shims/ 以下は実体を置くことができたのですが、 environments/$env/{bin,lib}
以下がまだインストールした module への symlink になっているので、それも実体にしないと、ライブラリ同士のディレクトリ構成に依存関係があるときに上手く行きません。
解決する方法は2通りあります。
- bin/, lib/ 以下にも中身をコピーする
- uninstall できるように、何をコピーしたか記録しておかなければなりません
- bin/, lib/ 以下に実体は置かない。
cload
時に任意のモジュールについてenvironments/$env/$module/
以下の path を CLOAD_PATH に追加して解決する
前者は clam install/uninstall で頑張る。後者は cload で頑張る感じ。
後者にしても、 bin/ 以下には RubyGems で言うところの binstub 相当を置かないといけないですが、それでも uninstall はだいぶ楽になりそうです。
また、後者にすると同一モジュールでも複数バージョンインストールできるようになったりと、(ニーズはさておき)夢が広がりそうです。
趣味でやっているので、いつになるかわかりませんが、ご興味ありましたら、完成までは気長にお待ちください。
現時点でも上に書いたようなことや、冒頭の記事で書いたような実行ファイルの管理に使えると思います。というか、使っています。
…が、今後、互換性のない変更が入る可能性はありますので、ご注意ください。
脚注
*1:https://github.com/key-amb/clenv/pull/3 https://github.com/key-amb/clenv/pull/4