コマンドラインツールまたはシェルスクリプト相当を書こうというお話。node.jsで書く利点はWindowsでもOSXでもLinuxデスクトップでも全く同じように実行可能だから。node.jsが入っているという前提条件だけど。
前準備
オフィシャルサイトやQiitaを参考にnode.jsとnpmが使えるようにする。
プロジェクトの作成
特別なことは何もなくいつも通り npm init
で。
shebang
#!/usr/bin/env node
shebangはUnix系の実行に必要。Windowだとこれは無視される。詳しくは https://docs.npmjs.com/files/package.json で。
オプションパーサー
コマンド引数を素のnode.jsで扱うのはちょっと辛いので commander
パッケージを利用する。
入力プロンプト
これもやはり便利な co-prompt
co
パッケージを使う。
Unixライクコマンド実行
shelljs
を使うとnode.jsで ls
や echo
っぽいコードが簡単に書ける素晴らしいパッケージ。勿論Windowsでも使えます。
package.json
上記のパッケージをプロジェクトにインストール。
$ npm i commander co-prompt co shelljs --save
$ npm list --depth=0
+-- co@4.6.0
+-- co-prompt@1.0.0
+-- commander@2.9.0
`-- shelljs@0.7.0
サンプルコード
プロジェクト名はmycli
で。
{
"name": "mycli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"bin": {
"mycli": "./index.js"
},
"dependencies": {
"co": "^4.6.0",
"co-prompt": "^1.0.0",
"commander": "^2.9.0",
"shelljs": "^0.7.0"
}
}
今回は紹介だけなので index.js
をこんな風に。ファイル名指定とユーザー名パスワード入力ができます。
#!/usr/bin/env node
require('shelljs/global')
program = require('commander')
prompt = require('co-prompt')
co = require('co')
program
.arguments('<file>')
.option('-u, --username <username>', 'The user to authenticate as')
.option('-p, --password <password>', 'The user\'s password')
.action(function(file) {
co(function *() {
var username, password
if (program.username) {
username = program.username
} else {
username = yield prompt('username: ')
}
password = yield prompt.password('password: ')
display(username, password, file)
})
})
.parse(process.argv)
display = (username, password, file) => {
echo(`user: ${username} pass: ${password} file: ${file}`)
}
index.js
に実行権を付与して実行。まずはヘルプから。
$ index.js --help
Usage: index [options] <file>
Options:
-h, --help output usage information
-u, --username <username> The user to authenticate as
-p, --password <password> The user's password
オプション関連はcommander
が全部処理してくれてヘルプも自動的に生成される。すごく便利。
実際の実行イメージはこんな感じ。
$ index.js hoge.txt
username: foo
password: ***
user: foo pass: bar file: hoge.txt
$ index.js hoge.txt -u foo
password: ***
user: foo pass: bar file: hoge.txt
入力関連はco-prompt
で実現。パスワードに***
とマスクをかけて入力するのも簡単。オプションで直接指定する時はさすがにマスクかからないけど実用性抜群。
shelljs
は今回echo()
だけ使ったが、基本的なUnixコマンドライクな関数が揃っててこれもまた便利。npmのscriptsでも使えるので簡単なことならタスクマネージャーよりこっちがフットワーク軽いです。
shelljs
で使える関数の例。
cd([dir])
pwd()
ls([options,] [path, ...])
ls([options,] path_array)
find(path [, path ...])
find(path_array)
cp([options,] source [, source ...], dest)
cp([options,] source_array, dest)
rm([options,] file [, file ...])
rm([options,] file_array)
mv([options ,] source [, source ...], dest')
mv([options ,] source_array, dest')
mkdir([options,] dir [, dir ...])
mkdir([options,] dir_array)
test(expression)
cat(file [, file ...])
cat(file_array)
head([{'-n', },] file [, file ...])
head([{'-n', },] file_array)
tail([{'-n', },] file [, file ...])
tail([{'-n', },] file_array)
〜
shelljs
サンプルコード。
require('shelljs/global');
if (!which('git')) {
echo('Sorry, this script requires git');
exit(1);
}
// Copy files to release dir
rm('-rf', 'out/Release');
cp('-R', 'stuff/', 'out/Release');
// Replace macros in each .js file
cd('lib');
ls('*.js').forEach(function(file) {
sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
sed('-i', /^.*REMOVE_THIS_LINE.*$/, '', file);
sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
});
cd('..');
// Run external tool synchronously
if (exec('git commit -am "Auto-commit"').code !== 0) {
echo('Error: Git commit failed');
exit(1);
}
他にもおすすめのnode.jsパッケージは出力テキストをカラーリングするchalk
や進捗を出力するprogress
などなど。
おすすめパッケージがあればコメント下さい🙇
mycliインストール
パッケージのルートにてnpm link
を実行する。
$ npm link
npm WARN mycli@1.0.0 No description
npm WARN mycli@1.0.0 No repository field.
/usr/local/bin/mycli -> /usr/local/lib/node_modules/mycli/index.js
/usr/local/lib/node_modules/mycli -> /Users/uchcode/Desktop/mycli
$ mycli --help
Usage: mycli [options] <file>
Options:
-h, --help output usage information
-u, --username <username> The user to authenticate as
-p, --password <password> The user's password
パッケージを公開すればどの環境でも簡単にインストール実行ができます。
node.jsすごいね。