go command line option parser

go-flags: a go library for parsing command line arguments

GoDoc Build Status Coverage Status

This library provides similar functionality to the builtin flag library of go, but provides much more functionality and nicer formatting. From the documentation:

Package flags provides an extensive command line option parser. The flags package is similar in functionality to the go builtin flag package but provides more options and uses reflection to provide a convenient and succinct way of specifying command line options.

Supported features:

  • Options with short names (-v)
  • Options with long names (--verbose)
  • Options with and without arguments (bool v.s. other type)
  • Options with optional arguments and default values
  • Multiple option groups each containing a set of options
  • Generate and print well-formatted help message
  • Passing remaining command line arguments after -- (optional)
  • Ignoring unknown command line options (optional)
  • Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
  • Supports multiple short options -aux
  • Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
  • Supports same option multiple times (can store in slice or last option counts)
  • Supports maps
  • Supports function callbacks
  • Supports namespaces for (nested) option groups

The flags package uses structs, reflection and struct field tags to allow users to specify command line options. This results in very simple and concise specification of your application options. For example:

type Options struct {
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
}

This specifies one option with a short name -v and a long name --verbose. When either -v or --verbose is found on the command line, a 'true' value will be appended to the Verbose field. e.g. when specifying -vvv, the resulting value of Verbose will be {[true, true, true]}.

Example:

var opts struct {
	// Slice of bool will append 'true' each time the option
	// is encountered (can be set multiple times, like -vvv)
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`

	// Example of automatic marshalling to desired type (uint)
	Offset uint `long:"offset" description:"Offset"`

	// Example of a callback, called each time the option is found.
	Call func(string) `short:"c" description:"Call phone number"`

	// Example of a required flag
	Name string `short:"n" long:"name" description:"A name" required:"true"`

	// Example of a flag restricted to a pre-defined set of strings
	Animal string `long:"animal" choice:"cat" choice:"dog"`

	// Example of a value name
	File string `short:"f" long:"file" description:"A file" value-name:"FILE"`

	// Example of a pointer
	Ptr *int `short:"p" description:"A pointer to an integer"`

	// Example of a slice of strings
	StringSlice []string `short:"s" description:"A slice of strings"`

	// Example of a slice of pointers
	PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"`

	// Example of a map
	IntMap map[string]int `long:"intmap" description:"A map from string to int"`
}

// Callback which will invoke callto:<argument> to call a number.
// Note that this works just on OS X (and probably only with
// Skype) but it shows the idea.
opts.Call = func(num string) {
	cmd := exec.Command("open", "callto:"+num)
	cmd.Start()
	cmd.Process.Release()
}

// Make some fake arguments to parse.
args := []string{
	"-vv",
	"--offset=5",
	"-n", "Me",
	"--animal", "dog", // anything other than "cat" or "dog" will raise an error
	"-p", "3",
	"-s", "hello",
	"-s", "world",
	"--ptrslice", "hello",
	"--ptrslice", "world",
	"--intmap", "a:1",
	"--intmap", "b:5",
	"arg1",
	"arg2",
	"arg3",
}

// Parse flags from `args'. Note that here we use flags.ParseArgs for
// the sake of making a working example. Normally, you would simply use
// flags.Parse(&opts) which uses os.Args
args, err := flags.ParseArgs(&opts, args)

if err != nil {
	panic(err)
}

fmt.Printf("Verbosity: %v\n", opts.Verbose)
fmt.Printf("Offset: %d\n", opts.Offset)
fmt.Printf("Name: %s\n", opts.Name)
fmt.Printf("Animal: %s\n", opts.Animal)
fmt.Printf("Ptr: %d\n", *opts.Ptr)
fmt.Printf("StringSlice: %v\n", opts.StringSlice)
fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1])
fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"])
fmt.Printf("Remaining args: %s\n", strings.Join(args, " "))

// Output: Verbosity: [true true]
// Offset: 5
// Name: Me
// Ptr: 3
// StringSlice: [hello world]
// PtrSlice: [hello world]
// IntMap: [a:1 b:5]
// Remaining args: arg1 arg2 arg3

More information can be found in the godocs: http://godoc.org/github.com/jessevdk/go-flags

