A Go library for implementing command-line interfaces.

Go CLI Library GoDoc

cli is a library for implementing powerful command-line interfaces in Go. cli is the library that powers the CLI for Packer, Serf, Consul, Vault, Terraform, and Nomad.

Features

  • Easy sub-command based CLIs: cli foo, cli bar, etc.

  • Support for nested subcommands such as cli foo bar.

  • Optional support for default subcommands so cli does something other than error.

  • Support for shell autocompletion of subcommands, flags, and arguments with callbacks in Go. You don't need to write any shell code.

  • Automatic help generation for listing subcommands

  • Automatic help flag recognition of -h, --help, etc.

  • Automatic version flag recognition of -v, --version.

  • Helpers for interacting with the terminal, such as outputting information, asking for input, etc. These are optional, you can always interact with the terminal however you choose.

  • Use of Go interfaces/types makes augmenting various parts of the library a piece of cake.

Example

Below is a simple example of creating and running a CLI

package main

import (
	"log"
	"os"

	"github.com/mitchellh/cli"
)

func main() {
	c := cli.NewCLI("app", "1.0.0")
	c.Args = os.Args[1:]
	c.Commands = map[string]cli.CommandFactory{
		"foo": fooCommandFactory,
		"bar": barCommandFactory,
	}

	exitStatus, err := c.Run()
	if err != nil {
		log.Println(err)
	}

	os.Exit(exitStatus)
}
Owner
Comments
  • Remove newline at the beginning and end of the subcommand template

    Remove newline at the beginning and end of the subcommand template

    This fixes the newline that gets appended within the range in the subcommands template. The reason for this is it makes the CLI UI a little inconsistent with the Commands: help text not having a newline at the beginning or at the end of the All other commands: piece of the help text in Terraform. It also just looks better, IMHO. :)

  • Flags showing up before subcommands

    Flags showing up before subcommands

    Filing this for https://github.com/hashicorp/terraform/issues/1773

    Current behavior: Except for help/version, flags before a subcommand are silently ignored.

    Possible solutions:

    (A) Flags before subcommand cause error (B) Flags before subcommand are passed in as subcommand args

    Unsure what the better behavior. Originally I thought (A) but then I swung to (B) after staring at it a bit.

    Thoughts?

  • Look for help even if a subcommand exists

    Look for help even if a subcommand exists

    This fixes an issue where multiple subcommands are nested, but the user is requesting help for a deeply nested command.

    It's strange that the tests specifically tested the opposite of this behavior, so I'm not sure if this is right @mitchellh

  • Mark commands (and flags) as hidden

    Mark commands (and flags) as hidden

    There isn't currently a way to mark a subcommand as "hidden". It's possible to filter help output to exclude it using a HelpFunc, but the subcommand still appears in the autocompletion. There should either be a way to customize the list of commands which are auto-completed or (better), a first-class mechanism for marking a command as hidden.

    There are a few use cases here, the most prominent being backwards compatibility. I may want to introduce a new command to do something, but I want to have the old command around with a warning for a few releases.

    Another use case involves hidden "internal-only" commands. Sometimes you want some flags or commands that are for internal use only. Again, there's currently no way to achieve this nicely.

    /cc @dadgar

  • Sporadic test failures in

    Sporadic test failures in "TestCLIRun_printCommandHelpSubcommands"

    With Golang 1.6 TestCLIRun_printCommandHelpSubcommands sometimes fail as follows:

    --- FAIL: TestCLIRun_printCommandHelpSubcommands (0.00s) 
            cli_test.go:344: bad: []string{"-h", "foo"} 
    
                    '"donuts\n\nSubcommands:\n\n    longer    hi!\n    bar       hi!\n\n"' 
    
                    '"donuts\n\nSubcommands:\n\n    bar       hi!\n    longer    hi!\n\n"' 
    
  • Ui.Error, Info, Output should take variadic arguments

    Ui.Error, Info, Output should take variadic arguments

    Instead of Ui.Error(string) it should be Ui.Error(string, interface{}...). This should then call fmt.Fprintf(w, string, ...v).

    Almost all of my calls to Ui.(Error|Info|Output) end up including a call to fmt.Sprintf.

  • Introduce CommandHidden to hide commands from help and autocomplete

    Introduce CommandHidden to hide commands from help and autocomplete

    Fixes #65

    This introduces a new optional interface CommandHidden. When implemented, the result of Hidden() allows a command to declare itself as hidden or not. A hidden command does not show up in the help callback map or for command autocompletion.

    This doesn't affect flags at all. In the future when we take a look at flags more holistically, we should consider allowing flags to declare themselves hidden as well. However, this PR doesn't affect that in any way.

  • Add Print to interface

    Add Print to interface

    Adds the Print() function to the Ui Interface. Print takes a message string, and Prints it to the UI without appending a newline character to the end of the message.

    This allows for multiple calls to Print() to write output to the same line of the writer.

  • '--help' and '--version' options returns exit status 1.

    '--help' and '--version' options returns exit status 1.

    Now, {command} --help and {command} --version returns exit status 1. For example,

    $ ./bin/packer --help
    ...
    $ echo $?
    1
    $ ./bin/packer --version
    0.8.7
    $ echo $?
    1
    

    These are normal cases, thus exit status 0 is better I think. This PR changes the behavior as follows.

    $ ./bin/packer --help
    ...
    $ echo $?
    0
    $ ./bin/packer --version
    0.8.7
    $ echo $?
    0
    

    Could you check it?

  • Error building

    Error building

    $ go version
    go version go1.4.2 solaris/amd64
    $ go build github.com/mitchellh/cli 
    # github.com/mitchellh/cli
    src/github.com/mitchellh/cli/ui.go:79: undefined: terminal.IsTerminal
    src/github.com/mitchellh/cli/ui.go:81: undefined: terminal.ReadPassword
    
  • Added support for setting default commands

    Added support for setting default commands

    I ran into a situation where I needed my program to just launch something with no subcommand, but also have a set of subcommands to interact with data and a running daemon. All bases should be covered here (tests, help text, etc...).

  • Subcommand parsing logic stops at first flag

    Subcommand parsing logic stops at first flag

    Noticed this behavior on an internal tool, essentially, if you have flags defined for a command, then execute a subcommand of that command with a flag before the subcommand, then it identifies the command as the subcommand.

    For example, if we take the test cases @ https://github.com/mitchellh/cli/blob/master/cli_test.go#L1459-L1489 and change it to:

    func TestCLISubcommand_nested(t *testing.T) {
    	testCases := []struct {
    		args       []string
    		subcommand string
    	}{
    		{[]string{"bar"}, "bar"},
    		{[]string{"foo", "-h"}, "foo"},
    		{[]string{"-h", "bar"}, "bar"},
    		{[]string{"foo", "bar", "-h"}, "foo bar"},
    		{[]string{"foo", "bar", "baz", "-h"}, "foo bar baz"},
    		{[]string{"foo", "bar", "-h", "baz"}, "foo bar"}, // expected match would be `foo bar baz`
    		{[]string{"-h", "foo", "bar"}, "foo bar"},
    	}
    
    	for _, testCase := range testCases {
    		cli := &CLI{
    			Args: testCase.args,
    			Commands: map[string]CommandFactory{
    				"foo bar": func() (Command, error) {
    					return new(MockCommand), nil
    				},
    				"foo bar baz": func() (Command, error) {
    					return new(MockCommand), nil
    				},
    			},
    		}
    		result := cli.Subcommand()
    
    		if result != testCase.subcommand {
    			t.Errorf("Expected %#v, got %#v. Args: %#v",
    				testCase.subcommand, result, testCase.args)
    		}
    	}
    }
    

    I guess the question is, with other tools like cobra which handle flags anywhere within the arguments, does it make sense to change this library's behavior?

  • How to write shell completion function in Go

    How to write shell completion function in Go

    For example the following is a zsh completion function for command foo:

    #compdef _foo foo
    compadd first second third fourth
    

    So, if we type foo <tab> in the zsh terminal, it suggests first second third fourth.

    How can I do this using cli?

  • Update to complete v2

    Update to complete v2

    Complete v2 includes some improvements, but I mostly perform this PR because it introduced breaking changes which breaks clients of this library which are not yet able to use go modules. If this change won't be accepted I will revert the changes in the complete library.

  • Allow the cli to accpect single lined interactivity

    Allow the cli to accpect single lined interactivity

    • This makes the prompts easier to test, e.g., if we ask for both username and password, we can now simply do printf "myName\nmyPassword\n" | myCli.

    • We don't create a new bufio.Reader each tiem we ask, hopefully it doesn't break someone's program.

    • All the tests pass! :)

