Coder Social home page Coder Social logo

cliparse-node's Introduction

Declarative CLI parsing for node apps

Build Status Coverage Status

This is a library designed to express command-line options. It supports commands and subcommands (at an arbitrary depth), automatically generates help text and usage contents. You can use custom parsers for attributes and options values (types supported out of the box: int, bool, string).

Its design is vaguely inspired from optparse-applicative which is a great CLI parsing library. JS being not as expressive as Haskell, a direct port is not possible.

Disclaimer:

This library has been started by @divarvel as part of his job at Clever Cloud. Since he left the company and doesn't use cliparse nor wishes to maintain it anymore, we mutually agreed to transfer ownership of the project to CleverCloud.

Big thanks to him for producing this library!

Enough talk, show me the code

npm install cliparse
#!/usr/bin/env node

var cliparse = require("cliparse");
var parsers = cliparse.parsers;

function echoModule(params) {
    
}

function addModule(params) {
    
}

var cliParser = cliparse.cli({
  name: "my-executable",
  description: "Simple CLI written for the sake of the example",
  commands: [

    cliparse.command(
      "echo",
      { description: "Display the given value",
        args: [ cliparse.argument("value", { description: "Simple value" })],
        options: [ cliparse.flag("reverse", { aliases: ["r"], description: "Reverse the value"}) ]
      },
      echoModule),

    cliparse.command(
      "add2",
      { description: "Add 2 to the given integer and display the result",
        args: [
          cliparse.argument("int",
            { default: 0,
              parser: parsers.intParser,
              description: "Int to add 2 to" })
        ]
      },
      addModule)
  ]
});

cliparse.parse(cliParser);

Where echoModule and addModule are callbacks taking a { args: ['value'], options: {key: 'value'} } parameter.

Generated output

Top-level help

$ my-executable --help
Usage: my-executable
Simple CLI written for the sake of the example.


Options:
[--help, -?]                    Display help about this program

Available commands:
help                            Display help about this program
echo VALUE                      Display the given value
add2 [INT]                      Add 2 to the given integer and display the result

Command-level help

$ my-executable echo --help
Usage : my-executable echo VALUE
display the given value

Arguments:
VALUE                           Simple value

Options:
[--help, -?]                    Display help about this program
[--reverse, -r]                 Reverse the value

Subcommands

The command constructor takes an optional commands attribute which allows you to nest subcommands at an arbitrary level.

var testCli = cliparse.cli({
  name: "testCli",
  description: "Simple CLI written for the sake of the example",
  commands: [
    cliparse.command(
      "number",
      { description: "perform simple arithmetic calculations",
        commands: [
          cliparse.command(
            "add",
            { description: "add two integers",
              args: [ intArgument, intArgument]
            }, numberModule.add),
          cliparse.command(
            "multiply",
            { description: "multiply two integers",
              args: [ intArgument, intArgument]
            }, numberModule.multiply)
        ]
      }),
  ]
});

Help command

An help command is automatically generated, with the following syntax:

$ my-executable help <command> <subcommand> <...>

It can be disabled by setting helpCommand to false in cliparse.cli options.

Autocompletion

CLI parse allows you to generate autocompletion scripts for bash and zsh (work in progress). Generate the script in your npm post-install hook and add it to your users shell completion scripts to enable it.

It supports completion on commands, options and arguments, as well as on the help command. Completion on options and arguments are configurable: you can declare your own completion methods.

All the completion logic is handled within your app, so it will work with dynamically defined commands.

Bash

Generate the completion script and put it in bash completion dir:

$ my-executable --bash-autocomplete-script /complete/path/to/my-executable > ~/.bash_completion.d/my-executable

Normally .bash_completion.d is automatically sourced. You can put the file where you want and source it manually.

ZSH

Generate the completion script and put it in zsh completion dir:

$ my-executable --zsh-autocomplete-script /complete/path/to/my-executable > ~/.zsh.d/completion/_my-executable

The file name must be _my-executable (if your executable is named my-executable). You can put the file where you want as long as it's in a directory listed in $fpath.

Custom completion

You can have custom completion for option or arguments, by passing a custom complete function (see API).

For instance to complete on a list of colors:

var colorCompleter = function() {
  return autocomplete.words(['mauve', 'blue', 'yellow', 'purple', 'parabolic']);
};

To complete on a list of files:

var fileCompleter = function() {
  return autocomplete.files;
};

The complete function can also return a promise for async results.

API

cli

cli(opts, cb);

