weblog of key_amb

主にIT関連の技術メモ

"clenv" というシェルスクリプトのパッケージ管理ツールのようなものを作った

主に先月、開発していました。
いまバージョンは 0.1.12 です。

最近、久しぶりにやりかけだった機能拡張を進めようかと思ったのですが、拡張した機能を今後、自分自身でもあまり使うイメージが持てなくて、現状をひとまずこの記事にまとめておくことにしました。

目次:

clenv とは

シェルスクリプトのパッケージ管理システムがあったら、流行るんじゃないかという妄想があって、試しにちょっと作ってみた、という感じです。

今のところ、シェルスクリプトに限らず、コマンドラインで実行可能なファイルをまとめる用途には使えるかな、というぐらいのもので、実際に自分でも使っています。

できること:

  • $CLENV_ROOT/shims/ というパス配下にモジュールの実行ファイルの symlink を貼る
  • $CLENV_ROOT/environments/ に任意の名前で「環境」を作り、モジュール群をその「環境」にインストール

お察しかと思いますが、clenv という名前は rbenvplenv の類推です。

clam モジュール

clenv で利用されるモジュールを clam モジュールと呼ぶことにしました。

モジュールの形式としては「Git リポジトリ」か、「ローカル環境からアクセスできるファイルシステム内の特定ディレクトリ」のみサポートされています。
いずれの場合も、clam.spec というファイルをトップ階層に持つ必要があります。

拙作のシェルスクリプトテストツールである shove も、実はこの clam モジュール形式に対応しておりまして、その clam.spec は下のようになっています。

# bash
name=shove
version=0.7.2
executables=bin/shove
resources=lib/*

このファイルは clam という bash スクリプト内で評価されます。

clam スクリプトRubygem, Perlcpan コマンド相当です。

clam https://github.com/key-amb/shove.git を実行すると shoveclenv の環境下にインストールします。
デフォルトの default environment を使っている場合、$CLENV_ROOT/environments/ 以下のディレクトリ構成は以下のようになります。

~/.clenv/environments
└── default
    ├── Clamdb.txt
    ├── bin
    │   └── shove -> ~/.clenv/environments/default/modules/shove/bin/shove
    ├── lib
    │   ├── shove.bashrc -> ~/.clenv/environments/default/modules/shove/lib/shove.bashrc
    │   └── t.shrc -> ~/.clenv/environments/default/modules/shove/lib/t.shrc
    └── modules
        └── shove/ # モジュールのディレクトリが丸っとコピーされる

で、 ~/.clenv/environments/default/bin~/.clenv/shims に symlink されるので、 ~/.clenv/shims に PATH を通しておけば shove をパスなしで実行できる、というわけです。

clam を使う前に 〜 clenv セットアップ

順番が前後したのですが、上の clam の機能を使う前に clenv のセットアップが必要です。
README.md にも書いている通りですが、転記しておきます。

インストール:

git clone https://github.com/key-amb/clenv.git ~/.clenv

シェルの設定:

export CLENV_ROOT=$HOME/.clenv
export PATH="$HOME/.clenv/bin:$PATH"
export PATH="$HOME/.clenv/shims:$PATH"
. ${CLENV_ROOT}/shrc.d/clenv.shrc

初回はこれを .bashrc ないし .zshenv に書いて exec $SHELL -l を実行して下さい。
最後の . clenv.shrcclenv_switchclenv_use という2つのシェル関数をロードします。

環境の作成には clenv init-env [ENV] を実行します。(ENV のデフォルトは default)
これは $CLENV_ROOT/environments/ 以下に所定のディレクトリを作るだけです。

clenv_switch ENV で、~/.clenv/environments/ENV/bin~/.clenv/shims に symlink されます。
clenv_use ENV だと更に ~/.clenv/environments/ENV/lib/*シェルスクリプトとして現在のシェルに読み込みます。(が、この機能は要らないかなと思っていたりします。)

その他便利かもしれない使い方

Clamfile

RubyGemfile, Perlcpanfile 相当です。

モジュールをこのファイルに記述して clam -r Clamfile でまとめてインストールできます。
気になる方は README.md をご覧ください。

任意の実行ファイルを勝手に clam 化してインストール

「この実行ファイルに PATH を通したいから clenv 下に入れておきたい」というときに便利な使い方です。
単純にソースをローカルにダウンロードして clam.spec を記述すればいいです。

wget https://example.com/any-program.zip
unzip any-program.zip
cd any-program
cat <<EOS > clam.spec
name=any-program
version=0.x
executables=bin/*
EOS
clam . # インストール

こんな感じで any-program/bin/* 以下の実行ファイルに PATH を通せます。

clenv を作ってよかったこと

自分は割とリポジトリを細かく分ける性格で、小さな CLI を含むリポジトリがちらほらあります。
clenv 以前は、それらを submodule にまとめて管理していました。 その管理や、各環境で PATH を通す作業がやや面倒だったのですが、clenv + clam に移行して Clamfile だけの管理になったので、ちょっと楽になった気がします。

clam は消すのも簡単なので、ツールを試しに使うようなときに、とりあえず PATH を通しておくことも気軽にできます。

あれ、シェルスクリプトあんまり関係ない…?

そうなんです。
一応シェル・リソースをロードする機能もあるにはあるのですが、今のところ、「任意の実行ファイルをまとめる君」になっており、「シェルスクリプトのパッケージ管理ツール」としては不完全かな、と思います。

最初に考えていた構想では、シェル関数などを再利用しやすいようにしようなどの企てもあったのですが、今は手が止まってる感じです。
Bash でライブラリ関数的なものを作る気になったら、この構想も進めたい気持ちが高まるかもしれません。

Zsh だとけっこうプラグインがたくさんあって、プラグインの管理ツールもあるようなので、ひょっとしたらここで考えているようなことは実現されているかもしれませんね。

(そもそもシェル関数にしたいケースってけっこう限られそうだと最近思いました。その話はまた機会があれば。)

他に似たようなものないの?

シェルスクリプトのパッケージ管理システムとして見つけたのは下の2つです。

それぞれ、各々のフレームワークの中でモジュール化して再利用できそうな雰囲気ですが、さらっと眺めたところ、各々の形式に合わせてモジュール/パッケージを作らないといけなさそうな感じ。
自分が妄想しているものとは少し違うかなー、と思いました。

余談 〜 shove との関係

下の記事でもちらっと言及していましたが、shove を作ったのは、この clenv のテストを書くためでした。

おわりに

…というわけで、かなり個人用途な感じのツールですが、GitHub で公開していますので、ご利用・ツッコミなどご自由にどうぞ。

また、他に「こういうのあるよ」という情報をいただけましたら幸いに思います。

Enjoy!