1.3.0 • Published 1 year ago

@thefarce/commando v1.3.0

Weekly downloads
1
License
SEE LICENSE IN LI...
Repository
bitbucket
Last release
1 year ago

Commando

A node module for creating command line programs easily and intuitively.

Installation

npm install @thefarce/commando

Usage

The Commando package is designed to make creating command-line interfaces (CLIs) painless. It does this by providing sensible default behaviours and allowing simple, expressive declarations.

Simple Programs

A very simple program with little complexity is extremely easy to write. The following is a complete CLI to a script that performs one function.

import commando from '@thefarce/commando';

const program = commando.program(
  () => console.log("Hello, World!")
);

// Now just run the program.
program();

Running this program with node say-hello.js will print Hello, World! to the console.

$ node say-hello.js
Hello, World!

While this is slightly more complex than a simple script:

console.log("Hello, World!");

The added indirection makes it extremely easy to enhance your program later on as you expand its feature-set.

There are at least three viable patterns when writing programs with @thefarce/commando:

  1. command-line options (typed!)
  2. git-style subcommands (modular!)
  3. metaprogramming (eh? wot!?)

Command-Line Options

Command-line arguments are supported with an easy, and expressive syntax. It is designed to be very intuitive to anyone familiar with unix-style command-line interfaces.

Let's take the prior program and adapt it to take an optional name argument and greet that name.

import commando from '@thefarce/commando';

const program = commando.program(
  ($runtime) => {
    // Default to "World" if we don't get anything passed in.
    let name = "World";

    // If we got any number of arguments, use the first one as our name.
    if ($runtime.arguments.length) {
      name = $runtime.arguments[0].value;
    }

    console.log(`Hello, ${name}!`);
  }
);

Notice we added a $runtime argument to the entry function. Before we discuss that, let's look at it's execution with a couple of different examples:

$ node say-hello.js
Hello, World!

$ node say-hello.js Bob
Hello, Bob!

$ node say-hello.js Sloopy!
Hello, Sloopy!

Now we can greet almost anyone!

Command-Line Options

In addition to simple arguments, we can easily and intuitively define command-line options. Options are like arguments, except that they are unordered, predefined, and structured.

Unordered

Unlike arguments, which are interpreted by their order of appearance, options are unordered, meaning that they can appear in any order without impacting their meaning.

Predefined

Arguments are handled by the program as a matter of course. They are passed into the program through the context.program.arguments parameter and the manner of their parsing, interpretation, and handling is defined within the execution of the script. These can have any value (though not all values may make sense or be handled).

Options, however, are typically denoted with hyphens (- or --) and may appear anywhere in the argument list.

Some options are accompanied by arguments as well. For example, to specify a color in your program, you may opt to use a "color" options, like this: node myprog.js --color red. Arguments to options are sometimes called the option's values, and the option is said to take those arguments or values.

An option that takes no value is often called a flag. Flags are typically interpreted as boolean values, with their presence being "truthy" and their absence being "falsey." For example, you may wish for your program to have the ability to run without output to stdout. In this case, you may choose to define a --silent flag. If the flag is not present, stdout receives data. If the flag is present, the user is opting for the program to run silently. Inverting this behavior with the --verbose flag inverts that logic, defaulting the program to silence, but allowing verbosity.

Structured

In @thefarce/commando, it's possible to add considerable structure to the program's options, including type, requirement, default values, value enumerations, internal naming, and a brief description.

See the Options section for detialed information about this.

Examples

Here are a few simple examples of how to define and use options in @thefarce/commando.

Complete Examples for Each Type

String option (using every possible option)

.option('-c --color {String+} <useColor=red> (red|green|blue) The color of the output')

Interpretation guide:

  • -c --color allows both the "short" style -c or the "long" style, --color.
  • {String} interprets all values as strings. The + means multiple occurances are allowed.
  • <useColor=red> internally represent this with the name useColor rather than color. =red means use "red" as the default value if the option is omitted.
  • (red|green|blue) allow only these three values.
  • [blue] Use the default value "blue". This value overrides the value specified in <useColor=red>.
  • The color of the output the help text associated with this option
More Examples

Execution examples:

  • node say-hello.js (options: {color: null})
  • node say-hello.js -c red (options: {color: "red"})
  • node say-hello.js --color red (options: {color: "red"})
  • node say-hello.js --color 123 ((options: {color: "123"})
  • node say-hello.js --color (options: {color: null})

An example flag with little definition .option('-c --color')

  • node say-hello.js (options: {color: false})
  • node say-hello.js -c (options: {color: true})
  • node say-hello.js --color (options: {color: true})

Specifying a value type .option('-c --color {String}')

  • node say-hello.js (options: {color: null})
  • node say-hello.js -c red (options: {color: "red"})
  • node say-hello.js --color red (options: {color: "red"})
  • node say-hello.js --color 123 ((options: {color: "123"})
  • node say-hello.js --color (options: {color: null})
1.3.0

1 year ago

1.2.0

2 years ago

1.1.0

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.9.10

3 years ago

0.9.9

3 years ago

0.2.0

5 years ago

0.1.0

5 years ago