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! :)

A command line parser written in Go

go-cmdline Introduction cmdline is a Go library to parse command line options (with optional default values), arguments and subcommands. Usage The fol

Oct 9, 2022
A command-line arguments parser that will make you smile.

docopt-go An implementation of docopt in the Go programming language. docopt helps you create beautiful command-line interfaces easily: package main

Jan 7, 2023
go command line option parser

go-flags: a go library for parsing command line arguments This library provides similar functionality to the builtin flag library of go, but provides

Dec 22, 2022
Fully featured Go (golang) command line option parser with built-in auto-completion support.

go-getoptions Go option parser inspired on the flexibility of Perl’s GetOpt::Long. Table of Contents Quick overview Examples Simple script Program wit

Dec 14, 2022
A flexible command and option parser for Go

Writ Overview Writ is a flexible option parser with thorough test coverage. It's meant to be simple and "just work". Applications using writ look and

Dec 27, 2022
A Go library for implementing command-line interfaces.

Go CLI Library cli is a library for implementing powerful command-line interfaces in Go. cli is the library that powers the CLI for Packer, Serf, Cons

Jan 1, 2023
Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC

bel Generate TypeScript interfaces from Go structs/interfaces - useful for JSON RPC bel is used in production in https://gitpod.io. Getting started be

Oct 23, 2022
Golang-Devnet-Interfaces - Quick example of using Scrapligo and TextFSM to parse interfaces from Devnet Sandbox

Scrapligo & TextFSM This is a simple example of using the Scrapligo library deve

Mar 7, 2022
GoWrap is a command line tool for generating decorators for Go interfaces

GoWrap GoWrap is a command line tool that generates decorators for Go interface types using simple templates. With GoWrap you can easily add metrics,

Dec 30, 2022
Test your command line interfaces on windows, linux and osx and nodes viá ssh and docker

Commander Define language independent tests for your command line scripts and programs in simple yaml files. It runs on windows, osx and linux It can

Dec 17, 2022
Docli - Command-line interfaces made easy
Docli - Command-line interfaces made easy

Docli Docli is a declarative language for describing command-line interfaces in Go programs. It cuts down the boilerplate to the bare minimum, so you

Aug 20, 2022
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
Command-line tool and library for Windows remote command execution in Go

WinRM for Go Note: if you're looking for the winrm command-line tool, this has been splitted from this project and is available at winrm-cli This is a

Nov 29, 2022
A Go library implementing an FST (finite state transducer)
A Go library implementing an FST (finite state transducer)

vellum A Go library implementing an FST (finite state transducer) capable of: mapping between keys ([]byte) and a value (uint64) enumerating keys in l

Jan 8, 2023
Go library implementing xor filters
Go library implementing xor filters

xorfilter: Go library implementing xor filters Bloom filters are used to quickly check whether an element is part of a set. Xor filters are a faster a

Dec 30, 2022
A simple Go library for 3D ray-tracing rendering, implementing the book Ray Tracing in One Weekend.
A simple Go library for 3D ray-tracing rendering, implementing the book Ray Tracing in One Weekend.

Ray Tracing in Go A Go implementation of the book Ray Tracing in One Weekend. The repository provides a library to describe and render your own scenes

Sep 23, 2022
Our library to use the idealo interfaces in go.

Here you can find our library for idealo. We develop the API endpoints according to our demand and need. You are welcome to help us to further develop this library.

Mar 15, 2022
Go library to interface with Solana JSON RPC and WebSocket interfaces
Go library to interface with Solana JSON RPC and WebSocket interfaces

Solana SDK library for Go Go library to interface with Solana JSON RPC and WebSocket interfaces. Clients for Solana native programs, Solana Program Li

Mar 2, 2022