SkillAgentSearch skills...

Commando

An easy-to-use command-line application builder.

Install / Use

/learn @thatisuday/Commando
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Commando

logo

go-version   Build

Commando helps you create beautiful CLI applications with ease. It parses "getopt(3)" style command-line arguments, supports sub-command architecture, allows a short-name alias for flags and captures required & optional arguments. The motivation behind creating this library is to provide easy-to-use APIs to create simple command-line tools.

This library uses clapper package to parse command-line arguments. Visit the documentation of this package to understand supported arguments and flag patterns.

logo

Documentation

pkg.go.dev

Tutorial

Medium

Installation

$ go get -u "github.com/thatisuday/commando"

Terminology

Let's imagine we are building a CLI tool reactor to generate and manage React front-end projects.

Root command

$ reactor --version
$ reactor -v
$ reactor --help
$ reactor -h

In the example above, the reactor alone is the root-command. Here, the --version and -v are flags. The --version is a long flag name and -v is a short flag name. The -v is an alias for --version. Similarly --help and -h are flags.

Commando adds --version and --help flags (along with their aliases) automatically for the root-command.

Sub command

$ reactor build --dir ./out/dir

In the above example, build is a sub-command. This sub-command has --dir flag, and unlike --help flag, this flag takes a user-input value like ./out/dir we have provided above.

Commando adds --help flag automatically for a sub-command. Also, it registers help and version sub-commands automatically to display CLI usage and version number respectively.

Arguments

$ reactor create <name> --dir <dir>

In the above example, create is a sub-command. The <name> placeholder is for the name argument value that the user is supposed to provide. For example, $ reactor create form --dir ./components/form. Here, form is the value for the name argument.

The root-command can also be configured to take arguments. For example, $ reactor <category> command is valid. If the category argument value doesn't match with any registered sub-command, then the root-command is executed, else the sub-command is executed.

How to configure?

Step 1: executable, version and description setup

First, we need to specify the name of the executable file using commando.SetExecutableName function. This value is same as your root-command name. You can use os.Executable function to get the name of the executable. Normally, you just specify the name of your package because when the user install your module using go get command, Go creates an executable file with the name same as your package name.

Then we need to set the version and the description of our CLI application using CommandRegistry.SetVersion and CommandRegistry.SetDescription function respectively. This version will be displayed with the --version flag (or version sub-command) and description will be displayed with --help flag (or help sub-command).

import "github.com/thatisuday/commando"

func main() {
    commando.
        SetExecutableName("reactor").
        SetVersion("v1.0.0").
        SetDescription("This CLI tool helps you create and manage React projects.")
}

Step 2: Register a sub-command

A sub-command is registered using commando.Register("<sub-command>") function. This function returns the *commando.Command object. If the sub-command is already registered, it returns the registered *commando.Command object.

If nil is passed as an argument, then the root-command is registered. However, Commando automatically registers the root-command and commando.Register(nil) returns the *commando.Command object of the root-command.

Commando automatically registers the root-command to provide built-in support for --help and --version flags, hence you do not need to manually register the root-command unless you want to configure it.

The *commando.Command object is a struct and it provides SetDescription, AddArgument, AddFlag, and SetAction methods.

  • The SetDescription method sets the description of the command.
  • The AddArgument method registers an argument with the command.
  • The AddFlag method registers a flag with the command.
  • The SetAction method registers a function that will be executed with argument values and flag values provided by the user when the root-command or a sub-command is executed by the user.

Step 3: Set a description of a sub-command

commando.
  Register("<sub-command>").
  SetDescription("<sub-command-description>")
  SetShortDescription("<sub-command-short-description>")

The SetDescription and SetShortDescription method takes a string argument tp set the long and a short description of the sub-command and returns the *commando.Command object of the same command. These descriptions are printed when user executes the $ reactor <sub-command> --help command.

You can set a description of the root-command by passing nil as an argument to the Register() function.

Step 4: Add an argument

commando.
  Register("<sub-command>").
  AddArgument("<name>", "<description>", "<default-value>")

The AddArgument method registers an argument with the command. The first argument is the name of the argument and the second argument is the description of that argument.

The third argument is a string value which is the default-value of the argument. If user doesn't provide the value of this argument, this argument will get the value from the default-value. If the default-value is an empty string (""), then it becomes a required argument. If the value of a required argument is not provided by the user, an error message is displayed.

Ideally, you should register all required arguments before the optional arguments. Since these are positional values, it is mandatory to do so, else you would get inappropriate results.

If the argument name ends with ... suffix, then it is considered as a variadic argument. A variadic argument stores all the leftover argument values and concatenate them using command comma (,). Hence a command should only contain one variadic argument and it should be registered after all arguments are registered.

If the argument is already registered, then registration of the argument is skipped without returning an error. You can configure arguments of the root-command by passing nil as an argument to the Register() function.

Step 5: Add a flag

commando.
  Register("<sub-command>").
  AddFlag("<long-name>,<short-name>", "<description>", <dataType>, <defaultValue>).

The AddFlag method registers a flag with the command. The first argument is string value containing the long-name and the short-name of the flag separated by a comma. For example, dir,d is a valid argument value for --dir and -d flags. You can skip the short-name registration if you do not need one by providing only long-name value, like dir.

The second argument sets the description of the flag. This will be displayed with the usage of the command (--help flag).

The third argument is the data-type of the value that will be provided by the user for this flag. The value of this argument could be either commando.Bool, commando.Int or commando.String. If the data-type is commando.Bool, then the flag does not take any user input (like --version flag).

The last argument is the default-value of the flag. The value of this argument must be of the data-type provided in the previous argument. If nil value is provided, then the flag doesn't have any default-value and it becomes required to be provided by the user, except if the data-type is commando.Bool in which case the default-value is false automatically.

If the flag name starts with no- prefix, for example no-clean, the

View on GitHub
GitHub Stars141
CategoryDevelopment
Updated4mo ago
Forks16

Languages

Go

Security Score

97/100

Audited on Nov 7, 2025

No findings