About
argmap is a simple command line argument parser for Go providing high level features and wide freedom of usage. The user inputs are stored in a map allowing to easily gather, analyze and retrieve them.
Along with positional arguments and commands, different types of flags can be defined according to the needs of your application. Please note that nothing is arbitrarily made without giving you, the developer, a choice about the handling of the results, even in case something goes wrong: there are built-in functions to easily report possible errors, but they won't be automatically called if you do not want so to ensure high flexibility of usage.
Getting started
In order to use argmap, first download it using the go get
command as follows:
go get -v "github.com/zorzr/argmap"
Afterwards, in your .go files it is sufficient to import the package at the beginning of the files. Just add argmap to the list of imports:
import "github.com/zorzr/argmap"
Defining arguments
If you already practised with argparse for Python, you will find argmap rather familiar. After importing the package, you need to create an ArgsParser
object as follows:
parser := argmap.NewArgsParser("Program name", "Program description")
The returned object includes all the methods you'll need to add arguments and parse the command line inputs. It can be also used to print the program help and report errors.
There are different kinds of arguments you can define.
// StringFlag arguments: [--str|-s arg1 arg2]
parser.NewStringFlag(argmap.StringFlag{Name: "str", Short: "s", NArgs: 2, Vars: []string{"arg1", "arg2"}, Help: "stores the two arguments in an array"})
// ListFlag arguments: [--list|-l item item ...]
parser.NewListFlag(argmap.ListFlag{Name: "list", Short: "l", Var: "item", Help: "list of items (could receive any number, even none)"})
// BoolFlag arguments: [--bool|-b]
parser.NewBoolFlag(argmap.BoolFlag{Name: "bool", Short: "b", Help: "stores true when present"})
// PositionalArg
parser.NewPositionalArg(argmap.NewPositionalArg{Name: "pos", Required: True, Help: "required argument (recognized just by its position)"})
The ArgsParser can also insert commands, which can help you structure your program and accept their own set of arguments (separate from the program ones). Clearly, commands support all of the already mentioned types of arguments, even (nested) sub-commands.
// main.go cmd --bool sub ...
cmd, err := parser.NewCommand(argmap.CommandParams{Name: "cmd", Help: "a command"})
cmd.NewBoolFlag(argmap.BoolFlag{Name: "bool"})
sub, err := cmd.NewSubcommand(argmap.CommandParams{Name: "sub", Help: "a subcommand")
Further information on the usage of the parser and the arguments can be found on the GitHub repository.
Parsing arguments
Once all arguments have been defined, the command line inputs can be parsed and organized in a map.
argsMap, err := parser.Parse()
If everything goes well, the arguments are grouped in the argsMap
instance. Every value can be found indexed by the previously defined argument name (or its abbreviation, if only the short parameter was passed). Now, argmap provides some useful functions to get values from the map in a straightforward way. Here's some examples:
strValues, err := argmap.GetList(argsMap, "str")
strArg1, err := argmap.GetListValue(argsMap, "str", 0)
strArg2, err := argmap.GetListValue(argsMap, "str", 1)
listValues, err := argmap.GetList(argsMap, "list")
boolValue := argmap.GetBool(argsMap, "bool")
positionalValue, err := argmap.GetPositional(argsMap, "pos")
// commands have their own argument map
// the same functions can be used on the cmdMap
cmdMap, err := argmap.GetCommandMap(argsMap, "cmd")
cmdBool, err := argmap.GetBool(cmdMap, "bool")
Most of these functions return an error if the key was not found in the map (that is, it wasn't in the terminal inputs) or the requested value isn't of the correct type (e.g., of course you can't get a positional string value with GetList()
, which returns an array). The only exception is GetBool()
which returns False in any of these circumstances. If you want to check if an argument is present in the map, you may want to use the function IsPresent()
.
if IsPresent(argsMap, "str") {
strValues, _ := argmap.GetList(argsMap, "str")
fmt.Printf("str: [%s, %s]\n", strValues[0], strValues[1])
}
If there is an error when calling parser.Parse()
, probably the flags weren't properly used (e.g., a value was missing from a StringFlag) or a required positional was missing. You can automatically report the error and exit by doing:
argsMap, err := parser.Parse()
if err != nil {
parser.ReportError(err)
// prints the error, shows the help message and exits
}
Support
Please report if you notice any bug by opening a new issue on Github!
Thank you!