rapido

Rápido is an extensible command line interface that enables rapid development for any technology stack. Rápido is written in JavaScript and is built on top of Node.js and npm.

npm install rapido
1 downloads in the last day
81 downloads in the last week
286 downloads in the last month

Rápido

Rápido is an extensible command line interface that enables rapid development for any technology stack. Rápido is written in JavaScript and is built on top of Node.js and npm.

Features

  • Custom commands and stacks
  • Scaffolding
  • Command line argument parsing
  • Configuration loading
  • User input
  • Colorized output
  • Command-line auto-completion

Screenshot

Screenshot

Installation

The only prerequisite for Rápido is Node. After Node has been installed, Rápido should be installed as a global script using npm as shown below:

$ npm install rapido --global

Overview

Commands

Rápido is extensible and supports any number of commands that can easily be invoked from the command line. Commands are bundled as part of "stacks" and new stacks can easily be installed using npm (described later). Based on the arguments passed to the Rápido command line interface, Rápido will delegate the work to the appropriate command handler. A simple command invocation is shown below:

$ rap create component ui/buttons/Button --no-testing

In the above example, "create component" is the command name and "ui/buttons/Button" and "--no-testing" are additional arguments to the command handler.

NOTE: Rápido uses rap by default, but you can change it to whatever you want. See Custom Command Line Tools using Rápido

Details on creating your own commands are described in the "Creating Custom Commands" section below.

Stacks

A stack is a collection of commands that are all related to a particular technology stack. Rápido supports using multiple stacks, and new stacks can easily be installed using npm. When running a command, the command is searched for in the stacks that are currently enabled.

Installing Stacks

A new stack should be installed just like any other Node module using npm. For example:

$ npm install rapido-raptorjs

Stacks can also be installed globally using the --global switch for npm (e.g. npm install rapido-raptorjs --global). When launched, Rápido will search for Rápido stacks and commands in all of the first-level Node modules found in any of the available node_modules directories. Rápido uses the same module search path that Node uses and will begin its search in the current working directory and ending in the global node_modules direcotry. A Rápido stack is indicated by the existence of a rapido-stack.json configuration file in the root directory of the module.

Enabling Stacks

Stacks can be enabled and disabled using the rap use command as shown in the sample below:

$ rap use raptorjs

It is also possible to enable multiple stacks:

$ rap use raptorjs jquery backbone

NOTE: If multiple enabled stacks support the same command then you will be prompted to choose a stack when invoking the ambiguous command.

NOTE: The currently enabled stacks are stored in the rapido.json configuration that is discovered first (see the "Configuration" section below). If a rapido.json file is not found, one is created in the current directory.

Listing Commands and Stacks

To get a list of available commands for the currently enabled stacks, simply run the following command:

$ rap list

To get a list of all commamnds for all stacks that have been installed (not just the ones that are enabled), the following command should be used:

$ rap list all

Configuration

Rápido, and all of the commands, can be configured using rapido.json files that can be loaded from multiple locations.

Sample rapido.json config file:

{
    "scaffold.component.dir": "scaffolds/component",
    "scaffold.page.dir": "scaffolds/page",
    "scaffold.webapp.dir": "scaffolds/webapp",
    "modules.dir": "modules",
    "components.base.dir": "modules",
    "pages.base.dir": "modules/pages",
    "app.rtld.file": "modules/taglibs/app/app.rtld"
}

NOTE: Any configuration properties that have the suffix "file" or "dir" will result in a property value of type raptor/file/File that references the file resolved relative to the directory containing the rapido.json file that the configuration property is defined in.

Configuration files are merged together, and Rápido supports configuration overrides at the directory/project-level and at the user or system level using a simple configuration search path.

Rápido will look for a rapido.json file in the current working directory, and then search in the parent directory, all the way up to the root. It will then search in the home directory. Lastly, Rápido will search for rapido-stack.json files in all of the node_modules directories using the same search path that Node uses to find and load modules (starting in the current working directory).

Creating a Stack

Rápido provides commands for creating stacks and commands. To create a new stack simply do the following:

$ mkdir my-stack
$ cd my-stack
$ rap create stack

You will be prompted for information about the new stack, and the command then will generate all of the files for your stack in the current directory. Stacks are defined in a rapido-stack.json file as shown in the following sample code:

{
    "name": "raptorjs",
    "description": "Commands for the RaptorJS Toolkit",
    "commands": {
        "create component": {
            "description": "Create a RaptorJS UI component",
            "file": "command-create-component.js"
        },
        "create page": {
            "description": "Create a RaptorJS page",
            "file": "command-create-page.js"
        },
        "rename component": {
            "description": "Rename an existing UI component",
            "file": "command-rename-component.js"
        }
    }
}

You can then share your stack by publishing it to the npm repository by simply running npm publish.

Creating a Command

New commands can be added to a stack using the rap create command. You will be prompted for some information about the command, and then the command implementation will be created and automatically registered in the stack by updating the rapido-stack.json for the stack.

A command handler is implemented as a CommonJS module as shown in the following sample code:

