npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@thefarce/commando

v1.3.0

Published

Command line processing that's intuitive.

Downloads

434

Readme

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})