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 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.

Owner
Eric Greer
When your biggest problems aren't big problems, you start fixing things that don't need fixing.
Eric Greer
Comments
  • How do you display default values in help text?

    How do you display default values in help text?

    Summary

    I'm very new to Go and am getting used to syntax and the overall mindset of using it, so it's likely that I'm missing something. As I was looking over the feature list and examples one of the features that really drew my eye was how default values for options appeared to be automatically displayed in help output.

    So far I can't figure out how to display default values for configured flags.

    I also can't seem to figure out how to display help output for invalid/unconfigured flags, but it's probably something else I'm doing wrong.

    Desired Results

    From the README:

      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.
    

    Is this support available? If so, how do I go about using it?

    Example program

    Here is a brief example program:

    package main
    
    import (
    	"fmt"
    
    	"github.com/integrii/flaggy"
    )
    
    func main() {
    
    	optKeepOldest := false
    	optRemove := false
    
    	flaggy.SetName("Test")
    	flaggy.SetDescription("Short example to illustrate issue")
    
            // attempt to show Help output when invalid flags/options are used
           // (does not seem to work?)
    	flaggy.DefaultParser.ShowHelpOnUnexpected = true
    
    	// Add flags
    	flaggy.Bool(&optKeepOldest, "ko", "keep-old", "Keep oldest files instead of newer")
    	flaggy.Bool(&optRemove, "rm", "remove", "Remove matched files")
    
    	flaggy.Parse()
    
    	fmt.Printf("%v\n", optKeepOldest)
    	fmt.Printf("%v\n", optRemove)
    
    }
    

    Package version used

    Contents of my go.mod file:

    module testing
    
    go 1.12
    
    require github.com/integrii/flaggy v1.2.1-0.20190517180110-07ea7eb77404 // indirect
    

    Environment

    • Windows 10
    • go1.12.9 windows/amd64
  • How do you use the ShowHelpOnUnexpected option for DefaultParser?

    How do you use the ShowHelpOnUnexpected option for DefaultParser?

    I tried using the option as shown here:

    https://github.com/integrii/flaggy/blob/master/README.md#recommended-program-structure

    and with tag 1.2.2 (425304205580254c6ea87908f35848c46eb99d5e) I do see the help output when I use an invalid flag, but only if I don't specify a value for the flag when I specify the flag.

    Example program:

    package main
    
    import (
    	"fmt"
    
    	"github.com/integrii/flaggy"
    )
    
    func main() {
    
    	optBool := false
    	optIntegerTestVar := 1
    	optStringTestVar := "My test string"
    
    	flaggy.SetName("Test")
    	flaggy.SetDescription("Short example to illustrate issue")
    
    	flaggy.DefaultParser.ShowHelpOnUnexpected = true
    
    	// Add flags
    	flaggy.Bool(&optBool, "bo", "bool", "Boolean test option")
    	flaggy.Int(&optIntegerTestVar, "int", "inttest", "Integer test option")
    	flaggy.String(&optStringTestVar, "str", "stringtest", "String test option")
    
    	// Parse the flag
    	flaggy.Parse()
    
    	fmt.Printf("%v\n", optBool)
    	fmt.Printf("%v\n", optIntegerTestVar)
    	fmt.Printf("%v\n", optStringTestVar)
    
    }
    

    Example usage:

    $ go run main.go -warning
    Test - Short example to illustrate issue
    
      Flags:
           --version  Displays the program version string.
        -h --help  Displays help with available flag, subcommand, and positional value parameters.
        -bo --bool  Boolean test option
        -int --inttest  Integer test option (default: 1)
        -str --stringtest  String test option (default: My test string)
    
    Expected a following arg for flag warning, but it did not exist.
    exit status 2
    
    $ go run main.go -warning=no
    false
    1
    My test string
    
    $ go run main.go --warning=no
    false
    1
    My test string
    
  • Aligns flag description

    Aligns flag description

    Before:

    example - Example application.
    
      Usage:
        example [ornare|lacinia-arcu|nostra-dapibus|ut|fames-nisi|sollicitudin|vestibulum] [facilisi] [platea-torquent-facilisi] [elementum]
    
      Positional Variables:
        facilisi (Required) - Sociosqu platea torquent facilisi dictumst facilisis molestie rutrum. (default: defaultValue)
        platea-torquent-facilisi - Neque lacinia eu placerat tristique, habitasse dui habitant pharetra convallis senectus luctus ac cum in velit.
        elementum (Required) - Elementum consequat suscipit.
    
      Subcommands:
        ornare - Curae ornare etiam ligula quis mauris aptent, fringilla consequat aenean habitasse.
        lacinia-arcu - Lacinia arcu ornare rhoncus, tellus et.
        nostra-dapibus - Aenean cubilia nostra dapibus facilisi, eget porta bibendum.
        ut - Ut penatibus velit gravida curabitur, nascetur suspendisse.
        fames-nisi - Fames nisi egestas euismod donec tristique, justo imperdiet ultrices aptent.
        sollicitudin - Sollicitudin primis tristique mus curae, venenatis nascetur aptent.
        vestibulum - Vestibulum torquent porttitor himenaeos etiam imperdiet, elementum consequat suscipit pulvinar.
    
      Flags:
           --version  Displays the program version string.
        -h --help  Displays help with available flag, subcommand, and positional value parameters.
           --scelerisque  Scelerisque molestie accumsan potenti dignissim ligula velit rhoncus vitae tincidunt senectus, proin aenean inceptos orci condimentum per eleifend habitant.
           --sapien  Cubilia facilisis molestie nulla sapien aliquet, pulvinar porta iaculis felis.
           --fringilla  Odio proin cum ac consequat, laoreet fringilla.
           --risus-magnis-morbi  Risus magnis morbi aliquet vulputate vel bibendum, tincidunt duis class imperdiet.
           --himenaeos-hac-parturient-primis  Himenaeos hac parturient primis dui lobortis phasellus mauris facilisi nam consequat condimentum, litora luctus nostra mattis ante convallis suspendisse molestie.
           --nunc  Nunc sociosqu pharetra.
           --pretium-magna-ante-justo  Pretium magna ante justo turpis, tempus aliquet libero, volutpat vulputate curabitur.
           --aptent-aliquet  Aptent aliquet proin vivamus donec, lacinia facilisis rhoncus.
        -n --nisl-augue  Nisl augue vitae libero, facilisis fames rhoncus eu, ligula sagittis.
           --vivamus  Mi dignissim vivamus libero posuere, tincidunt suspendisse dis.
           --class-praesent-sapien-velit-hendrerit-purus  Class praesent sapien velit hendrerit purus mattis varius, orci fringilla ultricies donec vitae aenean. Vitae ut bibendum varius justo tristique commodo aliquam non class sodale.
           --hendrerit  Hendrerit egestas.
           --vestibulum-torquent  Vestibulum torquent porttitor himenaeos etiam imperdiet, elementum consequat suscipit pulvinar.
        -s --suscipit  Nisl fringilla suscipit libero cum sodales, nibh odio dictum.
    

    After:

    example - Example application.
    
      Usage:
        example [ornare|lacinia-arcu|nostra-dapibus|ut|fames-nisi|sollicitudin|vestibulum] [facilisi] [platea-torquent-facilisi] [elementum]
    
      Positional Variables:
        facilisi                   Sociosqu platea torquent facilisi dictumst facilisis molestie rutrum. (default: defaultValue)
        platea-torquent-facilisi   Neque lacinia eu placerat tristique, habitasse dui habitant pharetra convallis senectus luctus ac cum in velit.
        elementum                  Elementum consequat suscipit. (Required)
    
      Subcommands:
        ornare           Curae ornare etiam ligula quis mauris aptent, fringilla consequat aenean habitasse.
        lacinia-arcu     Lacinia arcu ornare rhoncus, tellus et.
        nostra-dapibus   Aenean cubilia nostra dapibus facilisi, eget porta bibendum.
        ut               Ut penatibus velit gravida curabitur, nascetur suspendisse.
        fames-nisi       Fames nisi egestas euismod donec tristique, justo imperdiet ultrices aptent.
        sollicitudin     Sollicitudin primis tristique mus curae, venenatis nascetur aptent.
        vestibulum       Vestibulum torquent porttitor himenaeos etiam imperdiet, elementum consequat suscipit pulvinar.
    
      Flags:
           --version                                       Displays the program version string.
        -h --help                                          Displays help with available flag, subcommand, and positional value parameters.
           --scelerisque                                   Scelerisque molestie accumsan potenti dignissim ligula velit rhoncus vitae tincidunt senectus, proin aenean inceptos orci condimentum per eleifend habitant.
           --sapien                                        Cubilia facilisis molestie nulla sapien aliquet, pulvinar porta iaculis felis.
           --fringilla                                     Odio proin cum ac consequat, laoreet fringilla.
           --risus-magnis-morbi                            Risus magnis morbi aliquet vulputate vel bibendum, tincidunt duis class imperdiet.
           --himenaeos-hac-parturient-primis               Himenaeos hac parturient primis dui lobortis phasellus mauris facilisi nam consequat condimentum, litora luctus nostra mattis ante convallis suspendisse molestie.
           --nunc                                          Nunc sociosqu pharetra.
           --pretium-magna-ante-justo                      Pretium magna ante justo turpis, tempus aliquet libero, volutpat vulputate curabitur.
           --aptent-aliquet                                Aptent aliquet proin vivamus donec, lacinia facilisis rhoncus.
        -n --nisl-augue                                    Nisl augue vitae libero, facilisis fames rhoncus eu, ligula sagittis.
           --vivamus                                       Mi dignissim vivamus libero posuere, tincidunt suspendisse dis.
           --class-praesent-sapien-velit-hendrerit-purus   Class praesent sapien velit hendrerit purus mattis varius, orci fringilla ultricies donec vitae aenean. Vitae ut bibendum varius justo tristique commodo aliquam non class sodale.
           --hendrerit                                     Hendrerit egestas.
           --vestibulum-torquent                           Vestibulum torquent porttitor himenaeos etiam imperdiet, elementum consequat suscipit pulvinar.
        -s --suscipit                                      Nisl fringilla suscipit libero cum sodales, nibh odio dictum.
    
  • Displays current value as

    Displays current value as "Default" on Subcommand Positional Value when Extra

    When using positional values, if I accidentally add an extra argument the "default" is shown as whatever I entered already for the existing positional arguments.

    You can see from the following example program the "id" field shows the executed "bad" value as the default.

    package main
    
    import "github.com/integrii/flaggy"
    
    func main() {
    	var id string
    
    	getCmd := flaggy.NewSubcommand("get")
    	getCmd.Description = "Get from id"
    	getCmd.AddPositionalValue(&id, "id", 1, true, "ID")
    	flaggy.AttachSubcommand(getCmd, 1)
    
    	flaggy.Parse()
    }
    
    $ ./main get bad extra
    get - Get from id
    
      Usage:
        get [id]
    
      Positional Variables:
        id (Required) - ID (default: bad)
      Flags:
           --version  Displays the program version string.
        -h --help  Displays help with available flag, subcommand, and positional value parameters.
    
    Unexpected argument: extra
    
  • Incorrect parsing of bool flags on subcommands

    Incorrect parsing of bool flags on subcommands

    Bool flaggs specified on the parser are handled differently than those set on the subcommand. I couldn't find any documentation on why this should be the case, so I'm assuming there is a bug.

    On the parser, you're able to pass a flag like -f, and the variable passed into flagg.Bool() will be set as true. However, if you define -f on a subcommand, passing -f to the program errors with: Expected a following arg for flag f, but it did not exist.

    I've created a minimal example: https://play.golang.org/p/ScB7PMv9rZ5

    I tried tracking this down. I discovered that the subcommand passed to the flagIsBool function does not contain the bool flag defined on the subcommand.

  • Proposal: Adding support for environment vars

    Proposal: Adding support for environment vars

    I'm planning to integrate flaggy into an existing project, replacing the currently used urfave/cli package. This existing program also provides the option to pass in options via environment variables. The env part now could be solved on its own. But I was thinking if it wasn't a cool feature for flaggy itself?

    It could look something like this:

    flaggy.DefaultParser.EnableEnvFlags()
    flaggy.String(&stringFlag, "f", "flag", "A test string flag")
    

    If --flag was not passed to the program, we would use the env var FLAG if it is set.

    or

    flaggy.DefaultParser.EnableEnvFlagsWithPrefix("MYAPP")
    flaggy.String(&stringFlag, "f", "flag", "A test string flag")
    

    With a prefix we would look for MYAPP_FLAG.

    Precedence should be clear:

    1. The passed --flag
    2. ENV var FLAG
    3. Default value of the flag

    Lowercase flags would always relate to UPPERCASE env vars. Hyphens would be replaced with underscores. CamelCase will be split into separate words. So --someFlag would relate to SOME_FLAG.

    By default the feature should be disabled, as I can see it could cause problems in some situations, where flags are named like common bash vars, e.g. HOME, TERM, etc

    I'm not sure about subcommand flags. For my use case I would only need to add support for global flags - for functionality that would trigger special functionality on a global level, like MYAPP_DEBUG=1. But IF we want that feature as well for subcommand flags, I guess it will make sense to include the subcommand name into the env var name, to avoid conflicts with flags from other subcommands.

    flaggy.DefaultParser.EnableEnvFlagsWithPrefix("MYAPP")
    flaggy.String(&stringFlagA, "a", "flagA", "A test string flag (A)")
    subcommand := flaggy.NewSubcommand("subcommandExample")
    subcommand.String(&stringFlagB, "b", "flagB", "A test string flag (B)")
    

    Corresponding env vars would be:

    • MYAPP_FLAG_A
    • MYAPP_SUBCOMMAND_EXAMPLE_FLAG_B

    Happy to work on this. Just wanted to check if you were interested in this feature or would reject it.


    I also do like the way urfave/cli has support for custom env vars per flag. But I don't see how we could implement this in a backwards compatible way into flaggy. The function signature of all flag functions would change.

  • flags + config file

    flags + config file

    Ideally it would be possible to define the config via either a config file or via flags. If the same flag is present in both the config file and the flags, the flags take precedence.

    I find that being able to use a combination of config files and flags makes for a very robust system. There is some config which makes sense to live with the application in a config file, while other types of config make the most sense to be passed via a flag.

  • Support for trailing arguments

    Support for trailing arguments

    Unless I've misunderstood the documentation, it doesn't seem like it's possible to have an arbitrary number of trailing arguments.

    Let's say you want to write your own version of cat(1).

    Based on the documentation, it seems like I should be able to use flaggy.TrailingArguments to get at the list of zero or more input files.

    Unfortunately, if you actually try to use trailing arguments that aren't declared as positionals, flaggy throws an error:

    $ go run main.go file1 file2 file3
    <snip>
    Unexpected argument: file1
    exit status 2
    

    Flaggy will accept trailing arguments if declared as positionals, but there does not seem to be a way to support an arbitrary number of them--each must be explicitly declared, so you can't actually write a cat command that takes an arbitrary number of file arguments.

  • program string argument without the value doesn't appear to work

    program string argument without the value doesn't appear to work

    Based on the document, I should be able to have argument defined with a default. If no value is provided the default should be applied. Example: ./command -g all should work just like ./command -g when -g has a default of all. My code:

    var genDoc string = "ALL"
    
    func init() {
    	flaggy.SetName("sdocs - Sote Docs")
    	flaggy.SetDescription("sdocs will output markdown syntax for packages contenting publishable content")
    
    	// 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://gitlab.com/getsote/utils"
    
    	// Add a flag to the main program (this will be available in all subcommands as well).
    	flaggy.Bool(&listVar, "l", "list", "This list the packages that are supported by this utility")
    	flaggy.String(&genDoc, "g", "gen", "-g <package name> Generate docs from support packages")
    
    	// Set the version and parse all inputs into variables.
    	flaggy.SetVersion(version)
    	flaggy.Parse()
    }
    

    When I run with ./sdoc -g, I get the following:

    /Users/syacko/workspace/sotesoft/src/utils/sdocs/sdocs -g #gosetup
    sdocs - Sote Docs - sdocs will output markdown syntax for packages contenting publishable content
    http://gitlab.com/getsote/utils
    
      Flags: 
           --version   Displays the program version string.
        -h --help      Displays help with available flag, subcommand, and positional value parameters.
        -l --list      This list the packages that are supported by this utility
        -g --gen       -g <package name> Generate docs from support packages
    
    Expected a following arg for flag g, but it did not exist.
    
    Process finished with exit code 2
    

    When I run /sdoc -g ALL, I get the following:

    /Users/syacko/workspace/sotesoft/src/utils/sdocs/sdocs -g ALL #gosetup
    You selected All
    
    Process finished with exit code 0
    
  • Small cosmetic impovements

    Small cosmetic impovements

    • Added shortcut Positional() for better balanced API.
    • Replaced "Positional arguments" with "Positionals" in help message.
    • Added newline after positional arguments in help message.

    Guys! This is only my vision but i think it will looks slightly better.

  • Fix bug with bool flags on subcommands

    Fix bug with bool flags on subcommands

    Fixes error for valid bool flags "expected a following arg for flag , but it did not exist"

    The fix is to check flags on all nested subcommands when determining if a flag is a bool

    This fixes issue #57

  • Error customization

    Error customization

    Hi.

    Consider the following example:

    package main
    
    import "github.com/integrii/flaggy"
    
    func main() {
    	// 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
    	println(stringFlag)
    }
    

    when calling this by % ./main -f a, it shows the following error:

    mymain
    
      Usage:
        mymain [subcommandExample]
    
      Subcommands: 
        subcommandExample
    
      Flags: 
           --version   Displays the program version string.
        -h --help      Displays help with available flag, subcommand, and positional value parameters.
    
    Unknown arguments supplied:  f a
    

    so, is there any option to show the error as Unknown arguments supplied: -f a instead of Unknown arguments supplied: f a? I.e, replacing the empty space before f by the - symbol.

    Edit: the same for Expected a following arg for flag f, but it did not exist, it would be nice an option to show Expected a following arg for flag -f, but it did not exist instead, and Expected a following arg for flag --flag, but it did not exist instead of Expected a following arg for flag flag, but it did not exist, and so on.

    TIA

  • Unknown arguments supplied

    Unknown arguments supplied

    "Unknown arguments supplied" when the subcommand and flag have same shortname

    // example.go
    package main
    
    import (
    	"fmt"
    
    	"github.com/integrii/flaggy"
    )
    
    func main() {
    	subcmd := flaggy.NewSubcommand("testSubCmd")
    	subcmd.ShortName = `t`
    	var test string
    	subcmd.String(&test, "t", "testFlag", "test flag")
    	flaggy.AttachSubcommand(subcmd, 1)
    	flaggy.Parse()
    	fmt.Println(test)
    }
    

    go run example.go t -t hello
    testSubCmd

    Flags:
    --version Displays the program version string.
    -h --help Displays help with available flag, subcommand, and positional value parameters.
    -t --testFlag test flag

    Unknown arguments supplied: hello
    exit status 2

  • Text aligment of help output

    Text aligment of help output

    I'm trying to migrate https://github.com/rfjakob/gocryptfs from stdlib to flaggy. It's nice so far, having slice types is great, binding positional arguments is great, but is there a way to align the help output?

    $ ./gocryptfs -hh
    gocryptfs v2.0.1-43-gb67c678.flaggy; go-fuse v2.1.1-0.20210802120645-15a8bb029a4e; 2021-08-09 go1.16.5 linux/amd64
    
    Usage: gocryptfs -init|-passwd|-info [OPTIONS] CIPHERDIR
      or   gocryptfs [OPTIONS] CIPHERDIR MOUNTPOINT
    
    Options:
    gocryptfs
    
      Usage:
        gocryptfs [CIPHERDIR] [MOUNTPOINT]
    
      Positional Variables: 
        CIPHERDIR    ciphertext directory
        MOUNTPOINT   mountpoint
      Flags: 
        -h --help               Displays help with available flag, subcommand, and positional value parameters.
        -d 
        -debug                    Enable debug output
        -fusedebug                    Enable fuse library debug output
        -init                    Initialize encrypted directory
        -zerokey                    Use all-zero dummy master key
        -openssl                    Use OpenSSL instead of built-in Go crypto (default: auto)
        -passwd                    Change password
        -f 
        -fg                    Stay in the foreground
        -version                    Print version and exit
        -plaintextnames                    Do not encrypt file names
        -q 
        -quiet                    Quiet - silence informational messages
        -nosyslog                    Do not redirect output to syslog when running in the background
        -wpanic                    When encountering a warning, panic and exit immediately
        -longnames                    Store names longer than 176 bytes in extra files (default: true)
        -allow_other                    Allow other users to access the filesystem. Only works if user_allow_other is set in /etc/fuse.conf.
        -reverse                    Reverse mode
        -aessiv                    AES-SIV encryption
        -nonempty                    Allow mounting over non-empty directories
        -raw64                    Use unpadded base64 for file names (default: true)
        -noprealloc                    Disable preallocation before writing
        -speed                    Run crypto speed test
        -hkdf                    Use HKDF as an additional key derivation step (default: true)
        -serialize_reads                    Try to serialize read operations
        -forcedecode                    Force decode of files even if integrity check fails. Requires gocryptfs to be compiled with openssl support and implies -openssl true
        -hh                    Show this long help text (default: false)
        -info                    Display information about CIPHERDIR
        -sharedstorage                    Make concurrent access to a shared CIPHERDIR safer
        -devrandom                    Use /dev/random for generating master key
        -fsck                    Run a filesystem check on CIPHERDIR
        -dev                    Allow device files
        -nodev                    Deny device files
        -suid                    Allow suid binaries
        -nosuid                    Deny suid binaries
        -exec                    Allow executables
        -noexec                    Deny executables
        -rw                    Mount the filesystem read-write
        -ro                    Mount the filesystem read-only
        -kernel_cache                    Enable the FUSE kernel_cache option
        -acl                    Enforce ACLs
        -masterkey                    Mount with explicit master key
        -cpuprofile                    Write cpu profile to specified file
        -memprofile                    Write memory profile to specified file
        -config                    Use specified config file instead of CIPHERDIR/gocryptfs.conf
        -ko                    Pass additional options directly to the kernel, comma-separated list
        -ctlsock                    Create control socket at specified path
        -fsname                    Override the filesystem name
        -force_owner                    uid:gid pair to coerce ownership
        -trace                    Write execution trace to file
        -fido2                    Protect the masterkey using a FIDO2 token instead of a password
        -e --exclude            Exclude relative path from reverse view
        -ew --exclude-wildcard   Exclude path from reverse view, supporting wildcards
        -exclude-from                    File from which to read exclusion patterns (with -exclude-wildcard syntax)
        -extpass                    Use external program for the password prompt
        -badname                    Glob pattern invalid file names that should be shown
        -passfile                    Read password from file
        -notifypid                    Send USR1 to the specified process after successful mount - used internally for daemonization (default: 0)
        -scryptn                    scrypt cost parameter logN. Possible values: 10-28. A lower value speeds up mounting and reduces its memory needs, but makes the password susceptible to brute-force attacks (default: 16)
        -i --idle               Auto-unmount after specified idle duration (ignored in reverse mode). Durations are specified like "500s" or "2h45m". 0 means stay mounted indefinitely. (default: 0s)
        -nofail                    Ignored for /etc/fstab compatibility
        -o                    For compatibility with mount(1), options can be also passed as a comma-separated list to -o on the end.
    
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.