Related tags
An open-source GitLab command line tool bringing GitLab's cool features to your command line
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Dec 30, 2022
A command line tool that builds and (re)starts your web application everytime you save a Go or template fileA command line tool that builds and (re)starts your web application everytime you save a Go or template file

# Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web framework yo

Nov 22, 2021
A command line tool to prompt for a value to be included in another command line.

readval is a command line tool which is designed for one specific purpose—to prompt for a value to be included in another command line. readval prints

Dec 22, 2021
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.

asciigraph Go package to make lightweight ASCII line graphs ╭┈╯. Installation go get github.com/guptarohit/asciigraph Usage Basic graph package main

Jan 8, 2023
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.

Table of contents Introduction Reference Contributing Introduction Overview git-xargs is a command-line tool (CLI) for making updates across multiple

Dec 31, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command

git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command. You give git-xargs:

Feb 5, 2022
Package command provide simple API to create modern command-line interface

Package command Package command provide simple API to create modern command-line interface, mainly for lightweight usage, inspired by cobra Usage pack

Jan 16, 2022
A command line tool for simplified docker volume command built with go

dockervol A command line tool for simplified docker volume command built with go. Features: Remove anonymous volume (beta) Remove volume by matching n

Dec 18, 2021
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Mar 27, 2022
Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.

Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to