Comments
  • do quoting in INI and Help

    do quoting in INI and Help

    I am sorry that this is such a big single commit, but I think all parts are essential even the INI error handling.

    I have done the following:

    • "ini" is now a struct with sections and the filename
    • "iniValue" has a line number so we can use it later for sane errors
    • quote output of String values for Help
    • quote output of String values for INI write (this is the reason why so much test data has changed)
    • allow quoting for every value (even map values) for INI read

    The whole thing started out as a little fix for #88 but i noticed that there is no handling of \n for INI files.

  • Group namespaces

    Group namespaces

    This pull request implements group namespaces as described in #37 and should therefore fix and close #37. I had to add the multiTag structure to the Group type so it can be used later on. Subgroups inherit their namespace from their parents which opens the question for me if this request should also add a namespace separator which can be globally set per parser?

  • Allow passing value starting with - to custom option

    Allow passing value starting with - to custom option

    We have a case where some of our custom flags for the Cloud Foundry CLI have string values that take -1 as a value to signal special cases. For example, when we're setting a Maximum Allowed Memory Size (eg 1MB, 4GB, etc...) and we want this value to be unlimited, we use -1.

    This pr will enable custom flags to take values with -.

  • Improve travis configuration

    Improve travis configuration

    The linters are currently not failing the build if they find anything because I have currently no idea how to mark errors as false-positives. I will do that in the future but it is still good to have it in the build if the tools suddenly allow this.

  • Option new methods

    Option new methods

    Hopefully, this is helpful for everyone...

    • added Option.Field() method to recover the struct field associated with the option
    • added Option.IsSetDefault() to help distinguish cases where the option was really set or set with default values
  • Example for usage of bash completion

    Example for usage of bash completion

    So I am playing around with the new bash completion and it works great (except two things I will correct with pull requests). But I am missing an example for using it in a program. Is this the idiomatic way?

    p := flags.NewParser(&opts, flags.Default)
    
    if _, err := p.Parse(); err != nil {
        panic(err)
    }
    
    if len(os.Getenv("GO_FLAGS_COMPLETION")) != 0 {
        os.Exit(123)
    }
    
    // and now the code of the program
    

    If yes, I think we should add a flag or method to indicate that the completion code ran and that the user should stop the program.

  • Add field for callback to handle unknown/unmapped options during parse

    Add field for callback to handle unknown/unmapped options during parse

    This is the follow-up from our discussion in https://github.com/jessevdk/go-flags/pull/111 Hope this matches what you had in mind. Let me know if you'd like to see any changes.

  • Escape default values for Help output

    Escape default values for Help output

    "Special" characters like \n \t and so on as default value of an option are confusing in the Help output. I propose that we escape all default value outputs in the Help output. Or is there a better way?

    For example

    Sep string `long:"sep" default:"\n"`
    

    Looks currently like this

    --sep=   (
    )
    

    And I think that the following is much clearer

    --sep=   (\n)
    
  • Documentation for groups and commands

    Documentation for groups and commands

    Some documentation explaining the basics of groups and commands would be greatly appreciated.

    I am considering using go-flags for my project, and I need something like the "go" program command line processing. That is, writing myproject command ...options... with different options available for different commands. Top-level help should list the commands, each command's help should list its options. Some options are universal, some are shared by several commands, some are unique to specific commands.

    It seems that go-flags will do exactly what I want in a very nice way - if I knew how to use groups/commands properly. Since there's no documentation for that, I am looking at the code to reverse-engineer the proper way to use it, which may take longer than just hacking an application solution myself :-(

  • space between flag and argument

    space between flag and argument

    (whoops, pressed enter accidentally, updating issue now...)

    Works:

    my-app --file="config.yml"
    my-app -f=config.yml
    my-app -fconfig.yml
    

    Doesn't work:

    my-app -f config.yml
    

    Is this intended behaviour? I personally prefer leaving a space, which is why I hit this behaviour.

  • Cannot read single dash as a non-option argument

    Cannot read single dash as a non-option argument

    It is a relatively common idiom in unix command line applications to allow reading from stdin by passing - as a filename. For instance, many implementations of tar will accept

    tar -x -v -f -
    

    as a way of extracting an archive piped from stdin.

    We would like to have a similar interface in one of our applications, but when we try and catch - as one of the "remaining, non-option arguments " returned in the []string from ParseArgs, it isn't there. Go-flags seems to silently swallow a single dash at the end of a list of flags.

    It would be awesome if go-flags supported single dashes as remaining arguments, since our workaround for this is incredibly hacky and verbose.

    Thanks, Kyle

  • Add option for key value delimiter

    Add option for key value delimiter

    Description

    Currently, a map flag only allows : as the delimiter between key and value, e.g. -f key:value. This PR allows customisation of the delimiter so users can choose a delimiter that is better suited for their use case. For example, it's more natural to use -e key=value for a map flag of environment variables.

    Users can specify the delimiter via tag options. The default delimiter is :.

    type MyFlag struct {
        MyMap map[string]string `short:"f" key-value-delimiter:"="`
    }
    
  • Update to run go-flags on AIX

    Update to run go-flags on AIX

    I tried to build the datadog-agent for AIX, and I had difficulties because it didn't build the agent for AIX. Your library is used by datadog-agent, which is why I encountered this problem.

  • Is it possible to have dynamically generated help descriptions?

    Is it possible to have dynamically generated help descriptions?

    Given:

    var opts struct {
       Names []string
    }
    

    I want to provide the tag dynamically since it will depend on the config file read before I parse the command line options. Is this possible?

  • Fix single choice support

    Fix single choice support

    This PR fixes a situation when there is only once choice available. Normally, we probably wouldn't expect it. But it can be in a situation where the software is being actively developed and some feature is being added with future possible extension. Thus giving a single option could be a valid situation.

    Currently, if you pass an incorrect option to a single-optioned parameter, you will get an error with an empty list of possible values: Allowed values are:. This PR adds that single value to the list.

    In addition, this PR adds some tests and fixes broken tests as well (if you think the fix for the broken tests is excessive, I can remove it).

  • How to group subcommands

    How to group subcommands

    Hi,

    I am trying to group the subcommands using the top-level option "group" in the struct field. But instead of grouping the subcommands, it actually groups the options in the subcommands. Here is my code:

    type Cmd1 struct {
    	Opt1         string `long:"opt1" description:"first opt" required:"true"`
    	Opt2         int    `long:"opt2" description:"second opt" default:"10"`
    }
    
    type Cmd2 struct {
    	OptA string `long:"optA" description:"opt a" default:":8080"`
    	OptB string `long:"optB" description:"opt b" default:"debug"`
    }
    
    type MainCmd struct {
    	Cmd1      Cmd1      `group:"group1" namespace:"group1" env-namespace:"group1"`
    	Cmd2     Cmd2     `group:"group2" namespace:"group2" env-namespace:"group2"`
    }
    
    func main() {
    	var mainCmd MainCmd
    	parser := flags.NewParser(&mainCmd, flags.Default) 
    	if _, err := parser.Parse(); err != nil {
    		if err, ok := err.(*flags.Error); ok {
    			if err.Type == flags.ErrHelp {
    				os.Exit(0)
    			}
    			parser.WriteHelp(os.Stdout)
    		}
    		os.Exit(1)
    	}
    }
    

    What I am looking for is when I run the main function, it will print the help message with the grouped subcommands like:

    group1: --Cmd1 group2: --Cmd2

    However it groups the subcommands' options like:

    group1: --group1.opt1=
    --group1.opt2=

    group2: --group2.optA=
    --group2.optB=

    Any ideas or help? Thanks!

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 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
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
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
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
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
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
CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

CONTRIBUTIONS ONLY What does this mean? I do not have time to fix issues myself. The only way fixes or new features will be added is by people submitt

Dec 29, 2022
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
Kong is a command-line parser for Go
Kong is a command-line parser for Go

Kong is a command-line parser for Go Introduction Help Help as a user of a Kong application Defining help in Kong Command handling Switch on the comma

Dec 27, 2022
A simple command line time description parser

Zeit Zeit is an extremely simple command line application to read a natural language time description and output it as a timestamp. The main usecase f

Aug 21, 2021
Brigodier is a command parser & dispatcher, designed and developed for command lines such as for Discord bots or Minecraft chat commands. It is a complete port from Mojang's "brigadier" into Go.

brigodier Brigodier is a command parser & dispatcher, designed and developed to provide a simple and flexible command framework. It can be used in man

Dec 15, 2022
Maybe is a Go package to provide basic functionality for Option type structures

Maybe Maybe is a library that adds an Option data type for some native Go types. What does it offer: The types exported by this library are immutable

Oct 4, 2022
Concurrent ssh-tail sessions and sink option
Concurrent ssh-tail sessions and sink option

ssh-tail This project is one of the problems that I generally face while debugging some system. When I am reproducing the issue on the machine i also

Dec 2, 2022