筆記 - 幫自己寫一個 CLI 來幫自己建資料夾! 使用 nodeJS 的 commander!

自己的工具自己寫

最近寫測試需要自動gen一些資料夾跟檔案,覺得很麻煩,所以決定寫個小工具來幫自己

前置動作

node js 安裝完畢之後先下個指令創建一個資料夾

mkdir my-cli

cd 到 my-cli 初始化 npm 後 安裝 commander

npm init
npm install commander --save

在 package.json 中加入以下程式碼,這個是用來設定你教要使用的cli名字 跟 cli 切入點

...,
"bin": {
    "mycli": "./index.js"
},
...

創建一個 index.js 的檔案並在其檔案中加入以下程式碼

#!/usr/bin/env node

var program = require('commander');

program
  .version('0.1.0')
  .option('-s, --spicy', '要辣辣的, Add spicy')
  .option('-P, --no-parsley', '不要香菜, Remove parsley')
  .option('-t, --teatype [teatype]', '給我一杯 [紅茶]', '紅茶')
  .parse(process.argv);

console.log('you ordered:');
if (program.spicy)
  console.log('要辣辣');
else
  console.log('不要辣辣');

if (program.parsley)
  console.log('我要香菜');
else
  console.log('我不要香菜');
console.log('給我一杯 %s', program.teatype);

完成以上動作後 在 command line中下

npm link

這個指令將會幫助你把這個資料夾放進你的全域node module 中,這樣妳就不用部屬到 npm 上才能使用,詳細可以參考這裡

範例程式碼說明

現在開始來解釋一下上面那段code其中代表的意思

program 是指commander本體
version、option則是已經被包裝好的方法

這裡的 version('0.1.0') 代表著下了 "mycli -V" 或者 "mycli --version" 就會顯示被定義的版本 '0.1.0'

而option的格式為

.option('指令名稱, --指令變數名稱' , '說明')

以第一個option來舉例

.option('-s, --spicy', '要辣辣的, Add spicy')

寫了這一行之後執行 mycli -s,則會使 spicy 這個變數設為 true (預設為false)

你就可以使用 program.test 來判斷是否要做這個指令該做的事 只要下 mycli -s

就會出現以下訊息

從上面印出的結果可以看出 要下-P這個指令才能夠不要香菜,不然預設一般都會給你香菜  (一般店家也都會加香菜)

也就是說 如果要預設為 true 的變數,你需要這麼做

program.option('-P, --no-parsley', '不要香菜, Remove parsley')

所以如果下了這個指令 -P 才會把 parsley這個指令設為 false

看看執行結果

一般餐廳都預設會給你一杯紅茶,除非你有特別說要其他的餐點,不然一般來說都是紅茶,這樣的情況也是有的
所以如果你需要這樣做

program.option('指令, --變數名稱 [帶入的值]', '說明', '預設值')

範例程式碼如下

program.option('-t, --teatype [teatype]', '給我一杯 [紅茶]', '紅茶')

這樣就可以像上面那些輸出結果,每次沒有特別囑咐,就會直接給你一杯紅茶,如果特別囑咐要一杯綠茶則需要這樣下

mycli -t 綠茶

使用 fs 來建立資料夾與檔案

簡單的介紹完了,接下來要使用 filesystem 來建立資料夾跟檔案

首先要再 index.js上引入 fs 並加上使用 fs 建立資料夾的 code 所以 code會變成這樣

使用 fs.mkdir(資料夾位置, callback) 來建立資料夾

#!/usr/bin/env node

var program = require('commander');
fs = require('fs');

program
  .version('0.1.0')
  .option('-s, --spicy', '要辣辣的, Add spicy')
  .option('-P, --no-parsley', '不要香菜, Remove parsley')
  .option('-t, --teatype [teatype]', '給我一杯 [紅茶]', '紅茶')
  .parse(process.argv);

console.log('you ordered:');
createFolder('ordered');
if (program.spicy) {
  console.log('要辣辣');
} else
  console.log('不要辣辣');

if (program.parsley)
  console.log('我要香菜');
else
  console.log('我不要香菜');
console.log('給我一杯 %s', program.teatype);

function createFolder(folderName) {
  fs.mkdir('./'+ folderName, (err) => {
    if (err)
      console.log(err);
    else
      console.log('./' + folderName + ' has generated');
  });
}

使用 fs.writeFile(檔案名稱, 檔案內容, callback)來建立檔案

所以 code 最後長成這個樣子

#!/usr/bin/env node

var program = require('commander');
fs = require('fs');

program
  .version('0.1.0')
  .option('-s, --spicy', '要辣辣的, Add spicy')
  .option('-P, --no-parsley', '不要香菜, Remove parsley')
  .option('-t, --teatype [teatype]', '給我一杯 [紅茶]', '紅茶')
  .parse(process.argv);

console.log('you ordered:');
createFolder('ordered');
if (program.spicy) {
  createFile('要辣辣.txt', '真的要辣辣')
  console.log('要辣辣');
} else {

  createFile('不要辣辣.txt', '真的不要辣辣')
  console.log('不要辣辣');
}

if (program.parsley) {

  createFile('要香菜.txt', '真的要香菜')
  console.log('我要香菜');
} else {
  createFile('不要香菜.txt', '真的要不香菜')
  console.log('我不要香菜');
}
giveMeDrink = '給我一杯 ' + program.teatype;
createFile(giveMeDrink + ".txt", giveMeDrink)
console.log(giveMeDrink);

function createFolder(folderName) {
  fs.mkdir('./' + folderName, (err) => {
    if (err)
      console.log(err);
    else
      console.log('./' + folderName + ' has generated');
  });
}

function createFile(fileName, fileContent) {
  fs.writeFile('./ordered/' + fileName, fileContent, (err) => {
    if (err)
      console.log(err);
    else
      console.log('file:%s', fileName + ' has generated');
  });
}

來執行看看 mycli -s 就會看到他幫你建立完成了


檔案建立完成如下

這裡是 github 連結,歡迎clone下來參考~

以上是簡單的 commander 介紹,如果有錯誤麻煩大大指教 <(_ _)>