GithubHelp home page GithubHelp logo

integrii / flaggy Goto Github PK

View Code? Open in Web Editor NEW
854.0 17.0 31.0 277 KB

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

License: The Unlicense

Go 100.00%
golang flags subcommands cli input

flaggy's People

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

flaggy's Issues

How to organise your (sub)commands

I like what I see except I don't know how to actually structure you app.

For instance... let's imagine I have an app with 5 command that each have there own (3?) subcommands.

I would like to have a single file per command. How would I nicely call the different modules without having allot of if statements like if subcommand.Used`.

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

License

Add a reasonable license or nobody will actually use it in production. P. S. Good luck here it's a nice project.

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

Separate subcommand flags from global flags

I asked about this on the slack channel a while back. Since it is one of only two issues I have with flaggy, I thought I'd ask about it here.

When exploring a CLI program I start by viewing the help at the root command, I figure out which subcommand I want to use, then I view its available options. Currently in the help output flaggy groups all flags together in the Flags section. It is often difficult to figure out which flags apply specifically to the subcommand, especially when you have many global flags.

This is the default output:

go run main.go policy delete mypolicy -h
delete

  Usage:
    delete [policy_name]

  Positional Variables: 
    policy_name   (Required)

  Flags: 
       --version      Displays the program version string.
    -h --help         Displays help with available flag, subcommand, and positional value parameters.
    -a --associated-data   also delete associated data
       --addr         address of server

I'd like to see something like this instead:

delete

  Usage:
    delete [policy_name]

  Positional Variables: 
    policy_name   (Required)

  Subcommand Flags:
    -a --associated-data   also delete associated data

  Flags: 
       --version      Displays the program version string.
    -h --help         Displays help with available flag, subcommand, and positional value parameters.
       --addr         address of server

Here is some output from the Dgraph command line, which I believe uses Cobra. The root help shows a Flags section, but the help for a subcommand moves that flags section to Global Flags and uses the Flags section for the subcommand:

> $ dgraph acl --help
[Decoder]: Using assembly version of decoder
Run the Dgraph acl tool

Usage:
  dgraph acl [command]

Available Commands:
  add         Run Dgraph acl tool to add a user or group
  del         Run Dgraph acl tool to delete a user or group
  info        Show info about a user or group
  mod         Run Dgraph acl tool to modify a user's password, a user's group list, or agroup's predicate permissions

Flags:
  -a, --alpha string               Dgraph Alpha gRPC server address (default "127.0.0.1:9080")
  -h, --help                       help for acl
      --tls_cacert string          The CA Cert file used to verify server certificates.
      --tls_use_system_ca          Include System CA into CA Certs. (default true)

Global Flags:
      --alsologtostderr                  log to standard error as well as files
      --bindall                          Use 0.0.0.0 instead of localhost to bind to all addresses on local machine. (default true)
      --block_rate int                   Block profiling rate. Must be used along with block profile_mode
      --config string                    Configuration file.

Use "dgraph acl [command] --help" for more information about a command.

It's been a while since I've dug into the code. I'm curious if the required information is available to do this in a template (which I don't think it is). And how hard you think it would be make that expose that to the help template.

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.

Improve help output

I want to get the default help closer to the help output of Cobra a little more. Specifically the Usage section. This is challenging because Flaggy allows for even more use patterns than cobra does and we don't want output to hide that.

Sample help from Cobra:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.

Usage:
  cobra [command]

Available Commands:
  add         Add a command to a Cobra Application
  help        Help about any command
  init        Initialize a Cobra Application

Flags:
  -a, --author string    author name for copyright attribution (default "YOUR NAME")
      --config string    config file (default is $HOME/.cobra.yaml)
  -h, --help             help for cobra
  -l, --license string   name of license for the project
      --viper            use Viper for configuration (default true)

Use "cobra [command] --help" for more information about a command.

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.

Support slice flag inputs with commas

Currently, slice flags are required to be specified multiple times. It could be helpful though to automatically parse commas in slice flag inputs into different values. Then again, it could make passing literal commas more confusing.

Should we support slice inputs like this:
./app -str one,two
which results in []string{"one","two"}

or should we continue to only support multiple flag uses like this:
./app -str one -str two
which results in the same [string{"one","two"}

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

Change os.Exit() calls to use a function so more tests can be ran

Currently the go-awesome people are bouncing Flaggy for code coverage. If we simply change the calls to os.Exit() to some kind of quit() function, then we can disable actual quits during testing. When all tests are enabled, the code coverage will shoot up a lot. Most are skipped as of now because they cause testing to exit.

Can you require that a specific flag is used?

I saw this in the README:

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

and when reviewing the GoDoc page for this package I saw that positional arguments can optionally be required, but didn't spot that feature when configuring flags.

Is there an easy way to determine when a flag has been provided? Would you perhaps define a "default" instance of a configuration type to compare against the configuration type that is modified by flaggy.Parse()?

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.

Drop the built in -v version flag

The built-in -v flag is going to conflict with people who want a verbose flaf commonly. I think we should keep the --version flag but drop the -v flag.

Add flags dynamically

I want to dynamically add more flags to the application.

Imagine that I have a flag that is --extra-features. I want to add more flags dynamically if this one is present. How can I do something like that?

Thank you.

Show default values of variables

this will require reading the assignment var and converting it into the string format the user could use to supply it. Then, we display that value with help output, if it exists.

Add bash/zsh auto completion generation

We should generate bash auto complete code when some pre-defined flag is specified. The flag should be able to be turned off if the user prefers that flag not be used by the system.

implement a go module

We should implement a go module, even though the project is only v1 and has no dependencies.

Go Module Status

Bit confused by the project's current go.mod relation to the tagged version 1.1.0.

Current go mod tidy results with a import "github.com/integrii/flaggy" has master being selected:

go 1.12

require (
	github.com/integrii/flaggy v0.0.0-20190220052119-eb3cf98db853
)

Editing go.mod to:

go 1.12

require (
	github.com/integrii/flaggy 1.1.0
)

Results in:

$ go mod tidy
go: finding github.com/integrii/flaggy 1.1.0
go: github.com/integrii/[email protected]: go.mod has post-v0 module path "github.com/integrii/flaggy/v1" at revision f984caf11202
go: error loading module requirements

and results in go.mod being updated to:

go 1.12

require (
	github.com/integrii/flaggy v0.0.0-20180921152458-f984caf11202
)

This error makes sense since f984caf go.mod has v1 declared. It appears the later commit 6cc633c fixes this by removing all the v1 tags.

Is the project in a transitional state before the next release, eg. presumable tagging v1.1.1 would fix this?

Thanks.

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.

Refactor how - and -- are handled

In some circles, using a single - means that the next character will be a single-character flag and if there are multiple letters, they should be treated like a list of single-character flags. If a double dash is used (--) then we should consider the following characters all part of a single flag until a space or = is seen.

Right now, flaggy does not parse differently when it sees a - or --. This means that single letter flags can not be grouped up.

For example, this command would be parsed with two flags by some parsers:

docker exec -it

However in flaggy, this would be treated as one long flag named it.

I propose that we refactor flaggy with the following logic:

  • If a single dash (-) is used, then we treat every following character as its own flag
  • if a double dash (--) is used, then we treat the following as one long flag name

Make it easier to disable `--version` output

It's not obvious you can disable the --version output from flaggy by doing flaggy.DefaultParser.ShowVersionWithVersionFlag = false. It would be easier to have a top level function that sets ShowVersionWithVersionFlag to false on DefaultParser.

Global positional value arguments don't work after subcommands

I am trying to have some global positional values after subcommands as these are the same for each command but when parsing flags and entering a value at the positional place I always get an Unexpected argument: <value> exception

It works fine when using them under a subcommand but not globally

Global positional values also dont show up under the help of a subcommand

gist with code and output (mostly copied from example and blank lines removed):
https://gist.github.com/topjor/51e52e88e2c7aedb4d5b34c21497d1a1

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 (4253042) 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

Create a contributor guide

It would help contributors if we made getting started an easy process.

The process is basically the git flow...

  • Make an issue to propose your change
  • Fork the repo
  • Make your changes
    • Add tests
    • ensure all tests pass
  • Make a pull request referencing your original proposal
  • Get recognition (crate CONTRIBUTORS.md?)

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

Duplicate Results in Slice flags when SubCommand Used

Modifying the sliceFlag example to include a subcommand like:

package main

import "github.com/integrii/flaggy"

func main() {
	// Declare variables and their defaults
	var stringSliceFlag []string
	var boolSliceFlag []bool

	// Add a slice flag
	flaggy.DefaultParser.AdditionalHelpAppend = "Example: ./sliceFlag -b -b -s one -s two -b=false"
	flaggy.StringSlice(&stringSliceFlag, "s", "string", "A test string slice flag")
	flaggy.BoolSlice(&boolSliceFlag, "b", "bool", "A test bool slice flag")

	testSubcommand := flaggy.NewSubcommand("test")
	testSubcommand.Description = "Testing"
	testSubcommand.ShortName = "test"

	flaggy.AttachSubcommand(testSubcommand, 1)

	// Parse the flag
	flaggy.Parse()

	// output the flag contents
	for i := range stringSliceFlag {
		println(stringSliceFlag[i])
	}

	for i := range boolSliceFlag {
		println(boolSliceFlag[i])
	}
}

Results in:

$ ./main -b -b -s one -s two -b=false
one
two
true
true
false
$ ./main -b -b -s one -s two -b=false test
one
two
one
two
true
true
false
true
true
false

It appears all args are passed to the recursed subcommand here: https://github.com/integrii/flaggy/blob/master/subCommand.go#L280. Perhaps only the arguments to the right of the subcommand in the args should be passed?

Otherwise, perhaps a more thorough approach is to consider the depth of the flag being parsed. If the flag doesn't belong to the current depth then ignore it.

Non-flag arguments?

I'm trying to do this:

mycmd subcmd <random val> -verbose

how can I get the <random val> ? thanks

Sorting of flags

I have reviewed the documentation and I don't see a way to sort the out put of the flags when -h(elp) is used. Is this possible and if not, is it something that can be added?

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

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.

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.