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

Related tags

Command Line pflag
Overview

Build Status Go Report Card GoDoc

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 the POSIX recommendations for command-line options. For a more precise description, see the "Command-line flag syntax" section below.

pflag is available under the same style of BSD license as the Go language, which can be found in the LICENSE file.

Installation

pflag is available using the standard go get command.

Install by running:

go get github.com/spf13/pflag

Run tests by running:

go test github.com/spf13/pflag

Usage

pflag is a drop-in replacement of Go's native flag package. If you import pflag under the name "flag" then all code should continue to function with no changes.

import flag "github.com/spf13/pflag"

There is one exception to this: if you directly instantiate the Flag struct there is one more field "Shorthand" that you will need to set. Most code never instantiates this struct directly, and instead uses functions such as String(), BoolVar(), and Var(), and is therefore unaffected.

Define flags using flag.String(), Bool(), Int(), etc.

This declares an integer flag, -flagname, stored in the pointer ip, with type *int.

var ip *int = flag.Int("flagname", 1234, "help message for flagname")

If you like, you can bind the flag to a variable using the Var() functions.

var flagvar int
func init() {
    flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
}

Or you can create custom flags that satisfy the Value interface (with pointer receivers) and couple them to flag parsing by

flag.Var(&flagVal, "name", "help message for flagname")

For such flags, the default value is just the initial value of the variable.

After all flags are defined, call

flag.Parse()

to parse the command line into the defined flags.

Flags may then be used directly. If you're using the flags themselves, they are all pointers; if you bind to variables, they're values.

fmt.Println("ip has value ", *ip)
fmt.Println("flagvar has value ", flagvar)

There are helper functions available to get the value stored in a Flag if you have a FlagSet but find it difficult to keep up with all of the pointers in your code. If you have a pflag.FlagSet with a flag called 'flagname' of type int you can use GetInt() to get the int value. But notice that 'flagname' must exist and it must be an int. GetString("flagname") will fail.

i, err := flagset.GetInt("flagname")

After parsing, the arguments after the flag are available as the slice flag.Args() or individually as flag.Arg(i). The arguments are indexed from 0 through flag.NArg()-1.

The pflag package also defines some new functions that are not in flag, that give one-letter shorthands for flags. You can use these by appending 'P' to the name of any function that defines a flag.

var ip = flag.IntP("flagname", "f", 1234, "help message")
var flagvar bool
func init() {
	flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
}
flag.VarP(&flagVal, "varname", "v", "help message")

Shorthand letters can be used with single dashes on the command line. Boolean shorthand flags can be combined with other shorthand flags.

The default set of command-line flags is controlled by top-level functions. The FlagSet type allows one to define independent sets of flags, such as to implement subcommands in a command-line interface. The methods of FlagSet are analogous to the top-level functions for the command-line flag set.

Setting no option default values for flags

After you create a flag it is possible to set the pflag.NoOptDefVal for the given flag. Doing this changes the meaning of the flag slightly. If a flag has a NoOptDefVal and the flag is set on the command line without an option the flag will be set to the NoOptDefVal. For example given:

var ip = flag.IntP("flagname", "f", 1234, "help message")
flag.Lookup("flagname").NoOptDefVal = "4321"

Would result in something like

Parsed Arguments Resulting Value
--flagname=1357 ip=1357
--flagname ip=4321
[nothing] ip=1234

Command line flag syntax

--flag    // boolean flags, or flags with no option default values
--flag x  // only on flags without a default value
--flag=x

Unlike the flag package, a single dash before an option means something different than a double dash. Single dashes signify a series of shorthand letters for flags. All but the last shorthand letter must be boolean flags or a flag with a default value

// boolean or flags where the 'no option default value' is set
-f
-f=true
-abc
but
-b true is INVALID

// non-boolean and flags without a 'no option default value'
-n 1234
-n=1234
-n1234

// mixed
-abcs "hello"
-absd="hello"
-abcs1234

Flag parsing stops after the terminator "--". Unlike the flag package, flags can be interspersed with arguments anywhere on the command line before this terminator.

Integer flags accept 1234, 0664, 0x1234 and may be negative. Boolean flags (in their long form) accept 1, 0, t, f, true, false, TRUE, FALSE, True, False. Duration flags accept any input valid for time.ParseDuration.

Mutating or "Normalizing" Flag names

It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.

Example #1: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag

func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
	from := []string{"-", "_"}
	to := "."
	for _, sep := range from {
		name = strings.Replace(name, sep, to, -1)
	}
	return pflag.NormalizedName(name)
}

myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)

Example #2: You want to alias two flags. aka --old-flag-name == --new-flag-name

func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {
	switch name {
	case "old-flag-name":
		name = "new-flag-name"
		break
	}
	return pflag.NormalizedName(name)
}

