Categorygithub.com/integrii/flaggy
modulepackage
1.5.2
Repository: https://github.com/integrii/flaggy.git
Documentation: pkg.go.dev

# README


Sensible and fast command-line flag parsing with excellent support for subcommands and positional values. Flags can be at any position. Flaggy has no required project or package layout like Cobra requires, and no external dependencies!

Check out the go doc, examples directory, and examples in this readme to get started quickly. You can also read the Flaggy introduction post with helpful examples on my weblog.

Installation

go get -u github.com/integrii/flaggy

Key Features

  • Very easy to use (see examples below)
  • 35 different flag types supported
  • Any flag can be at any position
  • Pretty and readable help output by default
  • Positional subcommands
  • Positional parameters
  • Suggested subcommands when a subcommand is typo'd
  • Nested subcommands
  • Both global and subcommand specific flags
  • Both global and subcommand specific positional parameters
  • Customizable help templates for both the global command and subcommands
  • Customizable appended/prepended help messages for both the global command and subcommands
  • Simple function that displays help followed by a custom message string
  • Flags and subcommands may have both a short and long name
  • Unlimited trailing arguments after a --
  • Flags can use a single dash or double dash (--flag, -flag, -f, --f)
  • Flags can have = assignment operators, or use a space (--flag=value, --flag value)
  • Flags support single quote globs with spaces (--flag 'this is all one value')
  • Flags of slice types can be passed multiple times (-f one -f two -f three)
  • Optional but default version output with --version
  • Optional but default help output with -h or --help
  • Optional but default help output when any invalid or unknown parameter is passed
  • It's fast. All flag and subcommand parsing takes less than 1ms in most programs.

Example Help Output

testCommand - Description goes here.  Get more information at http://flaggy.
This is a prepend for help

  Usage:
    testCommand [subcommandA|subcommandB|subcommandC] [testPositionalA] [testPositionalB]

  Positional Variables:
    testPositionalA   Test positional A does some things with a positional value. (Required)
    testPositionalB   Test positional B does some less than serious things with a positional value.

  Subcommands:
    subcommandA (a)   Subcommand A is a command that does stuff
    subcommandB (b)   Subcommand B is a command that does other stuff
    subcommandC (c)   Subcommand C is a command that does SERIOUS stuff

  Flags:
       --version        Displays the program version string.
    -h --help           Displays help with available flag, subcommand, and positional value parameters.
    -s --stringFlag     This is a test string flag that does some stringy string stuff.
    -i --intFlg         This is a test int flag that does some interesting int stuff. (default: 5)
    -b --boolFlag       This is a test bool flag that does some booly bool stuff. (default: true)
    -d --durationFlag   This is a test duration flag that does some untimely stuff. (default: 1h23s)

This is an append for help
This is a help add-on message

Super Simple Example

./yourApp -f test

// Declare variables and their defaults
var stringFlag = "defaultValue"

// Add a flag
flaggy.String(&stringFlag, "f", "flag", "A test string flag")

// Parse the flag
flaggy.Parse()

// Use the flag
print(stringFlag)

Example with Subcommand

./yourApp subcommandExample -f test

// Declare variables and their defaults
var stringFlag = "defaultValue"

// Create the subcommand
subcommand := flaggy.NewSubcommand("subcommandExample")

// Add a flag to the subcommand
subcommand.String(&stringFlag, "f", "flag", "A test string flag")

// Add the subcommand to the parser at position 1
flaggy.AttachSubcommand(subcommand, 1)

// Parse the subcommand and all flags
flaggy.Parse()

// Use the flag
print(stringFlag)

Example with Nested Subcommands, Various Flags and Trailing Arguments

./yourApp subcommandExample --flag=5 nestedSubcommand -t test -y -- trailingArg

// Declare variables and their defaults
var stringFlagF = "defaultValueF"
var intFlagT = 3
var boolFlagB bool

// Create the subcommands
subcommandExample := flaggy.NewSubcommand("subcommandExample")
nestedSubcommand := flaggy.NewSubcommand("nestedSubcommand")

// Add a flag to both subcommands
subcommandExample.String(&stringFlagF, "t", "testFlag", "A test string flag")
nestedSubcommand.Int(&intFlagT, "f", "flag", "A test int flag")

// add a global bool flag for fun
flaggy.Bool(&boolFlagB, "y", "yes", "A sample boolean flag")

// attach the nested subcommand to the parent subcommand at position 1
subcommandExample.AttachSubcommand(nestedSubcommand, 1)
// attach the base subcommand to the parser at position 1
flaggy.AttachSubcommand(subcommandExample, 1)

// Parse everything, then use the flags and trailing arguments
flaggy.Parse()
print(stringFlagF)
print(intFlagT)
print(boolFlagB)
print(flaggy.TrailingArguments[0])

Supported Flag Types

Flaggy has specific flag types for all basic types included in go as well as a slice of any of those types. This includes all of the following types:

  • string and []string
  • bool and []bool
  • all int types and all []int types
  • all float types and all []float types
  • all uint types and all []uint types

Other more specific types can also be used as flag types. They will be automatically parsed using the standard parsing functions included with those types in those packages. This includes:

  • net.IP
  • []net.IP
  • net.HardwareAddr
  • []net.HardwareAddr
  • net.IPMask
  • []net.IPMask
  • time.Duration
  • []time.Duration

An Example Program

Best practice when using flaggy includes setting your program's name, description, and version (at build time) as shown in this example program.

package main

import "github.com/integrii/flaggy"

