Making Command-Line Interface (CLI) for Fun and Profit

Written by CK | Published 2020/02/04
Tech Story Tags: coding | cli | javascript | devops | nodejs | programming | npm-and-nodejs | tutorial

TLDR CLI uses command flags and help text to prevent you from making silly mistakes. At Taggun, we run a lot of node.js application. We make APIs for receipt OCR scanning. And I recommend oclif: The Open.CLI Framework by Heroku for creating and managing CLIs. For example, you will need to run npm i-find to install find npm module. It will look for all. node.js application in the root folder and run [command]via the TL;DR App

Next time you have an idea šŸ’” "I know... Why don't I write a script to automate this thing?" Actually, you should not, you should write aĀ CLIĀ instead.
CLI has better structure than scripts. And, CLI uses command flags and help text to prevent you from making silly mistakes. For example:
$ moa --help
Moa makes it easier to run your local node.js apps.

USAGE
  $ moa

OPTIONS
  -c, --commands=commands  [default: start] commands to run.
  -h, --help               show CLI help
  -r, --root=root          [default: ../] root path to run.

DESCRIPTION
  ...
  Have some fun
Scripts are messy and can get out of control.
AtĀ Taggun, we run a lot of node.js application. By the way, we make APIs for receipt OCR scanning. And I recommendĀ oclif: The Open CLI Framework by Heroku for creating and managing CLIs.

How to create a new CLI

InstallĀ node.jsĀ first.
Start by scaffolding the CLI
$ npx oclif single moa
? npm package name (moa): moa
$ cd moa
Modify your flags inĀ 
src\index.js
MoaCommand.flags = {
  // add --help flag to show CLI version
  help: flags.help({char: 'h'}),
  commands: flags.string({char: 'c', description: 'commands to run. Comma-separated.', default: 'start'}),
  root: flags.string({char: 'r', description: 'root path to run.', default: '../'}),
}
Modify your description inĀ 
src\index.js
MoaCommand.description = `Moa makes it easier to run your local node.js apps.
Modify your command inĀ 
src\index.js
class MoaCommand extends Command {
  async run() {
    const {flags} = this.parse(MoaCommand)
    const commands = flags.commands.split(',')
    const {root} = flags
    find.file(/(?<!node_modules\/.*)\/package\.json$/, root, files => {
      files.forEach(async file => {
        const cwd = require('path').dirname(file)
        commands.forEach(async command => {
          this.log(cwd, `npm run ${command}`)
          const npm = spawn('npm', ['run', command], {cwd})
          for await (const output of npm.stdout) {
            this.log(`${file}: ${output}`)
          }
        })
      })
    })
  }
}
In this example, you will need to
runĀ npm i
findĀ to installĀ findĀ npm module.
This simple CLI will look for all node.js application in theĀ root folderĀ and runĀ 
npm run [command]
. Great if you need to run multiple node.js application to start coding.
Run it
./bin/run -c start -c ../taggun/
Publish and share your CLI

Written by CK | Technical Founder @ TAGGUN
Published by HackerNoon on 2020/02/04