myFlagSet.SetNormalizeFunc(aliasNormalizeFunc)

Deprecating a flag or its shorthand

It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.

Example #1: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead.

// deprecate a flag by specifying its name and a usage message
flags.MarkDeprecated("badflag", "please use --good-flag instead")

This hides "badflag" from help text, and prints Flag --badflag has been deprecated, please use --good-flag instead when "badflag" is used.

Example #2: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n".

// deprecate a flag shorthand by specifying its flag name and a usage message
flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only")

This hides the shortname "n" from help text, and prints Flag shorthand -n has been deprecated, please use --noshorthandflag only when the shorthand "n" is used.

Note that usage message is essential here, and it should not be empty.

Hidden flags

It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.

Example: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.

// hide a flag by specifying its name
flags.MarkHidden("secretFlag")

Disable sorting of flags

pflag allows you to disable sorting of flags for help and usage message.

Example:

flags.BoolP("verbose", "v", false, "verbose output")
flags.String("coolflag", "yeaah", "it's really cool flag")
flags.Int("usefulflag", 777, "sometimes it's very useful")
flags.SortFlags = false
flags.PrintDefaults()

Output:

  -v, --verbose           verbose output
      --coolflag string   it's really cool flag (default "yeaah")
      --usefulflag int    sometimes it's very useful (default 777)

Supporting Go flags when using pflag

In order to support flags defined using Go's flag package, they must be added to the pflag flagset. This is usually necessary to support flags defined by third-party dependencies (e.g. golang/glog).

Example: You want to add the Go flags to the CommandLine flagset

import (
	goflag "flag"
	flag "github.com/spf13/pflag"
)

var ip *int = flag.Int("flagname", 1234, "help message for flagname")

func main() {
	flag.CommandLine.AddGoFlagSet(goflag.CommandLine)
	flag.Parse()
}

More info

You can see the full reference documentation of the pflag package at godoc.org, or through go's standard documentation system by running godoc -http=:6060 and browsing to http://localhost:6060/pkg/github.com/spf13/pflag after installation.

