"clenv" というシェルスクリプトのパッケージ管理ツールのようなものを作った
主に先月、開発していました。
いまバージョンは 0.1.12 です。
最近、久しぶりにやりかけだった機能拡張を進めようかと思ったのですが、拡張した機能を今後、自分自身でもあまり使うイメージが持てなくて、現状をひとまずこの記事にまとめておくことにしました。
目次:
- clenv とは
- clam モジュール
- clam を使う前に 〜 clenv セットアップ
- その他便利かもしれない使い方
- clenv を作ってよかったこと
- あれ、シェルスクリプトあんまり関係ない…?
- 他に似たようなものないの?
- 余談 〜 shove との関係
- おわりに
clenv とは
シェルスクリプトのパッケージ管理システムがあったら、流行るんじゃないかという妄想があって、試しにちょっと作ってみた、という感じです。
WindowsでBashが動くようになったからといって2016年はBashが流行るというのは安直だけど、誰かがいい感じのパッケージ管理システムを作ったら、すごく流行る気がする。
— きいあむ → @progrhyme (@key_amb) 2016年4月11日
今のところ、シェルスクリプトに限らず、コマンドラインで実行可能なファイルをまとめる用途には使えるかな、というぐらいのもので、実際に自分でも使っています。
できること:
$CLENV_ROOT/shims/
というパス配下にモジュールの実行ファイルの symlink を貼る$CLENV_ROOT/environments/
に任意の名前で「環境」を作り、モジュール群をその「環境」にインストール
お察しかと思いますが、clenv という名前は rbenv や plenv の類推です。
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 スクリプトは Ruby の gem, Perl の cpan コマンド相当です。
clam https://github.com/key-amb/shove.git
を実行すると shove
を clenv の環境下にインストールします。
デフォルトの 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.shrc
は clenv_switch
と clenv_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
Ruby の Gemfile, Perl の cpanfile 相当です。
モジュールをこのファイルに記述して 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!
アラートをまとめるシステム "poloxy" の v0.2 をリリースしました
前回の記事で紹介した poloxy をその後リリースして、本稿の執筆時点で v0.2.1 までバージョンが進みました。
※5/8 v0.3.1 になったので追記しました。
目次:
- "poloxy" とは
- Motivation
- Current Status (※5/8 追記アリ)
- Milestone
- (余談) Another Approach 〜 Fluentd との相似について
- 5/8 追記: AdminLTE という UI テンプレートについて
"poloxy" とは
繰り返しになるので詳しい説明は割愛しますが、スライドや README に載せている図を再掲しておきます。
こんな感じで、アラートをまとめて通知してくれるものです。
まとめられたアラートの内容は Web Dashboard で確認できます。
Motivation
サーバサイドアプリケーションの開発・運用従事者の方は何かやらかしてアラートを大量に飛ばした経験はあるでしょうか。
私は、あります^^;
アラートがたくさん届くと心臓に悪いですね。
たくさんアラートが発火したとしても、1通にまとまって届いてくれたら安心ですね。
…というわけで、それをやってくれるものを作ってみた、というものです。
4/28 の西日暮里.rb で、発表スライドの3ページ目に「1時間に1000件以上アラートを受信したことがある人」という質問を入れていました。
発表中に聞いてみたところ、若干名いらっしゃったので、多少はニーズがあるかなと思っています。
Current Status (※5/8 追記アリ)
できた:
- Web Dashboard
- HTTP API
- Worker
- 送信
- SMTP
- Slack
- まとめる
- 単位時間(1分程度。configで変更可能)に受信したアラートの品目単位
- 単位時間に受信したアラートのグループ単位
- 単位時間に受信したアラートの宛先(と送信タイプ)単位
- (5/8 追加) アラートのスヌーズ ... 単位時間じゃなくて一定時間アラートを飛ばさなくする
- 該当アラートと同じ (品目、グループ、深刻度) のアラートを
message.default_snooze
で設定した秒数(デフォルト30分)スヌーズします。
- 該当アラートと同じ (品目、グループ、深刻度) のアラートを
まだできてない:
- SMTP 受信/中継
- 古いデータのパージ機能
- WebUI でのページング等
その他スライド発表時点から変更した点:
- Redis キューを使わなくして、DB に統合しました
ドキュメントは今のところ README にざっと書いています。
config や curl のサンプルも載せているので、一応お試しいただけるかな、と思います。
Milestone
上の「まだできてない」に挙げていることは v1.0 リリースまでにはやろうと思っていることです。
趣味でやっていることもあり、いついつまでというのは特に決めてませんが。
試してみて「困った」など、何かフィードバックがありましたら、GitHub 等でお知らせ頂ければ幸いです。
(余談) Another Approach 〜 Fluentd との相似について
受信はさておき、送信は今後種類が増えるかもしれないので、Pluggable にしておいた方がよさそうです。
一応、それを見越して動的に各送信タイプの class をロードするようにしています。
そんなことを考えていたら、ふと「あれ、送信と受信があってなんだか Fluentd っぽい」と思った瞬間がありました。
ひょっとしたら、Daioikachan *1みたいに Fluentd の仕組みに乗っかった方が筋がよかっただろうか、とちょっと悩んでいたりします。
Fluentd の既存のプラグインでも、ログを間引いたり*2、suppression を入れたりできるもの*3はあるようなので、そっちのアプローチもアリだったかもしれません。
とはいえ、"poloxy" には Dashboard や DB が付いていたり、アラートのグルーピングなど独自な概念もあるので、Fluentd プラグイン化はやりすぎですかね。。
5/8 追記: AdminLTE という UI テンプレートについて
追記ついでに、AdminLTE について触れておきます。
自分にはフロントエンドをイチから作り込めるほどスキルも余裕もないので、Bootstrap ベースのテンプレートを使って、必要な部分だけカスタマイズする、という方針にしています。
"poloxy" の WebUI では、管理画面向けで多機能なテンプレートである AdminLTE を使ってみました。
その豊富な機能を使いこなすところまでは全然至っていませんが、作りたかった UI を割といい感じに整えることができたかなと思います。
いろいろパーツも揃っているので、便利です。
ドキュメンテーション用の Hugo のテーマ "bootie-docs" を改善しました #gohugo
Bootie Docs はちょうど一年前ぐらいにドキュメンテーション用の静的サイトジェネレータがほしくて作った Hugo*1 の Theme (テンプレート)です。
当時の記事はこちら:
色々イケてないところがあったので、GW 連休中にがっつり手を入れて、機能追加もしましたので、お知らせします。
ほとんど CHANGELOG に書いた内容に相当します。
※5/7 更に変更点有り、追記しました。
- デフォルトアイコンがかっこ悪い
- 依存コンポーネントを最新版にアップデートし、シンタックスハイライトのスタイルを選択可能に
- サイトマップ的なページを作った
- サイドバーをスクロールに追従するようにした
- Google のサイト検索機能を使った検索フォームを付けられるようにした
- (5/7 追記)メニューのテキストを変更可能に、任意ページをメニューに追加可能に
- (5/7 追記) カテゴリ > ページの一覧をサイドバーやTOPページで表示するようにした
- その他、細かいスタイルの改善
- 自分のプロダクトのドキュメントサイトも更新しました
- 終わりに
デフォルトアイコンがかっこ悪い
見るたびに気持ちが萎えていたので、パワーポイントでちょっと図形をいじって、こんな感じ になりました。
雰囲気おしゃれになったかなと。
依存コンポーネントを最新版にアップデートし、シンタックスハイライトのスタイルを選択可能に
Bootstrap と jQuery (v1系) と highlight.js を最新化しました。
highlight.js については、config.toml の params.highlightStyle
という設定値で好みのスタイルを選べるようにしました。
どんなスタイルがあるかは こちら に highlight.js のデモページがありますので、ご参考まで。
サイトマップ的なページを作った
/index/
というパスで全ページリストを表示できるようにしました。
Hugo は自由にディレクトリを切ってページを階層化できるのですが、2段階までは階層表示できます。
やり方は Bootie Docs の マニュアルサイト をアップデートしていますので、こちらをご確認下さい。
サイドバーをスクロールに追従するようにした
久しぶりに JavaScript を書きました。
Chrome, Firefox, Safari では動作確認しました。
※もっといい書き方があったら教えてほしい^^;
5/7 追記:
- ケータイなど幅の狭いブラウザで表示が崩れてしまっていたのを修正し、元通りのレスポンシブな表示になるようにしました。
Google のサイト検索機能を使った検索フォームを付けられるようにした
config で params.searchDomain
を設定した場合のみ、有効になります。
(5/7 追記)メニューのテキストを変更可能に、任意ページをメニューに追加可能に
今までは content/
直下のページ or section しかメニューに足せなかったのですが、v1.1.0 で任意ページを足せるようにしました。
これにより config の書き方が変わりましたので、ご注意下さい。
Before v1.0.x:
[params] mainMenu = ["about", "usage"]
After v1.1.0:
[[params.mainMenu]] name = "About" link = "about" [[params.mainMenu]] name = "Usage" link = "usage"
TOML の Array of Tables という記法を使っています。
下の書き方も試したのですが、たぶん Hugo 内部で使われているパーサが inline table 記法に未対応で、エラーになってしまいました。
[params] mainMenu = [ { name = "About", link = "about" }, { name = "Usage", link = "usage" }, ]
(5/7 追記) カテゴリ > ページの一覧をサイドバーやTOPページで表示するようにした
これにより、上述のサイトマップ的ページを設置する意義は薄れました^^;
まあ、お好みでどうぞ。
その他、細かいスタイルの改善
- table にスタイルが付いてなかったので、bootstrap の
.table-striped
,.table-bordered
相当のスタイルを付けて GitHub っぽく見えるようにした。 - コードブロック内が折り返しされていたので、折り返さないように。*2
- ページ幅が最大 970px だったが、1200px に変更
自分のプロダクトのドキュメントサイトも更新しました
見本としてご参考にどうぞ。
- http://key-amb.github.io/bootie-docs-demo/
- http://key-amb.github.io/App-Koyomi-Doc/
- http://key-amb.github.io/fireap-doc/ <-- NEW!
fireap は GitHub Wiki から引っ越しました。
Markdown 形式なので引越しそのものは簡単でした。
(※その過程で色々スタイルのイケてないところを見つけたので v1.0.1 => v1.0.2 になりましたが。)
終わりに
ドキュメント用のテーマとして、より使いやすくなったと思います。
Markdown でドキュメントを管理したいときに、選択肢としてご一考いただければ幸いです。
既にお使いの方は、ぜひアップデートしてみてください。*3
Enjoy!
*2:参考: Bootstrapを使った場合にpreタグを改行させたくない
*3:5/8 本家 hugoThemes にも最新版が取り込まれました :D https://github.com/spf13/hugoThemes/pull/133
西日暮里.rb で "poloxy" というアラートシステムの話をした #ninirb
昨夜、GW 突入前に下の勉強会に参加してきました。
poloxy は未完成なのですが、"pool" + "proxy" の造語で、通知の送信者と受信者の間で動いて、流量をコントロールしたりしてくれるものです。
「アラートまとめる君」と言うとわかりやすいでしょうか。
まだリリースバージョンは作っていませんが、リポジトリは GitHub で公開しています。
発表後にちょっとだけ README.md を作っておきました。
といっても、まだスライド以上の情報は(ソースコードを除いて)無いので、「どんなものか」というのはそちらを見てもらった方がよさそうです。
というわけで、下が発表したスライドです。
GW 中に 1st リリース出来るといいなあ、と思っています。
また、勉強会中に @mtsmfm さんから「Docker 化してはどうか」という示唆を頂きました。
@key_amb ただ engine はアプリ毎に組み込みたい場合だったりするけど今回はアプリそのものが公開したい気がしたのでタグだけうってまるっと公開しつつ dockerfile 置いとくのがいいのかもとかって思いました!
— Fumiaki MATSUSHIMA (@mtsmfm) 2016年4月28日
確かに、サーバアプリだし Docker ですぐに使えると便利ですね。
リリース後にトライしてみたいと思います!
西日暮里.rb という勉強会について
西日暮里.rb なのに、会場は秋葉原の UDX でした。
なんでも「西日暮里は概念化している」とのこと(笑)
"オレ達のいるところが西日暮里だ!"
— Koichi ITO (@koic) 2016年4月28日
_人人人人人人人人人_
> 西日暮里は概念 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y ̄#ninirb
「俺が、俺達が西日暮里なんだ!!」
…なんてセリフも聞こえてきそうですね(笑)
先週の渋谷.rb は割と年代・職種もばらばらで、全体としては落ち着いた雰囲気だった気がしますが、今回の西日暮里.rb は全体に活気のある雰囲気だったなーというのが感想です。
飛び込み LT の後、2回目の LT をやる人も2, 3人いました。
会場は弥生株式会社さんにご提供いただいたのですが、なんとご厚意で参加費も無料にしていただきました。
ありがとうございました!
余談 - "poloxy" 命名について
"fireap", "shove" に続き、またまた造語を作ってしまいました。
ユニークな名前にしようと思うと造語かイニシャルかしかないかなあ、という気もします。
命名は毎回悩みます。
実は最初は "mforwd" という名前でした。
あと、"m4x" とか "bufferay" とか "fubako"(和風)とか考えましたが、最終的に "poloxy" にしました。
短くてわかりやすくてユニークなものがいいかな、と思います。
おわりに
"poloxy" のリリースは Coming Soon ということで、気長にお待ち下さい^^;
良い GW をお過ごしください。
find ... xargs ~ のラッパーを2つ書いたけど ag に移行していこうと思う
自分がよく使うコマンドを、自分が使いやすいオプション付きでラッパー化しました。
自分はこれまで ag(the silver searcher) をほとんど使っていなかった *1 ので、いつもこんなコマンドを叩いていました。
…が、このエントリを書くにあたって改めて調べたところ、ag の方が便利そうで、下の機能はだいたいまかなえそうなので、今後は ag にしていこうとしているところです。*2
後者の xfperl-pie
の方は少し便利かもしれませんが、でもやっぱり ag でいいかなという気もしています。
ともあれ、下の2つは GitHub で公開していますので、お気に召しましたらご自由にお使い下さい。
xfgrep
# 使い方 xfgrep KEYWORD [-i|--ignore IGNORE_FILE_PATTERN] [-d|--dir DIR] \ [-f|--file FILE] # 実行されるコマンド find $DIR -type f -name "$FILE" [ | egrep -v "$IGNORE" ] | xargs egrep \ --color=always -Hn "$KEYWORD"
xfperl-pie
# 使い方 xfperl-pie PL_CODE [-f|--file FILE] [-i|--ignore IGNORE_FILE_PATTERN] \ [-d|--dir DIR] [-b|--backup BACKUP] [-n|--dry-run] # 実行されるコマンド find $DIR -type f -name '$FILE' [ | egrep -v '$IGNORE' ] | \ xargs perl -pi'$BACKUP' -e '$PL_CODE'
利用例
# カレントディレクトリ以下の .pm に対してバックアップしつつ 'foo' => 'bar' に一括置換 xfperl-pie 's/foo/bar/g' -f '*.pm' -b '.bak'
参考
- GitHub - ggreer/the_silver_searcher: A code-searching tool similar to ack, but faster.
- The Silver Searcher のススメ
- Perlのワンライナーとコマンドラインオプション - weblog of key_amb
*1:一応 Mac に ag を入れていたことを、これを書いた後に思い出しました^^;
*2:早速、昨日 Qiita に ag (The Silver Searcher) コマンド覚え書き というエントリを書きました。