Where opts can contain

  • name: the name of the executable (if not provided, process.argv is used)
  • description: a one-line description of the executable
  • version: the version number of the executable (displayed by --version. Default value: null
  • options: array of top-level options (constructed with option or flag). Default value: [].
  • commands: array of commands (constructed with command). Default value: []
  • args: array of arguments (constructed with argument). If your app doesn't have commands.
  • helpCommand: Generate a help command. Default value: true.

If your application is not solely made of commands, you can pass an action callback. If you don't give a callback, calling your application without any argument will display a usage message describing the available commands.

option

option(name, opts);

Where name is the name of the flag, and opts can contain

  • aliases: array of other names (the shorthand name for instance. Default value: []
  • metavar: the name of the value of the option (if applicable: for flags, see below)
  • parser: the parser used to parse the value. Default value: stringParser which is a noop parser returning the string.
  • description: a single-line description of what the option is about. Default value: the empty string.
  • required: make option mandatory
  • default: value used if the option is not given any value. If set, overrides the required setting.
  • complete: a function returning completion results for the option (or a promise of results). Default value: a function returning an empty result.
  • expects_value: does the option expect a value? Default: true. Rather than setting it yourself, use flag.

flag

Shorthand for flags (ie options with boolean values, defaulting to false, doesn't expect a value)

flag(name, opts);

Acts like option, with different defaults:

  • parser defaults to booleanParser, which parses boolean values
  • default defaults to false

argument

argument(name, opts);

Where opts can contain

  • parser: ther parser used to parse the value of the argument. Default value: stringParser
  • description: a single-line description of what the argument is about.
  • default: value used if the argument is not given any value
  • complete: a function returning completion results for the argument. Default value: a function returning an empty result.

command

command(name, opts, cb);

Where name is the name of the command , and opts can contain

  • description: a single line description of the command
  • args: array of arguments (constructed with argument). Default value: []
  • options: array of options (constructed with option). Default value: []
  • commands: array of subcommands (constructed with command). Default value: []

cb is a callback which is called when the command match (if no subcommand match). It is called with a { args: ['value'], options: {key: 'value'}} object. opts contains both the options of the command and the options of the parent commands.

Parsers

Basic scalar types (int, bool, and string) are already supported. It is possible to declare your own parsers to validate more specific types of values (eg. enums).

A parser is a function String -> Result where Result is either

  • { success: <parsed value> }
  • or { error: <error message> }

Parser results can be constructed with parsers.success(<value>) and parsers.error(<reason>).

For instance, to parse an hexadecimal RBG color:

var colorParser = function(input) {
  var pattern = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
  var matches = input.match(pattern);
  if(matches !== null) {
    var components = matches.slice(1,4)
          .map(function(x) { return parseInt(x, 16); });
    return parsers.success(components);
  } else {
    return parsers.error("invalid color code");
  }
}

Autocompletion helpers

Autocompletion results

autocomplete.empty: no results

autocomplete.words([โ€ฆ]): list of words

autocomplete.glob(<glob>): files matching glob (eg. *.log).

autocomplete.files: files

autocomplete.directories: directories

You can combine autocompletion results:

autocomplete.mappend(<result1, result2>): combine results from result1 and result2. As globs can't be combined, the last one wins (if set).

autocomplete.mconcat([ <results> ]): reduce a list of result to a composite result with mappend. If the list is empty, then empty is returned.

Contributing

Make sure you don't break anything.

npm test

ToDo

For 0.3.0

Later

cliparse-node's People

Contributors

blackyoup avatar chrishiestand avatar davlgd avatar divarvel avatar hsablonniere avatar judu avatar miton18 avatar mostalive avatar objectisadvantag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cliparse-node's Issues

Cleaner display of errors

Right now the error display is a bit crude:

./subcommands.js number add AA BB
int: invalid int: AA
int: invalid int: BB

Usage: testCli number add INT INT
add two integers

Arguments:
INT                 int value
INT                 int value

Options:
[--help, -?]        Display help about this program
[--version, -V]     Display the version of this program

Add a --version flag

And maybe display the version number under Available commands when you just call $ my-executable ?

Support for variadic arguments

Right now, CLI parse only supports a fixed number of arguments.
What needs to be done:

  • the declaration syntax
  • the implementation

stringParser: empty options are passed as boolean true

In the case of user input error while using options in the form my-executable --myvar1 --myvar2 blue then myvar1 will be set as boolean true, when I think the general case is that empty option strings should return an error. Whereas in the case of flags, of course boolean values are desired.

I'd be happy to submit a pull request, time permitting, with a patch. But I wasn't sure what the ideal solution would be in @divarvel 's mind.

I have a simple workaround for now:

function valid_string_parser(string) {

    if (Boolean(string) === string) {
        return parsers.error('empty strings are not allowed');
    }

    return parsers.success(string.toString());
}

Dedicated ZSH completion

The zsh completion support is currently using zsh's bash completion compatibility layer and does not use zsh's completion support to its full extent.

There is a WIP in the zsh-completion branch, but it's not fully working.
I could use some help on this, as I'm not very proficient with zsh completion internals

Ownership transfer to Clever Cloud

I have created this library as part of my job at Clever Cloud. Since I've left the company and I don't use cliparse anymore, the Clever Cloud team and I have decided to transfer ownership.

I'll transfer ownership of the npm package to clever cloud, and will shut down this repo and add a note redirecting to its Clever Cloud clone (I can't directly transfer its ownership to the CleverCloud organization because I can't create repos in it).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.