https://github.com/youta-t/flarc
commandline parser, supporting flag, args, and subcommands
https://github.com/youta-t/flarc
argparser commandlineparser flags flarc go golang
Last synced: 13 days ago
JSON representation
commandline parser, supporting flag, args, and subcommands
- Host: GitHub
- URL: https://github.com/youta-t/flarc
- Owner: youta-t
- License: mit
- Created: 2024-02-25T01:38:36.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-25T11:24:34.000Z (almost 2 years ago)
- Last Synced: 2024-02-28T02:25:45.946Z (almost 2 years ago)
- Topics: argparser, commandlineparser, flags, flarc, go, golang
- Language: Go
- Homepage:
- Size: 25.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
flarc -- commandline parser, supports flag, arg, subcommands
============================================================
flarc is a commandline parser. With flarc, you can
- declare *fl*ags, gnu style (short option `-f` and long option `--flag`)
- declare positional *ar*guments, and
- declare sub*c*ommands
- get generated help texts
Install
--------
```
go get github.com/youta-t/flarc
```
flarc needs go1.21+.
Usage
------
### Define command
```go
// ...
import "github.com/youta-t/flarc"
// ...
// declare struct for flags.
// Flag options can be set with tag.
//
// Recognized tag keys are:
//
// - flag: flag name. by default, field-name-in-kebab-case.
// - alias: aliases of the flag.
// - help: help message.
// - metavar: value example in Usage section in help.
// By default, the default value of the flag is used.
//
type Flag struct {
Foo string `alias:"f" help:"flag foo" metavar:"FOO"`
Bar int // when no tag, assumed as `flag:"${field-name-in-kebab-case}"` is given.
Fizz bool `flag:"F"` // flag name is case sensitive
Bazz time.Duration `metavar:"DURATION"`
}
func main() {
// ...
cmd, err := flarc.NewCommand(
"short description...",
// declare default values for flags
Flag{
Foo: "default foo",
Bar: 42,
Fizz: false,
Bazz: 3 * time.Second,
},
// declare positional args
flarc.Args{
{
Name: "SOURCE", // positional arg name
Repeatable: true, // set true if this arg takes many items
Required: true, // require at least 1 item
Help: "help message of SOURCE",
},
{
Name: "DEST", Required: true,
Help: "help message of DEST",
},
},
func(
ctx context.Context,
commandline flarc.Commandline[Flag],
param []any,
) error {
// parsed flag
var flag Flag = commandline.Flags()
// key is arg's name. values are assigned commandline
var args map[string][]string = commandline.Args()
buf := make([]byte, 1024)
io.ReadAtLeast(commandline.Stdin(), buf, 0)
fmt.Fprintf(commandline.Stdout(), "passed flag: %+v\n\n", flag)
fmt.Fprintf(commandline.Stdout(), "passed arg: %+v\n\n", args)
fmt.Fprintf(commandline.Stdout(), "passed params: %+v\n\n", param)
return nil
},
// Description is template.
// Placeholder {{ .Command }} will be replaced with command name at runtime.
flarc.WithDescription(`this is example command.
To show how to declare flags and args, also genereatad help message.
This command is called "{{ .Command }}"
`),
)
if err != nil {
fmt.Fprintln(os.Stderr, "unexpected error:", err)
os.Exit(1)
}
// ...
}
```
### Run command
```go
func main() {
// ...
ctx, cancel := signal.NotifyContext(
context.Background(), os.Interrupt,
)
defer cancel()
type param struct {
ParamValue string
}
os.Exit(flarc.Run(
ctx, cmd,
// (optional) extra params.
//
// For example, loggers can be injected with this.
flarc.WithParams([]any{param{ParamValue: "this is param value"}}),
))
}
```
Return status is selected by flarc.
If the task of command returns,
- `nil`: success! exits with `0`.
- `flarc.ErrUsage`: prints help message and exits with `2`.
- other error: exits with `1`.
```
$ go run ./example/example_command -f foo -F false source1 source2 dest1
passed flag: {Foo:foo Bar:42 Fizz:false Bazz:3s}
passed arg: map[DEST:[dest1] SOURCE:[source1 source2]]
passed params: [{ParamValue:this is param value}]
```
By default, flarc provides `--help, -h` flag to show help message.
```
$ go run ./example/example_command --help
example_command -- short description...
Usage:
example_command --foo=FOO --bar=0 --fizz=false --bazz=DURATION --help=false SOURCE[, ...] DEST
Description:
this is example command.
To show how to declare flags and args, also genereatad help message.
This command is called "example_command"
Flags:
--foo, -f flag foo
--bar
--fizz, -F
--bazz
--help, -h show help message
Args:
SOURCE help message of SOURCE
DEST help message of DEST
```
### Define Command Group and Subcommand
```go
// ...
type GroupFlag struct {
Qux string `alias:"q" help:"help for command group flag"`
Quux string `alias:"Q"`
}
//...
func main() {
// ...
grp, err := flarc.NewCommandGroup(
"description of command group",
GroupFlag{
Qux: "qux",
Quux: "QUUX",
},
flarc.WithGroupDescription(`command group description.
This command is called as "{{ .Command }}".
`),
flarc.WithSubcommand("sub", cmd),
)
if err != nil {
fmt.Fprintln(os.Stderr, "unexpected error:", err)
os.Exit(1)
}
// ...
}
```
#### run it
Help for command group:
```
$ go run ./example/example_subcommand --help
example_subcommand -- description of command group
Usage:
example_subcommand --qux --quux --help=false
Description:
command group description.
This command is called as "example_subcommand".
Flags:
--qux, -q help for command group flag
--quux, -Q
--help, -h show help message
Subcommands:
sub short description...
```
Help for subcommand:
```
$ go run ./example/example_subcommand sub --help
example_subcommand sub -- short description...
Usage:
example_subcommand sub --foo=FOO --bar=0 --fizz=false --bazz=DURATION --qux --quux --help=false SOURCE[, ...] DEST
Description:
this is example command.
To show how to declare flags and args, also genereatad help message.
Flags:
--foo, -f flag foo
--bar
--fizz, -F
--bazz
--qux, -q help for command group flag
--quux, -Q
--help, -h show help message
Args:
SOURCE help message of SOURCE
DEST help message of DEST
```
```
$ go run ./example/example_subcommand sub -f foo -F false -q "queue" -Q "Queue" source1 source2 dest1
passed flag: {Foo:foo Bar:42 Fizz:false Bazz:3s}
passed arg: map[DEST:[dest1] SOURCE:[source1 source2]]
passed params: [{ParamValue:this is param value} {Qux:queue Quux:Queue}]
```