Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Writing CLI apps with Flatiron

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

Command-line interfaces (CLIs) are an often overlooked, but extremely important part of every developers workflow. Think about how different your day-to-day life would be if git functioned differently? Or (gasp) incorrectly or inconsistently? At Nodejitsu, we know CLI applications. The CLI for our public platform jitsu is designed to be quick to get started, highly portable and above all: consistent and robust. With these principals in mind we took extra care designing Flatiron to be adaptable to our production-quality needs.

Flatiron is an adaptable decoupled framework for both node.js and the browser. An adaptable framework enables users to build multiple types of applications. In Flatiron we are focusing on:

  • Web applications (http and websockets)
  • Command line (CLI) applications
  • Front-end applications

This article will focus on the tools at your disposal when using Flatiron to build CLI applications as well as how many existing Flatiron CLI applications are structured.

Getting started

Writing a Command-line application with Flatiron starts out like writing every other flatiron application:

  $ flatiron create simple-app cli
  info:   Creating application simple-app
  info:   Using cli scaffold.
  info:   Creating directory config
  info:   Creating directory lib
  info:   Creating directory commands
  info:   Creating directory test
  info:   Writing package.json
  info:   Writing app.js
  info:   Writing lib/index.js
  info:   Application simple-app is now ready

Lets examine the directory structure created by running flatiron create simple-app cli:

  simple-app/
    app.js
    config/
    lib/
      index.js
      commands/
    package.json
    test/

With this simple scaffold the application has already been setup with:

There are other options which make writing CLI applications quick and easy. Leave the tough stuff to us.

To the code!

Lets examine each line of the code generated by flatiron create simple-app cli:

var flatiron = require('flatiron'),  
    path = require('path'),
    app = flatiron.app;

app.config.file({ file: path.join(__dirname, 'config', 'config.json') });

app.use(flatiron.plugins.cli, {  
  source: path.join(__dirname, 'lib', 'commands'),
  usage: 'Empty Flatiron Application, please fill out commands'
});

app.start();  

Setup up Configuration

  app.config.file({ file: path.join(__dirname, 'config', 'config.json') });

Add a store to back the configuration for this application. It will automatically load :pwd/config/config.json from disk.


Attach the CLI plugin

  app.use(flatiron.plugins.cli, {
    source: path.join(__dirname, 'lib', 'commands'),
    usage: 'Empty Flatiron Application, please fill out commands'
  });

Attach Command-line functionality to the application. See Configuring your Command-line Application for more detailed documentation.


Start the Application

  app.start();

Initializes the application and then dispatches to the director router using app.argv._. For example when running app config get foo, app.argv._ will be ['app', 'config', 'get', 'foo'].


Configuring your Command-line Application

There is a simple convention for passing options to both flatiron.plugins.cli and flatiron.plugins.http: the settings for the named property added to the application has the same name in the options passed to .use(). For example:

//
// Configuring app.argv
//

app.use(flatiron.plugins.cli, {  
  //
  // Settings used by `require('optimist').options()
  //
  argv: {
    login: {
      alias: 'l',
      description: 'Login to use',
      string: true
    }
  }
});

//
// `app.argv.l` is now available
//
console.log(app.argv.l);  

There are some important settings you need to be aware of:

Composable Command-line applications

Flatiron enables developing adaptable applications through a lightweight dependency injection system called broadway. Writing broadway plugins is easy and can be used to easily compose applications out of reusable components. This was the motivation behind a new CLI-plugin for Flatiron released today: flatiron-cli-config. This plugin extends the application by adding handlers for app config *. It also adds help for all of these commands available through app help config *:


  • app config list: Lists all key-value pairs known to the application.
  • app config get <key>: Displays the value for to the user.
  • app config set <key> <value>: Sets the to the specified value.
  • app config delete <key>: Clears the value for the specified .

Using this plugin is simple:

  app.use(require('flatiron-cli-config'));

That's it. Your application is now fully setup to use edit configuration files from the command-line.

Flatiron Command-line applications in the wild

Since we released Flatiron there have been a number of interesting applications released and refactored:

  • issues: Github Issues from the CLI
  • box: Powerful key -> value storage for the CLI.
  • todo: Todos in the CLI like what.
  • npmcount: Silly program that counts number of npm packages from one or more users.
  • jitsu: Flawless command line deployment of your Node.js apps to the cloud.

Well that about wraps it up. Can't wait to see what crazy things I'll be able to do from the CLI soon!