Dec 30, 2022
A basic REST API implementing crud functionalities with MySQL.

go-crud-app A CRUD REST API with mysql Uses: gorilla/mux gorm Implemented [ ✔ ] GET /book returns list of books as JSON [ ✔ ] GET /book/{id} returns d

Oct 16, 2022
argv - Go library to split command line string as arguments array using the bash syntax.

Argv Argv is a library for Go to split command line string into arguments array. Documentation Documentation can be found at Godoc Example func TestAr

Nov 19, 2022
Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.
Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.

cmdr cmdr is a POSIX-compliant, command-line UI (CLI) library in Golang. It is a getopt-like parser of command-line options, be compatible with the ge

Oct 28, 2022
Flag is a simple but powerful command line option parsing library for Go support infinite level subcommand

Flag Flag is a simple but powerful commandline flag parsing library for Go. Documentation Documentation can be found at Godoc Supported features bool

Sep 26, 2022
A Go library for building command line applications

gocmd A Go library for building command line applications. Features Advanced command line arguments handling Subcommand handling Short and long comman

Dec 21, 2022
A command-line tool and library for generating regular expressions from user-provided test cases
A command-line tool and library for generating regular expressions from user-provided test cases

Table of Contents What does this tool do? Do I still need to learn to write regexes then? Current features How to install? 4.1 The command-line tool 4

Jan 9, 2023
colorStyle is a library of styles for command-line text.
colorStyle is a library of styles for command-line text.

colorStyle ColorStyle is a library of styles for command-line text. Used to modify the style of text for standard output to the terminal interface, yo

Nov 12, 2022
A command line utility and library for generating professional looking invoices in Go.
A command line utility and library for generating professional looking invoices in Go.

ginvoicer A command line utility and library for generating professional looking invoices in Go. This is a very rough draft and there could still be b

Dec 15, 2022
A Go library and a command-line tool to manage Docker Swarm clusters

go-swarm go-swarm is a Go library and command-line tool for managing the creation and maintenance of Docker Swarm cluster. Features: Creates new Swarm

Jul 26, 2022