Jan 25, 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

Nov 24, 2022
Read from standard input and output a Haags translation of the given input.

haags Read from standard input and output a Haags translation of the given input. Building make && sudo make install You may also run go build on syst

Oct 23, 2022
Terminal stock ticker with live updates and position tracking
Terminal stock ticker with live updates and position tracking

Ticker Terminal stock watcher and stock position tracker Features Live stock price quotes Track value of your stock positions Support for multiple cos

Jan 8, 2023
☀️ Go calculations for the position of the sun and moon.
☀️ Go calculations for the position of the sun and moon.

Astral Calculations for the position of the sun and moon. This is a Go port of the Python astral package. The astral package provides the means to cal

Sep 28, 2022
A simple way for CLI command to have many subcommands

subcommands This is a modified fork of google/subcommands that uses lucasepe/pflag Subcommands is a Go package that implements a simple way for a sing

Oct 12, 2021
Json-match - Command line util for matching values in a JSON input

json-match Match JSON input by specifying key and value > json-match -json '{\"p

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

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

Dec 30, 2022
Jan 27, 2022
Grab is a tool that downloads source code repositories into a convenient directory layout created from the repo's URL's domain and path

Grab is a tool that downloads source code repositories into a convenient directory layout created from the repo's URL's domain and path. It supports Git, Mercurial (hg), Subversion, and Bazaar repositories.

