コピペで済ませたい、と思う場面は割とよくある。開発をしているとかなりよくある。
例えば、
- pythonのサーバ側のWebAPIとそのドキュメント、クライアント側のSwift/Javaのエンティティで同じような定義情報やらコメントを持っていたい。
- GitHubのWikiとREADMEとpackage.jsonの一部に重複した情報を埋め込みたい。
- HTTPのGETとPOSTとPUTとPATCHとDELETEで個別のハンドリングメソッドを用意したいけど中身はほとんど一緒。
とかね。
泥臭い手作業や、禍根を残す無責任なコピペをやめて、こういうのを全部クールに自動的にいい感じにしたい。
既に世の中にはいろんな自動生成ツールがあり、それらを上手く取り入れ、ちゃんと組み込み、しっかり運用することができればきっとできるはずだ。
と思っていろいろ試してみたのだけれど、なかなか上手くいかない。
理由として
- 事前に用意されたテンプレートは微妙に用途が合わない
- 自分でテンプレートを用意すると管理が大変
- 自動生成ツールが混ざるとどれが何をどう作成しているのかわからなくなってカオスになる
既存の組み合わせだとどうも上手くいかない。
そこでcozだ。
cozではメタ情報ファイルに各種の生成ルールを記述し、コマンドからレンダリングを走らせるツールだ。
インストール
cozはNode.jsで作られており、NPMからインストールできる。
# Instal coz via npm
$ npm install coz -g
イストールが成功するとcoz
コマンドが使えるようになる
# Show installed coz version.
$ coz --version
Hello world
cozではbudファイルと呼ばれるメタファイルに生成ルールを記述する。
budファイルには何をどこからどう生成するか、という情報が含まれている。文法はjavascriptで記述されており、require()
を使って外部モジュールを読み込める。
.have-a-nice-day.txt.bud
// Define rendering rule.
module.exports = {
path: 'have-a-nice-day.txt', // File path to write
tmpl: '.have-a-nice-day.txt.hbs', // Template file
force: true, // Overwrite each time
mode: '444', // As readyonly file
data: require('./my-datasource.json') // Data to render
}
budファイルのtmpl
の項目には、budファイルからの相対パスでテンプレートを指定する。
テンプレートの解釈は、デフォルト設定ではHandlebarsエンジンによって行われる。
.have-a-nice-day.txt.hbs
Have a nice day, {{name}}!
これらのファイルを用意した後、
renderコマンドの引数に.budファイルのパスを渡すとレンダリングが実行される
$ coz render .*.bud
have-a-nice-day.txt
Have a nice day, jhon!
budファイルの名称や配置先は何でもよいが、先頭にドットをつけた隠しファイルとして、出力先と同じディレクトリに置くことが推奨される。
これは、どのファイルがどのbudファイルから出力されたかを追いやすいようにするためである。
Advanced
tmpl,pathの省略
budファイル内のtmpl
,path
の項目は省略できる。
何も書かなければbudファイル自身のパスから自動で類推される。
例えば foo/.bar.js.bud
の場合、
tmpl
のデフォルト値はfoo/.bar.js.hbs
path
のデフォルト値はfoo/bar.js
となる。
複数まとめてレンダリング
同じようなファイルをたくさん作る場合はbudファイルの中身を配列にすればよい。
.-entity.js.bud
var names = ["User", "Department"];
module.exports = names.map(function(name) {
return {
path: name + 'Entity.py',
force: true,
mode: '444'
}
});