Git Product home page Git Product logo

getopt's Introduction

getopt build status

Package getopt provides traditional getopt processing for implementing commands that use traditional command lines. The standard Go flag package cannot be used to write a program that parses flags the way ls or ssh does, for example. There are two versions, v1 and v2, both named getopt, that use the following import paths:

	"github.com/pborman/getopt"     // version 1
	"github.com/pborman/getopt/v2"  // version 2

This README describes version 2 of the package, which has a simplified API.

Usage

Getopt supports functionality found in both the standard BSD getopt as well as (one of the many versions of) the GNU getopt_long. Being a Go package, this package makes common usage easy, but still enables more controlled usage if needed.

Typical usage:

	Declare flags and have getopt return pointers to the values.
	helpFlag := getopt.Bool('?', "display help")
	cmdFlag := getopt.StringLong("command", 'c', "default", "the command")

	Declare flags against existing variables.
	var (
		fileName = "/the/default/path"
		timeout = time.Second * 5
		verbose bool
	)
	func init() {
		getopt.Flag(&verbose, 'v', "be verbose")
		getopt.FlagLong(&fileName, "path", 0, "the path")
		getopt.FlagLong(&timeout, "timeout", 't', "some timeout")
	}

	func main() {
		Parse the program arguments
		getopt.Parse()
		Get the remaining positional parameters
		args := getopt.Args()
		...

If you don't want the program to exit on error, use getopt.Getopt:

		err := getopt.Getopt(nil)
		if err != nil {
			code to handle error
			fmt.Fprintln(os.Stderr, err)
		}

Flag Syntax

Support is provided for both short (-f) and long (--flag) options. A single option may have both a short and a long name. Each option may be a flag or a value. A value takes an argument.

Declaring no long names causes this package to process arguments like the traditional BSD getopt.

Short flags may be combined into a single parameter. For example, "-a -b -c" may also be expressed "-abc". Long flags must stand on their own "--alpha --beta"

Values require an argument. For short options the argument may either be immediately following the short name or as the next argument. Only one short value may be combined with short flags in a single argument; the short value must be after all short flags. For example, if f is a flag and v is a value, then:

	-vvalue    (sets v to "value")
	-v value   (sets v to "value")
	-fvvalue   (sets f, and sets v to "value")
	-fv value  (sets f, and sets v to "value")
	-vf value  (set v to "f" and value is the first parameter)

For the long value option val:

	--val value (sets val to "value")
	--val=value (sets val to "value")
	--valvalue  (invalid option "valvalue")

Values with an optional value only set the value if the value is part of the same argument. In any event, the option count is increased and the option is marked as seen.

	-v -f          (sets v and f as being seen)
	-vvalue -f     (sets v to "value" and sets f)
	--val -f       (sets v and f as being seen)
	--val=value -f (sets v to "value" and sets f)

There is no convience function defined for making the value optional. The SetOptional method must be called on the actual Option.

	v := String("val", 'v', "", "the optional v")
	Lookup("v").SetOptional()

	var s string
	FlagLong(&s, "val", 'v', "the optional v).SetOptional()

Parsing continues until the first non-option or "--" is encountered.

The short name "-" can be used, but it either is specified as "-" or as part of a group of options, for example "-f-". If there are no long options specified then "--f" could also be used. If "-" is not declared as an option then the single "-" will also terminate the option processing but unlike "--", the "-" will be part of the remaining arguments.

Advanced Usage

Normally the parsing is performed by calling the Parse function. If it is important to see the order of the options then the Getopt function should be used. The standard Parse function does the equivalent of:

func Parse() {
	if err := getopt.Getopt(os.Args, nil); err != nil {
		fmt.Fprintln(os.Stderr, err)
		s.usage()
		os.Exit(1)
	}
}

When calling Getopt it is the responsibility of the caller to print any errors.

Normally the default option set, CommandLine, is used. Other option sets may be created with New.

After parsing, the sets Args will contain the non-option arguments. If an error is encountered then Args will begin with argument that caused the error.

It is valid to call a set's Parse a second time to amend the current set of flags or values. As an example:

	var a = getopt.Bool('a', "", "The a flag")
	var b = getopt.Bool('b', "", "The a flag")
	var cmd = ""

	var opts = getopt.CommandLine

	opts.Parse(os.Args)
	if opts.NArgs() > 0 {
		cmd = opts.Arg(0)
		opts.Parse(opts.Args())
	}

If called with set to { "prog", "-a", "cmd", "-b", "arg" } then both a and b would be set, cmd would be set to "cmd", and opts.Args() would return { "arg" }.

Unless an option type explicitly prohibits it, an option may appear more than once in the arguments. The last value provided to the option is the value.

Builtin Types

The Flag and FlagLong functions support most standard Go types. For the list, see the description of FlagLong below for a list of supported types.

There are also helper routines to allow single line flag declarations. These types are: Bool, Counter, Duration, Enum, Int16, Int32, Int64, Int, List, Signed, String, Uint16, Uint32, Uint64, Uint, and Unsigned.

Each comes in a short and long flavor, e.g., Bool and BoolLong and include functions to set the flags on the standard command line or for a specific Set of flags.

Except for the Counter, Enum, Signed and Unsigned types, all of these types can be declared using Flag and FlagLong by passing in a pointer to the appropriate type.

Declaring New Flag Types

A pointer to any type that implements the Value interface may be passed to Flag or FlagLong.

VALUEHELP

All non-flag options are created with a "valuehelp" as the last parameter. Valuehelp should be 0, 1, or 2 strings. The first string, if provided, is the usage message for the option. If the second string, if provided, is the name to use for the value when displaying the usage. If not provided the term "value" is assumed.

The usage message for the option created with

	StringLong("option", 'o', "defval", "a string of letters")

is

	-o, -option=value

while the usage message for the option created with

	StringLong("option", 'o', "defval", "a string of letters", "string")

is

	-o, -option=string

getopt's People

Contributors

bormanp avatar ib-steffen avatar jmahler avatar pborman avatar pgier avatar ryjen avatar tractaylor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

getopt's Issues

Add version to PrintUsage output

I would like to see an option or variable defined to allow for the code version 
to show up in the output, maybe something like:
getopt.Version = "2.5.1"


Original issue reported on code.google.com by [email protected] on 25 Nov 2014 at 5:45

IsSet crashes on unknown option names

Querying (*Set).IsSet() for a flag name not actually defined causes a nil ptr crash instead of returning false.

I'm unable to provide demo code (much less a fix) due to CLA conflicts; hopefully this is enough of a report. I'm working around it for now by using .VisitAlI().

Is this package abandoned?

I notice there has been no activity for a couple of years and that Issues persist for years without a response from the maintainer.

Is this package abandoned?

Go 1.15: error messages changed so test is failing

Go 1.15 rc 1 on Fedora Rawhide:

Testing    in: /builddir/build/BUILD/getopt-ee0cd42419d3adee9239dbd1c375717fe482dac7/_build/src
         PATH: /builddir/build/BUILD/getopt-ee0cd42419d3adee9239dbd1c375717fe482dac7/_build/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
       GOPATH: /builddir/build/BUILD/getopt-ee0cd42419d3adee9239dbd1c375717fe482dac7/_build:/usr/share/gocode
  GO111MODULE: off
      command: go test -buildmode pie -compiler gc -ldflags "-X github.com/pborman/getopt/version.commit=ee0cd42419d3adee9239dbd1c375717fe482dac7 -X github.com/pborman/getopt/version=0 -extldflags '-Wl,-z,relro -Wl,--as-needed  -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '"
      testing: github.com/pborman/getopt
github.com/pborman/getopt
--- FAIL: TestDuration (0.00s)
    duration_test.go:64: duration_test.go:40: got error "test: time: missing unit in duration \"1\"\nUsage: test [-d value] [--duration value] [parameters ...]\n", want "test: time: missing unit in duration 1\n"
    duration_test.go:64: duration_test.go:46: got error "test: time: invalid duration \"foo\"\nUsage: test [-d value] [--duration value] [parameters ...]\n", want "test: time: invalid duration foo\n"
FAIL
exit status 1
FAIL	github.com/pborman/getopt	0.003s

Variables to contorl help formatting do not always work

Setting these variables:

getopt.HelpColumn = 25
getopt.SetParameters("")

Only take effect when you manually bring out the usage with:
getopt.Usage()

They do not seem to have any impact when the Usage is displayed due to an error 
or a missing argument to a parameter  

Original issue reported on code.google.com by [email protected] on 9 Dec 2014 at 3:57

Required parameters

After looking through the documentation, source code, and spending a fair amount of time trying to find anything useful on Google, I'm still unsure how to bring required arguments from the command-line along with optional flags/values.

I'm using os.Args. The flags/values seem to be ignored if they're provided last but obviously used as the initial arguments if provided first. How are we supposed to do this?

Flags don't parse after encountering positional parameter

Based on what I've read in the documentation I would expect the following to work, but I might have misconfigured something. Essentially I would like to support syntax like what git exposes, ala git status --short command.

Here's some sample code:

	connection := ""
	migrations := ""

	getopt.FlagLong(&connection, "connection", 'c', "SQL connection string")
	getopt.FlagLong(&migrations, "migrations", 'm', "Migrations directory")

	getopt.Parse()

	config := MigConfig{
		Connection: connection,
		Migrations: migrations,
	}

	args := getopt.Args()

	fmt.Println("CONFIG")
	fmt.Println(config)
	fmt.Println("ARGS")
	fmt.Println(args)

	return config, nil

Next, I'm invoking the program in two ways:

$ app status --connection="foo"    
CONFIG
{ }
ARGS
[status --connection=foo]

$ app --connection="foo" status
CONFIG
{foo }
ARGS
[status]

The second invocation works as expected, pulling the flag data out and providing the remaining non-flag arguments via .Args(). However the first invocation, in the style of the git command, wasn't able to parse the flags. Have I configured this wrong or is this expected behavior?

Simple README update

While reading over the documentation, I found a simple error. I found a sentence that had "... and and...". I believe the text should say "...a and b..."
In vim, its line 168 in the readme file. And I have attached a sceen shot as well. I will be opening a pull request

screen shot 2018-05-29 at 9 57 16 pm

Also, this is my first time to contribute to this project and I did create a Contributing License Agreement, but not sure what to do with it.

thanks!

Optional long flags do not accept values after space, only with '='

Hi
Using this declaration:

getopt.FlagLong(&calendar, "calendar", 'c', "Filter events of a specified calendar").SetOptional()

If I call the program like this

prog --calendar "test"

it doesn't parse the argument. Only if I use the equal sign:

prog --calendar="test"

While if I remove .SetOptional() it works fine. Is it a forethought feature or a possible bug? The README mentions that it should work this way.

ExtraParameter ErrorCode is never set

It seems that the ErrorCode ExtraParameter "a value was set to a long flag" is never being set.

The related function extraArg is referenced nowhere

func extraArg(o Option, value string) *Error {

Testing setting a value to a long boolean flag returns the error "invalid value for bool" with the Invalid ErrorCode

getopt/bool.go

Line 21 in 6173d3f

return fmt.Errorf("invalid value for bool %s: %q", opt.Name(), value)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.