module.exports = {
    usage: 'Usage: $0 say hello <name>',

    options: {
        'upper-case': {
            describe: 'Convert name to upper case'
        }
    },

    validate: function(args, rapido) {
        var name = args._[0];
        if (!name) {
            throw 'name is required';
        }

        return {
            name: name,
            upperCase: args['upper-case']
        };
    },

    run: function(args, config, rapido) {
        var name = args.name;

        if (args.upperCase) {
            name = name.toUpperCase();
        }

        rapido.log.success('Command says: ' + name);
    }
}

Command Line Argument Parsing

A command should declare which options it allows using the options property of the exported command module as shown in the previous section. In addition, the usage property should be used to provide basic information for the command.

Internally, Rápido uses the optimist module to parse the command line arguments using the option definitions. Please see the documentation for the optimist module on the format for defining options.

Reading Configuration Properties

The loaded configuration is passed as the second argument to the run method exported by a command. Configuration properties can easily be read as shown in the following sample code:

module.exports = {
    ...
    run: function(args, config, rapido) {
        var scaffoldDir = config["scaffold.page.dir"];
        if (!scaffoldDir) {
            throw new Error('"scaffold.page.dir" not defined in "' + rapido.configFilename + '" config file');
        }
        ...
    }
}
`

Scaffolding

Rápido provides support for scaffolding which allows for commands to generate a set of files from a template directory. Rápido uses dust-linkedin to support variables, conditionals and other structural logic inside template files. Only files with the ".dust" extension will be treated as Dust templates and other files will be copied directly to the output directory. In addition, variables are supported in filenames using _<var-name>_ syntax. If a variable inside a filename resolves to a false value then the file will be ignored, thus allowing for conditional files.

The generation of files using a scaffold can be done as shown in the following sample code:

rapido.scaffold({
    scaffoldDir: scaffoldDir, // Location of the input scaffold directory
    outputDir: outputDir,     // Output directory
    overwrite: true,          // Files will only be overwritten if true
    data: {                   // Input data for the templates
        name: 'Frank',
        count: 30
    },
    beforeFile: function(outputFile, content) { // Invoked before writing a file
        return true; // If false is returned then the file will not be written
    },
    afterFile: function(outputFile) { // Invoked after writing a file

    }
});

User Input

Rápido makes it easy to accept user input from the command line using the prompt module for Node as shown in the following sample code:

var prompt = rapido.prompt;
prompt.start();
prompt.get(
    {
        properties: {
            'name': {
                description: 'Name',
                required: false
            },
            'count': {
                description: 'Count',
                required: false
            },
        }       
    }
    , 
    function (err, result) {
        if (err) { 
            rapido.log.error(err);
            return;
        }

        var name = result.name || 'Default';
        var count = result.count || 0;
        //...
    });

Colorized Output

The following commands should be used to produce colorized output:

rapido.log.success('Completed successfully');
rapido.log.success('success', 'Completed successfully'); // With label: [success] Completed successfully!
rapido.log.info('Some info message');
rapido.log.info('info', 'Some info message'); // With label: [info] Some info message
rapido.log.warn('Some warning message');
rapido.log.warn('warn', 'Some warning message'); // With label: [warn] Some warning message
rapido.log.error('Some error message');
rapido.log.error('error', 'Some error message'); // With label: [error] Some warning message
rapido.log('Message with no color');

Command-line Auto-Completion

Rápido provides support for auto-completion in a shell. Auto-completion allows the TAB character to be used to complete a command name or a command option. To enable this feature, the following command must be added to your shell initialization scripts (typically ~/.profile) after installing Rápido globally.

complete -C rap rap

The above command will use the rap command itself to handle auto-completion. The rap script detects when it is being invoked in the context of auto-completion based on special environment variables that get set by the shell. For more info, please see Bash: Programmable Completion Builtins.

Custom Command Line Tools using Rápido

Don't like the name rap or what to create your own custom command line tool that utilizes the power or Rápido? No problem! Just add a Node bin script to project similar to the following:

#!/usr/bin/env node
var path = require('path');
var rapido = require('rapido').create();

// Want to use something other than "rapido.json"?
rapido.configFilename = "raptor.json";

// Give your command line tool a name:
rapido.title = 'RaptorJS Command Line Tools';

// Does your project have its own Rápido that were installed from npm?
// If so, you'll need to tell Rápido where to find them:
rapido.addNodeModulesDir(path.join(__dirname, '../node_modules'));

// Enable any stacks you need for your Command Line Tool
rapido.enableStack('raptorjs');

// Add a specific directory that contains a Rápido stack
rapido.addStackDir(path.join(__dirname, '..'));

// Multiple stacks with the same command names? Make one of the stacks
// exclusive to avoid ambigous commands
rapido.exclusiveStackCommands('raptorjs');

// Don't want to list a command in one of the enabled stacks?
// Then hide it:
rapido.hideCommand('another-stack', 'useless command');

// Now run Rápido and let it take care of the rest!
rapido.run(process.argv);

You'll then want to register your script in the package.json file for your Node module so that it can be installed globally:

{
 "bin": {
    "raptor": "bin/raptor",
    ...
  }
  ...
}

Your command line tool is ready to be installed:

npm install raptor --global

Now, when you launch your custom script, you will be shown something similar to the following: Screenshot

npm loves you