Skip to content

Latest commit

 

History

History
252 lines (198 loc) · 8.67 KB

File metadata and controls

252 lines (198 loc) · 8.67 KB

The available methods are described here:

parse(args)

Parses the given list of arguments based on the provided definition, and returns an object containing the resulting options, and the calculated location where the script is expected to be found. If any error is generated during the process, they will be registered inside an errors field. The form is:

type ParsingOutput = {
  /** Location based solely on supplied namespaces/commands */
  location: string[];
  /** Calculated options */
  options: { _: string[]; [key: string]: any };
  /** Errors originated while parsing */
  errors: string[];
}

If no command is found in the parsing process, an error with a suggestion (the closest to the one suplied) will be returned.

TIP: You can define an option as required (required: true), which will verify that such option is present in the provided arguments, setting an error otherwise.

This library also interprets the delimiter -- to stop parsing, including the remaning arguments as an array inside ParsingOutput.options.__

The execution of this example would be:

{
  "options": {
    "source": ".", "debug": false, "__": ["someother-external-option"]
  },
  "location": ["builder", "build"]
}

option-value syntax

The library support three ways for specifying the value of an option:

  • {alias} {value} as separate arguments (e.g --delay 10)
  • {alias}={value} for long aliases (more than one letter, e.g. --delay=10)
  • {alias}{value} for short aliases (a single letter, e.g. -d10)

Boolean options with short aliases can also be concatenated with a single leading -, e.g:

$ ls -la   # list also hidden files, in long format
$ ls -l -a # same as above

run(args?)

Parses the given options by calling parse(args), and executes the script in the computed location, forwarding the parsed options. If no arguments are provided, the args value defaults to process.argv.slice(2). With the following example (action.js):

new Cli({
  cmd: {
    options: {
      log: { type: "boolean" },
    },
    action: ({ options }) => {
      if (options.log) {
        console.log("Log from cmd");
      }
    },
  },
}).run();

invoking with node action.js cmd --log will print "Log from cmd" into the console.

This method has three main behaviours: print version, print help and execute a command:

  • print version: if autoincluded version is enabled and version option is provided, version will be printed.
  • print help: if autoincluded help is enabled and help option is provided, or a cli without rootCommand is invoked without location, or a namespace is invoked, help will be generated. If any errors configured in CliOptions.errors.onGenerateHelp are generated, they will be outputted before the help.
  • execute command: if any errors configured in CliOptions.errors.onExecuteCommand are generated, they will be printed and execution will end with status 1. Otherwise, the script location will be calculated, and the corresponding script executed.

If a cli application does not have registered a root command (logic executed without any supplied namespace/command), it should be configured with CliOptions.rootCommand: false. By doing this, when the cli application is invoked with no arguments, full help will be shown (see this docker example).

You also use CliOptions.rootCommand to define a default command to execute, when no command/namespace is supplied (check this webpack-cli example).

[Typescript] Typing command's options

When defining a command handler inside a script file, in order to have typed options the following steps are needed:

  • Define the command using Cli.defineCommand:
const command = Cli.defineCommand({
  // ...
  options: {
    type: { type: "string", enum: ["type-1", "type-2", "type-3"] as const},
    elements: { type: "list" },
    value: { type: "float", required: true },
    files: { positional: true, required: true }
  }
})
  • Get the type for the options by using Cli.CommandOptions:
function handler(options: Cli.CommandOptions<typeof command>){
  // options: {
  //   type: "type-1" | "type-2" | "type-3" | undefined;
  //   elements: string[] | undefined;
  //   value: number;
  //   files: string[]
  //   _: string[];
  //   __?: string[];
  //  }
}

[Typescript] Typing namespace's options

When defining a namespace handler inside a script file, in order to have typed options the following steps are needed:

  • Define the namespace using Cli.defineNamespace:
const namespace = Cli.defineNamespace({
  // ...
  options: {
    get: {
      kind: "command",
      options: { key: { kind: "option", type: "string" } },
    },
    set: {
      kind: "command",
      options: {
        key: { kind: "option", type: "string", required: true },
        set: { kind: "option", type: "string", required: true },
      },
    },
    globalopt: { kind: "option", type: "string"}
  },
});
  • Get the type for the options by using Cli.NamespaceOptions:
type ConfigOptions = Cli.NamespaceOptions<typeof namespace>;
function setHandler(options: ConfigOptions["set"]){
  // options: {
  //   key: string;
  //   value: string;
  //   globalopt: string | undefined
  //   _: string[];
  //   __?: string[];
  //  }
}

help(location?)

Generates and outputs help message based on the provided definition. Given the following code (test.js):

const definition = {
  nms: {
    description: "Description for the namespace",
    options: {
      cmd: {
        kind: "command",
        description: "Description for the command",
        options: {
          cmdOption: {
            positional: 0
          }
        }
      },
    },
  },
  gcmd: {
    kind: "command",
    description: "Description for global command",
  },
  globalOption: {
    aliases: ["g", "global"],
    default: "globalvalue",
    description: "Option shared between all commands",
  },
};

new Cli(definition, { cliDescription: "Cli for testing purposes" }).help();

will output:

Usage:  test NAMESPACE|COMMAND [OPTIONS]

Cli for testing purposes

Namespaces:
  nms           Description for the namespace

Commands:
  gcmd          Description for global command

Options:
  -g, --global  Option shared between all commands (default: "globalvalue")
  -h, --help    Display global help, or scoped to a namespace/command

The optional argument location enables the generation of scoped help. For the above definition, the following code:

new Cli(definition).help(["nms"]);

will output:

Usage:  test nms COMMAND [OPTIONS]

Description for the namespace

Commands:
  cmd  Description for the command

Options:
  -g, --global  Option shared between all commands (default: "globalvalue")
  -h, --help    Display global help, or scoped to a namespace/command

In the case of commands, you may specify usage option to override default section content.

The library also checks process.stdout.columns to format the help and line-breaks appropriately.

TIP: any DefinitionElement can be hidden from the generated help by using hidden:true on its definition.

Note help-generation option is auto-included by default. This can be configured via CliOptions.help

version()

Prints the formatted version of the current cli application: finds the package.json for the current application, and prints its name and version.

Note version-generation option is auto-included by default. This can be configured via CliOptions.version

completions()

Generates and outputs bash-completion script contents. This can instead be included as a command and be managed by Cli.run, check: bash completion

configContent()

Find and parse configuration files defined via CliOptions.configFile.
In several cases, undefined may be returned:

  • No CliOptions.configFile configured
  • No file is found from the provided list (CliOptions.configFile.names)
  • An error is generated while parsing the file contents

Otherwise, the parsed content is returned (hopefully, an object containing global options defined in the cli).

envContent()

Extract options from environment variables matching CliOptions.envPrefix.
Will return undefined if no prefix value is configured.