コマンドラインプログラムの開発
コマンドラインで使うプログラムを開発する際に便利なモジュールがcommander.js(MITライセンス)です。commander.jsを使うと、引数の解釈やプロンプト入力の待機などのコマンドラインでよく必要となる処理が簡単に実装できます。
commander.jsをインストールするには、プロジェクトのディレクトリで次のコマンドを実行します。
$ npm install commander
リスト16はcommander.jsの使用例です。
program = require 'commander' program .version('1.0.0') # -V または --version オプションで表示されるバージョン .usage('[options] <file ...>') # -h または --help オプションで表示される使い方 .option('-q, --quiet', 'コンソール出力をしない') .option('-o, --output <dir>', '出力ディレクトリ') # 引数を1つ取る .option('-w, --warn [level]', '警告', parseInt) # 引数は整数で指定は任意 .option('-s, --size <bytes>', 'サイズ', parseInt) # 引数は整数 .option('-d, --degree <deg>', '度数', parseFloat) # 引数は小数 .option('-n, --names <names>', '名前(カンマ区切り)', (val) -> val.split ',') .parse process.argv # プログラムに渡された引数の解釈を実行する
このプログラムが実行される時にコマンドラインオプションが指定されると、program.長いオプション名
で値を取得できます。例えばリスト16のプログラムがmyprog.coffeeというファイル名だとすると、coffee myprog.coffee -o build
と実行した場合はprogram.output
にbuildという文字列が入ります。オプションが指定されなかった場合はundefinedとなります。オプション以外に指定されたコマンドライン引数はprogram.args
に配列として入ります。
commander.jsでは次のようにオプションを定義します。一般的に、コマンドラインのオプションは短い名前と長い名前の2種類どちらでも指定できるようにすることが多いです。あまり使われないオプションなどは、長い名前しか持たないこともあります。コマンドを使う側からすると、短い名前はコマンドラインで指定する時に便利であり、長い名前はスクリプトに埋め込む時など可読性を高めたい場合に便利です。
オプションの定義方法
option('-q, --quiet', 'コンソール出力をしない')
-q
または --quiet
で指定できるオプション。引数を取らない。
option('-o, --output <dir>', '出力ディレクトリ')
-o
または --output
で指定できるオプション。引数は必須。
option('-w, --warn [level]', '警告', parseInt)
-w
または --warn
で指定できるオプション。引数は任意で指定可。引数をparseInt()
で整数に変換する。
option('-s, --size <bytes>', 'サイズ', parseInt)
-s
または --size
で指定できるオプション。引数は必須。引数をparseInt()
で整数に変換する。
option('-d, --degree <deg>', '度数', parseFloat)
-d
または --degree
で指定できるオプション。引数は必須。引数をparseFloat()
で小数に変換する。
option('--names <names>', '名前(カンマ区切り)', (val) -> val.split ',')
--names
で指定できるオプション。引数は必須。引数を ,(カンマ)で区切って配列に変換する。
入力プロンプトを表示する
入力プロンプトを使用すると、ユーザーからの入力を待って処理を進めることができます。
1行の入力
program.prompt '名前を入れてください: ', (name) -> console.log "#{name}さん、こんにちは。" process.stdin.pause()
program.prompt()
の第1引数の最後に半角スペースを入れます。実行結果は以下のようになります。
名前を入れてください: nao naoさん、こんにちは。
複数行の入力
program.prompt '自己紹介を入力してください', (desc) -> console.log "紹介文: #{desc}" process.stdin.pause()
program.prompt()
の第1引数の最後に半角スペースを入れない場合は複数行入力となり、空行が入力されるまで待機します。実行結果は以下のようになります。
自己紹介を入力してください 趣味でプログラムを書きます。 最近CoffeeScriptに興味があります。 紹介文: 趣味でプログラムを書きます。 最近CoffeeScriptに興味があります。
数値の入力
program.prompt '年齢を入力してください: ', Number, (age) -> console.log "年齢: #{age}" process.stdin.pause()
第2引数にNumber
を指定すると数値以外の値を拒否します。実行結果は以下のようになります。
年齢を入力してください: abc 年齢を入力してください: (must be a number) 32 年齢: 32
日付の入力
program.prompt '日付を入力してください: ', Date, (date) -> console.log "日付: #{date}" process.stdin.pause()
第2引数にDate
を指定すると日付以外の値を拒否します。実行結果は以下のようになります。
日付を入力してください: abc 日付を入力してください: (must be a date) 2012/4/1 date: Sun Apr 01 2012 00:00:00 GMT+0900 (JST)
パスワードの入力
program.password 'パスワードを入力してください: ', (pass) -> console.log '入力を受け付けました。' process.stdin.pause()
program.password()
で表示されるプロンプトでは、キーを打っても画面に表示されません。実行結果は以下のようになります。
パスワードを入力してください: 入力を受け付けました。
実行するか確認する
program.confirm '続行しますか? ', (ok) -> if ok console.log "続行します。" else console.log "中断します。" process.stdin.pause()
yで始まる文字、ok、trueのいずれかを入力した場合はtrue、それ意外の場合はfalseになります。実行結果は以下のようになります。
続行しますか? y 続行します。
選択肢から選ぶ
console.log "好きな言語を選んでください。" langs = ['CoffeeScript', 'Ruby', 'Perl', 'PHP'] program.choose langs, (i) -> console.log "#{langs[i]}ですか。良い言語ですね。" process.stdin.pause()
複数の選択肢から番号で選ばせます。選んだ選択肢のインデックスがコールバック関数に引数として渡されます。インデックスは0から始まります。実行結果は以下のようになります。
好きな言語を選んでください。 1) CoffeeScript 2) Ruby 3) Perl 4) PHP : 1 CoffeeScriptですか。良い言語ですね。