Node.jsを使ってCommand line ツールことはじめ
Node.js使ってCommand lineツールがつくれるということを知ったのでさっそくためしてみます。
jsファイル作成
hello-nodejs-command.js
という名前でスクリプトファイルをつくってみます。
nodejs interpreterで実行させるためのおまじないとして#!/usr/bin/env node
を先頭に記述します。
#!/usr/bin/env node /** * hello-nodejs-command.js */
実行権を追加します。
$ chmod +x ./hello-nodejs-command.js
ためしに実行してみます。
$ ./hello-nodejs-command.js $
何も書いていないので当然何も起こりません (ノω・)テヘ
globalにインストールする
コマンドの中身を書いてみたい気持ちをぐっと抑えて、current directoryとか意識せずにコマンドたたけるようにglobal インストールしてみます。
まず、インストール前の状態
$ which hello-git-command $
何も表示されません。
インストールできるようにpackage.json
ファイルをhello-nodejs-command.js
と同じディレクトリに作成します。
{ "name": "hello-git-command", "version": "0.0.1", "description": "A simple command-line tool for display hello git command", "author": "mid0111", "engines": { "node": ">=0.10" }, "dependencies": { }, "bin": { "hello-git-command": "hello-nodejs-command.js" } }
bin
プロパティでコマンドhello-git-command
が呼ばれた時に実行するjsファイルを指定します。
$ ls hello-nodejs-command.js package.json $ sudo npm install -g /usr/local/bin/hello-git-command -> /usr/local/lib/node_modules/hello-git-command/hello-nodejs-command.js hello-git-command@0.0.1 /usr/local/lib/node_modules/hello-git-command ~/src/hello-git-command $ which hello-git-command /usr/local/bin/hello-git-command
これで、/usr/local/bin
に実行ファイルが作成されました。
なお、スクリプトの内容を変更するたびに、/usr/local/lib/node_modules/hello-git-command/hello-nodejs-command.js
に変更を反映するために、npm install -g
を実行する必要があります。
コマンド引数を取得してみる
コマンド引数はproccess.argv
で配列形式で取得することができます。
#!/usr/bin/env node /** * hello-nodejs-command.js */ console.log(process.argv);
引数-xxxx
を指定して実行してみると、、
$ ./hello-nodejs-command.js -xxxx [ 'node', '/home/mid/src/hello-git-command/hello-nodejs-command.js', '-xxxx' ]
visionmediaさんがcommand-line interfaceのための便利ライブラリを提供してくださっているので、それを使用していい感じに引数をパースしてみます。
Commander.js
The complete solution for node.js command-line interfaces, inspired by Ruby's commander.
$ npm install commander --save
上記コマンドで、dependencies
にcommander
ライブラリが追加されます。
"dependencies": { "commander": "^2.2.0" },
commander
を使用してパースしていきます。
#!/usr/bin/env node /** * hello-nodejs-command.js */ var program = require('commander'); program .version('0.0.1') .usage('<keywords>') .parse(process.argv); if(!program.args.length) { program.help(); } else { console.log('Keywords: ' + program.args); }
ためしにいろいろうってみます。
$ ./hello-nodejs-command.js Usage: hello-git-command <keywords> Options: -h, --help output usage information -V, --version output the version number $ ./hello-nodejs-command.js --version 0.0.1 $ ./hello-nodejs-command.js hello Keywords: hello $ ./hello-nodejs-command.js hello hello2 Keywords: hello,hello2
それでは、ちょっと改造してオプション-n
または--name
で指定された名前を使用してSay helloしてみます。
#!/usr/bin/env node /** * hello-nodejs-command.js */ var program = require('commander'); program .version('0.0.1') .option('-n, --name [Your Name]', 'Specify your name.') .parse(process.argv); if(!program.name) { program.help(); } else { console.log('Hello %s', program.name); }
Say hello !
$ ./hello-nodejs-command.js --name mid0111 Hello mid0111
おもしろライブラリを使ってみる
他にもvisionmediaさんのライブラリでかわいいのがあったので、遊んでみます。
ライブラリ追加。
$ npm install progress --save
hello-nodejs-command.js
にshowProgressBar
関数を追加し、console.log
でHelloする前に呼び出し追加。
var ProgressBar = require('progress'); showProgressBar(); console.log('Hello %s', program.name); function showProgressBar() { var bar = new ProgressBar(':bar', { total: 10 }); var timer = setInterval(function () { bar.tick(); if (bar.complete) { console.log('\ncomplete\n'); clearInterval(timer); } }, 500); }
実行してみる。
$ ./hello-nodejs-command.js --name mid0111 Hello mid0111 ========= complete
テキストにしてしまうとわかりにくいですが、いい感じにProgress Barが進んでます。
せっかくなので、complete
の文字を*
に変更して、さらに現在何%かを表示してみます。
var bar = new ProgressBar('Waiting... [ :bar ] :percent :etas', { total: 10, complete: '*' });
:percent
:現在の進捗何%を表示:etas
:時間を表示complete
:完了した状態を表す文字を指定
$ ./hello-nodejs-command.js --name mid0111 Hello mid0111 Waiting... [ ****----- ] 50% 3.9s
いまさら気づいたけど、ProgressBarは非同期で呼び出されるのか。
なので、ProgressBarで表す処理が終わってからHelloの処理を実行したい場合は以下のようにする必要があるみたいです。
showProgressBar(); function showProgressBar() { var bar = new ProgressBar('Waiting... [ :bar ] :percent :etas', { total: 10, complete: '*' }); var timer = setInterval(function () { bar.tick(); if (bar.complete) { console.log('\ncomplete\n'); clearInterval(timer); console.log('Hello %s', program.name); } }, 200); }