integrii / flaggy Goto Github PK
View Code? Open in Web Editor NEWIdiomatic 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
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
Currently it shows help for the main parser, regardless of subcommands
A simple example:
mycoolpackagemanager install pkg1 pkg2 pkg3 ... pkgN
Is this supported? I didn't find anything about this
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`.
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
Add a reasonable license or nobody will actually use it in production. P. S. Good luck here it's a nice project.
It's said no external dependencies.
"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
testSubCmdFlags:
--version Displays the program version string.
-h --help Displays help with available flag, subcommand, and positional value parameters.
-t --testFlag test flagUnknown arguments supplied: hello
exit status 2
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.
It leaves a lot out and is missing a comma.
It would be convenient to support time.Duration flags.
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.
This issue is to plan this feature. We should not put this program in the main codebase if it has external dependencies.
Formats to consider support for:
How do I explicitly print out a subcommand's help text (usage)?
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.
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:
--flag
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.
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"}
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
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.
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()
?
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.
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.
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.
If the user specifies -h
, --help
, -v
, or --version
when those flags are enabled on the parser, flaggy should throw a helpful warning instructing them to either disable the built-in flag or change their flag name.
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.
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.
It could be convenient to pass in a pointer to a struct for options. Flaggy could loop over the struct fields, and depending on the property type and name, assign variables into it.
We should implement a go module, even though the project is only v1 and has no dependencies.
We should be able to hide flags, subcommands, and positionals from help output and suggestions.
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.
refactor code so that more flag types can be easily added. Fold all flags into a single Flag struct and use type switches where specific flag type operations are performed.
Would you consider adding an option to convert positional arguments to different types like flags do today?
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.
This prevents endless error checking on each variable's assignment declaration in your init function and mirrors the behavior of the flags package.
These default flags should appear in the help messaging... They should be hidden when they are disabled.
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:
-
) is used, then we treat every following character as its own flag--
) is used, then we treat the following as one long flag nameIt'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
.
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
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
It would help contributors if we made getting started an easy process.
The process is basically the git flow...
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.
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?
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)
}
Contents of my go.mod
file:
module testing
go 1.12
require github.com/integrii/flaggy v1.2.1-0.20190517180110-07ea7eb77404 // indirect
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.
I'm trying to do this:
mycmd subcmd <random val> -verbose
how can I get the <random val>
? thanks
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?
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
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.
When they aren't any positionals or subcommands, the help ends up reading:
Usage:
appname
which is not helpful. Just hide it if that occurs.
For example, you could do -l label -l label
or -v -v
.
Help templates are spawned from values created in helpValues.go
. It would be good to document this so people don't have to figure it out on their own.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.