// Make a variable for the version which will be set at build time.
var version = "unknown"

// Keep subcommands as globals so you can easily check if they were used later on.
var mySubcommand *flaggy.Subcommand

// Setup the variables you want your incoming flags to set.
var testVar string

// If you would like an environment variable as the default for a value, just populate the flag
// with the value of the environment by default.  If the flag corresponding to this value is not
// used, then it will not be changed.
var myVar = os.Getenv("MY_VAR")


func init() {
  // Set your program's name and description.  These appear in help output.
  flaggy.SetName("Test Program")
  flaggy.SetDescription("A little example program")

  // You can disable various things by changing bools on the default parser
  // (or your own parser if you have created one).
  flaggy.DefaultParser.ShowHelpOnUnexpected = false

  // You can set a help prepend or append on the default parser.
  flaggy.DefaultParser.AdditionalHelpPrepend = "http://github.com/integrii/flaggy"
  
  // Add a flag to the main program (this will be available in all subcommands as well).
  flaggy.String(&testVar, "tv", "testVariable", "A variable just for testing things!")

  // Create any subcommands and set their parameters.
  mySubcommand = flaggy.NewSubcommand("mySubcommand")
  mySubcommand.Description = "My great subcommand!"
  
  // Add a flag to the subcommand.
  mySubcommand.String(&myVar, "mv", "myVariable", "A variable just for me!")

  // Set the version and parse all inputs into variables.
  flaggy.SetVersion(version)
  flaggy.Parse()
}

func main(){
    if mySubcommand.Used {
      ...
    }
}

Then, you can use the following build command to set the version variable in the above program at build time.

# build your app and set the version string
$ go build -ldflags='-X main.version=1.0.3-a3db3'
$ ./yourApp version
Version: 1.0.3-a3db3
$ ./yourApp --help
Test Program - A little example program
http://github.com/integrii/flaggy

Contributions

Please feel free to open an issue if you find any bugs or see any features that make sense. Pull requests will be reviewed and accepted if they make sense, but it is always wise to submit a proposal issue before any major changes.

# Packages

# Functions

AddPositionalValue adds a positional value to the main parser at the global context.
AttachSubcommand adds a subcommand for parsing.
Bool adds a new bool flag.
BoolSlice adds a new slice of bools flag Specify the flag multiple times to fill the slice.
ByteSlice adds a new slice of bytes flag Specify the flag multiple times to fill the slice.
Duration adds a new time.Duration flag.
DurationSlice adds a new time.Duration flag.
Float32 adds a new float32 flag.
Float32Slice adds a new float32 flag.
Float64 adds a new float64 flag.
Float64Slice adds a new float64 flag.
HardwareAddr adds a new net.HardwareAddr flag.
HardwareAddrSlice adds a new net.HardwareAddr slice flag.
Int adds a new int flag.
Int16 adds a new int16 flag.
Int16Slice adds a new int16 slice flag.
Int32 adds a new int32 flag.
Int32Slice adds a new int32 slice flag.
Int64 adds a new int64 flag.
Int64Slice adds a new int64 slice flag.
Int8 adds a new int8 flag.
Int8Slice adds a new int8 slice flag.
IntSlice adds a new int slice flag.
IP adds a new net.IP flag.
IPMask adds a new net.IPMask flag.
IPMaskSlice adds a new net.HardwareAddr slice flag.
IPSlice adds a new int8 slice flag.
NewParser creates a new ArgumentParser ready to parse inputs.
NewSubcommand creates a new subcommand that can have flags or PositionalFlags added to it.
Parse parses flags as requested in the default package parser.
ParseArgs parses the passed args as if they were the arguments to the running binary.
ResetParser resets the default parser to a fresh instance.
SetDescription sets the description of the default package command parser.
SetName sets the name of the default package command parser.
SetVersion sets the version of the default package command parser.
ShowHelp shows parser help.
ShowHelpAndExit shows parser help and exits with status code 2.
ShowHelpOnUnexpectedDisable disables the ShowHelpOnUnexpected behavior on the default parser.
ShowHelpOnUnexpectedEnable enables the ShowHelpOnUnexpected behavior on the default parser.
String adds a new string flag.
StringSlice adds a new slice of strings flag Specify the flag multiple times to fill the slice.
UInt adds a new uint flag.
UInt16 adds a new uint16 flag.
UInt16Slice adds a new uint16 slice flag.
UInt32 adds a new uint32 flag.
UInt32Slice adds a new uint32 slice flag.
UInt64 adds a new uint64 flag.
UInt64Slice adds a new uint64 slice flag.
UInt8 adds a new uint8 flag.
UInt8Slice adds a new uint8 slice flag.
UIntSlice adds a new uint slice flag.

# Variables

DebugMode indicates that debug output should be enabled.
DefaultHelpTemplate is the help template that will be used for newly created subcommands and commands.
DefaultParser is the default parser that is used with the package-level public functions.
PanicInsteadOfExit is used when running tests.
TrailingArguments holds trailing arguments in the main parser after parsing has been run.

# Structs

Flag holds the base methods for all flag types.
Help represents the values needed to render a Help page.
HelpFlag is used to template string flag Help output.
HelpPositional is used to template positional Help output.
HelpSubcommand is used to template subcommand Help output.
Parser represents the set of flags and subcommands we are expecting from our input arguments.
PositionalValue represents a value which is determined by its position relative to where a subcommand was detected.
Subcommand represents a subcommand which contains a set of child subcommands along with a set of flags relevant to it.

# Interfaces

ArgumentParser represents a parser or subcommand.