Issues
  • add ability to ignore unknown flags

    add ability to ignore unknown flags

    It will be nice if we can add ability to ignore unknown flags. This can be useful when writing wrappers on other commands where exposing all downstream flags is un-necessary.

    opened by rajatjindal 33
  • Allows any flag to expect optional arguments

    Allows any flag to expect optional arguments

    The motivation for this change is to allow any flag or flag type (not only boolean) to support optional arguments as long as they are declared to do so. Example:

    git diff --stat[=<width>]
    

    The logic around flags with empty arguments (e.g. --debug) were detached from the boolean type and moved to a separate attribute called Optional. This allows to mark any flag type as supporting optional arguments.

    The difference in comparison to not providing the flag at all is that the Changed attribute is set, so it allows to control the difference of not providing the flag or providing but without an argument.

    A possible use case would be:

    flag.IntVar(&flagvar, "list", 10, "list the number of items")
    flag.MarkOptional("list")
    

    So when using the flag users could either provide the number of items to display in the list, or not provide any argument to use the default int value:

    deploy           // perform a deployment
    deploy --list    // will list 10 deployments (default value)
    deploy --list=20 // will list 20 deployments
    

    The behavior for default types were not changed (the only flags that allow empty arguments by default are boolean).

    opened by fabianofranz 28
  • allow lookup by shorthand

    allow lookup by shorthand

    @eparis I take your advice at https://github.com/kubernetes/kubernetes/pull/35030, I found that it's simple to parse long flag using flags.Lookup() , but there is no method for short flag. I can't get flag.NoOptDefVal to make a distinction between "--flag" and "--flag arg". Would we add a new function for short flag?

    opened by xilabao 22
  • Question about optional params

    Question about optional params

    Hi, I need to implement an optional param in my programs and I am wondering if there is a way to do it using this library. The use case is to mimic MySQL behavior for -p -p can be used as -p<password here> or just -p and in that case, the param is marked as set but empty and MySQL client will ask for a password. This way, you can avoid using a password in the command line.

    Regards

    question 
    opened by percona-csalguero 20
  • Add support for specifying only a shortflag

    Add support for specifying only a shortflag

    This PR seeks to add support for specifying flags with only a short flag. Tests have been adjusted and added, but suggestions for any additional validation are welcome.

    Fixes #139 Closes #165 Fixes spf13/cobra#679

    opened by cornfeedhobo 19
  • Update flag.go, add secret option

    Update flag.go, add secret option

    I think we could add a new option for flag to make a distinction between secret flag and normal flag, let people can hide the value of flag by "******". just like --username=****** --password=******

    opened by xilabao 13
  • Grouping flags?

    Grouping flags?

    Hi,

    is it possible to group flags so that they appear together in the --help text? I'm using pflag in my backup program, there I have for example the options to expire backups according to a policy. Before (with the go-flags) library the options were nicely grouped together (in the order they were defined):

    $ restic forget --help
    Usage:
      restic [OPTIONS] forget [snapshot ID] ...
    [...]
    [forget command options]
          -l, --keep-last=    keep the last n snapshots
          -H, --keep-hourly=  keep the last n hourly snapshots
          -d, --keep-daily=   keep the last n daily snapshots
          -w, --keep-weekly=  keep the last n weekly snapshots
          -m, --keep-monthly= keep the last n monthly snapshots
          -y, --keep-yearly=  keep the last n yearly snapshots
              --keep-tag=     alwaps keep snapshots with this tag (can be specified multiple times)
              --hostname=     only forget snapshots for the given hostname
              --tag=          only forget snapshots with the tag (can be specified multiple times)
          -n, --dry-run       do not delete anything, just print what would be done
    

    Now with pflag and cobra they are printed in alphabetical order:

    [...]
    Usage:
      restic forget [flags] [snapshot ID] [...]
    
    Flags:
      -n, --dry-run                do not delete anything, just print what would be done
          --hostname string        only forget snapshots for the given hostname
      -d, --keep-daily int         keep the last n daily snapshots
      -H, --keep-hourly int        keep the last n hourly snapshots
      -l, --keep-last int          keep the last n snapshots
      -m, --keep-monthly int       keep the last n monthly snapshots
          --keep-tag stringSlice   always keep snapshots with this tag (can be specified multiple times)
      -w, --keep-weekly int        keep the last n weekly snapshots
      -y, --keep-yearly int        keep the last n yearly snapshots
          --tag stringSlice        only forget snapshots with the tag (can be specified multiple times)
    [...]
    

    Is there a way to group some flags so that they are printed together?

    opened by fd0 13
  • Issue #55: implement Go 1.5-style default usage formatting.

    Issue #55: implement Go 1.5-style default usage formatting.

    Compare to 1.4, the main difference in formatting is the placement of default values. Moreover, UnquoteUsage() is now added (and exported, for full API compatibility with the standard flag package), so backtick words in usage messages can be used to set the placeholder name.

    Compared to the standard flag package, this patch always prints usage in one-line, with automatic alignment, because I feel that the 1.4 output is very confusing when modified to include also dash-dash flags.

    opened by rasky 13
  • v1.0.4 Has a Broken Path

    v1.0.4 Has a Broken Path

    edit: updated how to recreate

    go get -u github.com/golangci/golangci-lint/cmd/golangci-lint will fail when hitting this dep

    go get: github.com/spf13/[email protected] updating to
            github.com/spf13/[email protected]: parsing go.mod:
            module declares its path as: github.com/spf13/pflags
                    but was required as: github.com/spf13/pflag
    
    opened by jmuldoon 10
  • fix mixed named and positional argument parsing

    fix mixed named and positional argument parsing

    • Prefer a given argument over the default value
    • Look ahead to detect given arguments that are not specified with the connectint = to the argument name

    Fixes #32.

    opened by steveeJ 10
  • Fix handling of -- termination

    Fix handling of -- termination

    Fix handling of -- termination. Previously, if you ran

    $command -flag1 -etc -- some args after
    

    the command's args would be doubled (some args after some args after). Additionally, if there were items after the -- termination that looked like flags, the parser would throw an error. It's better to terminate parsing when -- is seen, because that usually indicates the caller wants to pass the remainder of the arguments (including flags) as-is to something else.

    opened by ncdc 10
  • FlagSet Slice

    FlagSet Slice

    Hi,

    I think it would be useful if pflag could allow defining slice of FlagSets so we can do the following:

    markdown render \
      --line --column="Go" --column="golang" --left-aligned \
      --line --column="Rust" --column="rust-lang" \
      --line --column="C"
    
    opened by sylr 0
  • Add support for time.Time flags

    Add support for time.Time flags

    This PR implements support for time.Time flags which can be used to accept timestamps as input directly (see https://github.com/spf13/cobra/issues/742).

    The implementation allows defining a list of acceptable timestamp formats which are tested in order, i.e., devs using this flag type would be responsible for ordering their formats correctly should there be an overlap.

    opened by max-frank 2
  • Prevent help output from escaping default values as go strings

    Prevent help output from escaping default values as go strings

    When creating the help text for a flag, the default value shouldn't be be excaped. It isn't clear to an end user that we would be escaping those values.

    Instead we should be printing the actual value and letting the users decide when/how to add escaping based on how they're utilzing it.

    Fixes #346

    Signed-off-by: John Schnake [email protected]

    opened by johnSchnake 0
  • Default strings in help shouldn't be Go escaped

    Default strings in help shouldn't be Go escaped

    From https://github.com/spf13/cobra/issues/1396:

    Just spent another minute looking at this and that I think it is caused from the pflag library here https://github.com/spf13/pflag/blob/85dd5c8bc61cfa382fecd072378089d4e856579d/flag.go#L733

    The %q is what causes it to be a go-escaped string rather than just using "%v"; go fmt package states that %q for strings as:

    %q	a double-quoted string safely escaped with Go syntax
    

    So I think we need to put a PR up for that. I'll create an issue there to track it.

    Originally posted by @johnSchnake in https://github.com/spf13/cobra/issues/1396#issuecomment-1068755417

    opened by johnSchnake 2
Releases(v1.0.5)
Owner
Steve Francia
@golang product lead at @google • Author, Speaker, Developer • Creator of @gohugoio, Cobra, Viper & spf13-vim • former @docker & @mongodb
Steve Francia
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

hz 105 May 7, 2022
Dependency-free replacement for GNU parallel, perfect fit for usage in an initramfs.

coshell v0.2.5 A no-frills dependency-free replacement for GNU parallel, perfect for initramfs usage. Licensed under GNU/GPL v2. How it works An sh -c

gdm85 41 May 11, 2022
The standard library flag package with its missing features

cmd Package cmd is a minimalistic library that enables easy sub commands with the standard flag library. This library extends the standard library fla

Eyal Posener 33 Sep 23, 2021
A collection of CLI argument types for the Go `flag` package.

flagvar A collection of CLI argument types for the flag package. import "github.com/sgreben/flagvar" Or just copy & paste what you need. It's public d

Sergey Grebenshchikov 38 Apr 19, 2022
Argparse for golang. Just because `flag` sucks

Golang argparse Let's be honest -- Go's standard command line arguments parser flag terribly sucks. It cannot come anywhere close to the Python's argp

Alexey Kamenskiy 422 May 16, 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

null 120 Apr 1, 2022
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

Alec Thomas 3.2k May 11, 2022
Go binding configuration and command flag made easy✨✨

✨ Binding configuration and command flag made easy! ✨ You can use multiple keys tag to simplify the look like this (supported feature**): // single ta

Ii64人 13 Mar 2, 2022
Idiomatic Go input parsing with subcommands, positional values, and flags at any position. No required project or package layout and no external dependencies.

Sensible and fast command-line flag parsing with excellent support for subcommands and positional values. Flags can be at any position. Flaggy has no

Eric Greer 792 May 11, 2022
A golang library for building interactive prompts with full support for windows and posix terminals.

Survey A library for building interactive prompts on terminals supporting ANSI escape sequences. package main import ( "fmt" "github.com/Alec

Alec Aivazis 3.1k May 16, 2022
A simple posix shell created in golang

Fox-Shell Description Fox-Shell is a simple posix shell builded with golang Features - chdir works perfectly - mkdir works, but need bug fix To-Do Li

null 2 Dec 13, 2021
Readline is a pure go(golang) implementation for GNU-Readline kind library

A powerful readline library in Linux macOS Windows Solaris Guide Demo Shortcut Repos using readline Feedback If you have any questions, please submit

chzyer 1.8k May 20, 2022
GNU coreutils remade in Go for RosetteOS

Rosebush GNU and POSIX coreutils remade in Go for RosetteOS Build To compile the Rosebush, simply make -B This will compile all the utils one by one.

RosetteOS Linux 5 Oct 4, 2021
GDScript Syntax Highlighting in GNU Nano

nano-gdscript GDScript Syntax Highlighting in GNU Nano. Updated regularly every minor updates. Contributions are welcomed Installation This is 100% fr

null 0 Jun 25, 2021
A Go implementation of gnu-coreutils programs

Go-Coreutils A Go implementation of gnu-coreutils programs (https://www.gnu.org/software/coreutils/manual/coreutils.html) Build and Run In the root di

Will Cygan 0 Jan 15, 2022
A lightweight replacement for the standard fmt package, reduces binary size by roughly 400kb in a hello world

console This is a lightweight replacement for the fmt package, reduces the binary size by roughly 400kb in a hello world program. Please note: This pa

null 1 Nov 7, 2021
Automatically sets up command line flags based on struct fields and tags.

Commandeer Commandeer sets up command line flags based on struct fields and tags. Do you... like to develop Go apps as libraries with tiny main packag

Matthew Jaffee 156 Apr 8, 2022
Generate flags by parsing structures

Flags based on structures. The sflags package uses structs, reflection and struct field tags to allow you specify command line options. It supports di

null 134 Apr 13, 2022
A rich tool for parsing flags and values in pure Golang

A rich tool for parsing flags and values in pure Golang. No additional library is required and you can use everywhere.

ALi.w 14 Jan 25, 2022