import "github.com/barbell-math/smoothbrain-argparse"
A very simple CMD line argument parser that allows for arguments to be specified from both the CLI and a TOML config file.
Example (Simple)
package main
import (
"flag"
"fmt"
"reflect"
)
type exampleConf struct {
StoreName string
NumItems int
NumLocations int
HasFreeFood bool
Department struct {
Name string
Specialty string
}
Vegies []string
Fruits map[string]struct {
Yummy bool
Color string
}
}
func main() {
var c exampleConf
err := Parse(
&c,
[]string{
// Normally these would be os.Args[1:] but for the example we
// provide a list of strings.
"-StoreName", "kings",
"-NumLocations", "3",
"-conf", "./bs/example.toml",
},
ParserOpts[exampleConf]{
ProgName: "example",
RequiredArgs: []string{"StoreName"},
ArgDefsSetter: func(conf *exampleConf, fs *flag.FlagSet) error {
// It is generally recommented (though not enforced) to name
// CMD line arguments the same as the keys in the TOML file.
fs.StringVar(&c.StoreName, "StoreName", "", "a string")
fs.IntVar(&c.NumItems, "NumItems", 1, "a int")
fs.IntVar(&c.NumItems, "NumLocations", 0, "a int")
// Defaults for non-FlagSet arguments can be set here as well
c.HasFreeFood = true // :)
return nil
},
},
)
fmt.Println("Parsing error: ", err)
fmt.Println("Parsed conf:")
typ, val := reflect.TypeOf(c), reflect.ValueOf(c)
for i := 0; i < typ.NumField(); i++ {
fmt.Printf(" %-20s → %v\n", typ.Field(i).Name, val.Field(i).Interface())
}
}
Parsing error: <nil>
Parsed conf:
StoreName → kings
NumItems → 3
NumLocations → 0
HasFreeFood → true
Department → {produce fruit and vegetables}
Vegies → [potato carrot chicken]
Fruits → map[apple:{true red} banana:{true yellow} orange:{true orange}]
- Variables
- func DB(fs *flag.FlagSet, dc *DBConf, longArgStart string, _defaults DBConf)
- func Logging(fs *flag.FlagSet, lc *LoggingConf, longArgStart string, _defaults LoggingConf)
- func Parse[T any](conf *T, cliArgs []string, opts ParserOpts[T]) error
- func Verbosity[T constraints.Signed](fs *flag.FlagSet, val *T, longArgStart string, _default T)
- type AbsDir
- type AbsFile
- type DBConf
- type Dir
- type EnvVar
- type File
- type FlagSetFunc
- func Float[T constraints.Float](val *T, _default T) FlagSetFunc
- func FromTextUnmarshaler[T any, I interface { *T encoding.TextUnmarshaler }](val *T, _default T) FlagSetFunc
- func Int[T constraints.Signed](val *T, base int, _default T) FlagSetFunc
- func Time(val *time.Time, _default time.Time) FlagSetFunc
- func Uint[T constraints.Unsigned](val *T, _default T, base int) FlagSetFunc
- type LoggingConf
- type ParserOpts
var (
InvalidArgumentErr = errors.New("Invalid argument")
InvalidConfFileErr = errors.New("Invalid conf file")
MissingRequiredArgsErr = errors.New("Missing required args")
InvalidValuesInConfFileErr = errors.New("Invalid values in conf file")
)
var (
EnvVarNotSetErr = errors.New(
"The supplied environment variable was not set",
)
)
var (
MissingLeadingZerosErr = errors.New(
"Leading zeros in date-time values cannot be left off",
)
)
func DB
func DB(fs *flag.FlagSet, dc *DBConf, longArgStart string, _defaults DBConf)
Sets five flags that are intended to be used to access a database:
- <longArgStart>.User
- <longArgStart>.PswdEnvVar
- <longArgStart>.Host
- <longArgStart>.Port
- <longArgStart>.Name
The longArgStart argument should be used to make sure the CMD line argument has the same name as the TOML key.
func Logging
func Logging(fs *flag.FlagSet, lc *LoggingConf, longArgStart string, _defaults LoggingConf)
Sets five flags:
- <longArgStart>.SaveTo
- l
- <longArgStart>.Name
- <longArgStart>.MaxNumLogs
- <longArgStart>.MaxLogSizeBytes
- <longArgStart>.Verbose
- v
`<longArgDir>.SaveTo` and `l` will both set the directory to place any log files in. The flag parser will check that the dir exists. `<longArgStart>.Verbose` and `v` will be set by Verbosity.
The longArgStart argument should be used to make sure the CMD line argument has the same name as the TOML key.
func Parse
func Parse[T any](conf *T, cliArgs []string, opts ParserOpts[T]) error
Takes a sequence of CMD line arguments and parses them. The supplied `conf` value will be populated with any values.
A `conf` argument will be added that will accept a path to a TOML config file. This TOML config file will be treated as another source of arguments, and the `conf` value will be populated with the contents of that file. The burnt sushi TOML parser is used internally, refer to it's documentation for things like struct field tags.
The arguments that are present in the TOML config file will take precedence over all CMD line arguments.
func Verbosity
func Verbosity[T constraints.Signed](fs *flag.FlagSet, val *T, longArgStart string, _default T)
Sets two flags:
- <longArgStart>.Verbose
- v
`<longArgStart>.Verbose` and `v` will both increment the same underlying value by one every time they are supplied. Both `v` and `<longArgStart>.Verbose` can be supplied multiple times.
The longArgStart argument should be used to make sure the CMD line argument has the same name as the TOML key. If verosity is a top level key then set longArgStart to an empty string.
type AbsDir
Can be used to represent an absolute path to a dir in a config. When unmarshaling the path will be made absolute if it is not already.
type AbsDir string
func (*AbsDir) UnmarshalText
func (a *AbsDir) UnmarshalText(data []byte) error
Checks that the supplied data is a valid path to a dir and if so resolves the absolute path and sets the underlying value absolute to the path.
type AbsFile
Can be used to represent an absolute path to a file in a config. When unmarshaling the path will be made absolute if it is not already.
type AbsFile string
func (*AbsFile) UnmarshalText
func (a *AbsFile) UnmarshalText(data []byte) error
Checks that the supplied data is a valid path to a file and if so resolves the absolute path and sets the underlying value absolute to the path.
type DBConf
type DBConf struct {
User string
PswdEnvVar EnvVar
Host string
Port uint16
Name string
}
type Dir
Can be used to represent a path to a dir in a config
type Dir string
func (*Dir) UnmarshalText
func (d *Dir) UnmarshalText(data []byte) error
Checks that the supplied data is a valid path to a dir and if so sets the underlying value to the path.
type EnvVar
Can be used to represent a path to an environment variable in a config. The value of the config entry will be set to the value of the environment variable, if it exists. If it does not exist an error is returned.
type EnvVar string
func (*EnvVar) UnmarshalText
func (e *EnvVar) UnmarshalText(data []byte) error
Checks that the supplied data is a valid path to a file and if so sets the underlying value to the path.
type File
Can be used to represent a path to a file in a config
type File string
func (*File) UnmarshalText
func (f *File) UnmarshalText(data []byte) error
Checks that the supplied data is a valid environment variable and if so sets the underlying value to the value of the environment variable.
type FlagSetFunc
The type of function that flag.Func accepts
type FlagSetFunc func(arg string) error
func Float
func Float[T constraints.Float](val *T, _default T) FlagSetFunc
Useful for parsing a specific kind of float from the CMD line since flag does not have a generic version yet. (It only provides float64)
func FromTextUnmarshaler
func FromTextUnmarshaler[T any, I interface {
*T
encoding.TextUnmarshaler
}](val *T, _default T) FlagSetFunc
Useful when a type in the supplied config value is a custom type that implements the encoding.TextUnmarshaler interface which the TOML parser will use when parsing values.
This is provided as a way to make sure the CMD line args can be parsed in the same manner as the values in the TOML file.
func Int
func Int[T constraints.Signed](val *T, base int, _default T) FlagSetFunc
Useful for parsing a specific kind of int from the CMD line since flag does not have a generic version yet. (It only provides int)
func Time
func Time(val *time.Time, _default time.Time) FlagSetFunc
Useful for parsing a time value from the CMD line. The format will one of the [allowd date-time formats in TOML].
func Uint
func Uint[T constraints.Unsigned](val *T, _default T, base int) FlagSetFunc
Useful for parsing a specific kind of uint from the CMD line since flag does not have a generic version yet. (It only provides uint)
type LoggingConf
type LoggingConf struct {
Verbosity int
SaveTo Dir
Name string
MaxNumLogs int
MaxLogSizeBytes int
}
type ParserOpts
type ParserOpts[T any] struct {
// The program name that should be printed out on the help menu in the
// following format: `Usage of <program name>`. If left empty
// <program name> will be replaced with `this program`.
ProgName string
// All arguments provided in this list must be provided. Arguments can
// be provided in either the CMD line, in a TOML conf file, or both. If
// an argument is provided in either place it will be marked as present.
RequiredArgs []string
// The function that allows the user (you) to define the CMD line
// arguments. The CMD line argument parameters can be named the same as
// the keys in the TOML file. Naming the parameters the same as their
// associated key in the TOML file is generally recommended, and may be
// necessary to make it so arguments in the [RequiredArgs] list are seen
// as present from both the CMD line and TOML conf file. Hierarchical
// keys of the TOML file are separated by a '.'.
//
// This function can also be used to set default values. Assuming that
// you don't have a FlagSet argument for a given value in conf, simply
// set that value to the default value. If a FlagSet argument
// corresponds to a value in conf then the default value will be
// whatever is defined by the FlagSet method.
ArgDefsSetter func(conf *T, fs *flag.FlagSet) error
}
Generated by gomarkdoc
To build the build system:
go build -o ./bs/bs ./bs
The build system can then be used as usual:
./bs/bs --help
./bs/bs buildbs # Builds the build system!