Jun 2, 2022
archy is an static binary to determine current kernel and machine architecture, with backwards compatible flags to uname, and offers alternative output format of Go runtime (i.e. GOOS, GOARCH).

archy archy is an simple binary to determine current kernel and machine architecture, which wraps uname and alternatively can read from Go runtime std

Mar 18, 2022
Automatically sets up command line flags based on struct fields and tags.
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

Dec 1, 2022
A go1.18 wrapper to provide simple generics based API for defining command line flags.

gflag A go1.18 wrapper to provide simple generics based API for defining command line flags. Example package main import ( "flag" "fmt" "time" "

Dec 20, 2021
Go-flags wireframing demo

go-flags-demo redo - global option redo Redo global option via automatic code-gen TOC go-flags-demo - global option redo Synopsis Usage Development Hi

Jan 22, 2022
Package varflag implements command-line flag parsing into vars.Variables for easy type handling with additional flag types.

varflag Package flag implements command-line flag parsing into vars.Variables for easy type handling with additional flag types. varflag Flags String

Aug 2, 2022
Fonts is a package that provides helpers to access font details and easily retrive font bytes with ZERO dependencies

Fonts Fonts is a package that provides helpers to access font details and easily retrieve font bytes. This package has ZERO 3rd-party dependencies. Fo

Mar 3, 2022
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.
Go package to make lightweight ASCII line graph ╭┈╯ in command line apps with no other dependencies.

asciigraph Go package to make lightweight ASCII line graphs ╭┈╯. Installation go get github.com/guptarohit/asciigraph Usage Basic graph package main

Jan 8, 2023
Clones dependencies from .resolved file of Swift Package Manager.

SPM-dep-cloner Clones dependencies from .resolved file of Swift Package Manager. Useful for setup of new project with dependencies in another repos. H

Nov 29, 2021
Optinator - Idiomatic way to fill structs with options logic

optinator Go packages are generally start with a main struct and the package ini

Mar 15, 2022