diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 5f0ef30..2f2112a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,7 +12,7 @@ on:
jobs:
test:
name: Test
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
diff --git a/README.md b/README.md
index 7e8b776..b7eb9f3 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,14 @@
# broccli
-[](https://pkg.go.dev/gopkg.pl/phings/broccli/v2) [](https://goreportcard.com/report/gopkg.pl/phings/broccli/v2)
+[](https://pkg.go.dev/gopkg.pl/phings/broccli/v3) [](https://goreportcard.com/report/gopkg.pl/phings/broccli/v3)
----
-The `phings/broccli` package simplifies command line interface management. It allows you to define commands complete with arguments and flags, and attach handlers to them. The package handles all the parsing automatically.
+The `phings/broccli/v3` package simplifies command line interface management. It allows you to define commands complete with arguments and flags, and attach handlers to them. The package handles all the parsing automatically.
+
+
+:warning: `v3` is not compatible with `v2`. The latest version requires a context in handlers and when calling `Run` method. Also
+methods for adding commands, args etc. have been shortened to `Command`, `Arg`, `Flag` and `Env`.
----
@@ -26,17 +30,17 @@ However, the following code snippet from another tiny project shows how the modu
Import the code with the following URL:
```go
-import "gopkg.pl/phings/broccli/v2"
+import "gopkg.pl/phings/broccli/v3"
```
```go
// create new CLI object
-cli := broccli.NewCLI("snakey-letters", "Classic snake but with letters and words!", "")
+cli := broccli.NewBroccli("snakey-letters", "Classic snake but with letters and words!", "")
// add a command and attach a function to it
-cmd := cli.AddCmd("start", "Starts the game", startHandler)
+cmd := cli.Command("start", "Starts the game", startHandler)
// add a flag to the command
-cmd.AddFlag("words", "f", "",
+cmd.Flag("words", "f", "",
"Text file with wordlist",
// should be a path to a file
broccli.TypePathFile,
@@ -45,39 +49,39 @@ cmd.AddFlag("words", "f", "",
)
// add another command to print version number
-_ = cli.AddCmd("version", "Shows version", versionHandler)
+_ = cli.Command("version", "Shows version", versionHandler)
// run cli
-os.Exit(cli.Run())
+os.Exit(cli.Run(context.Background()))
// handlers for each command
-func startHandler(c *broccli.CLI) int {
+func startHandler(ctx context.Context, c *broccli.CLI) int {
fmt.Fprint(os.Stdout, "Starting with file %s...", c.Flag("words"))
return 0
}
-func versionHandler(c *broccli.CLI) int {
+func versionHandler(ctx context.Context, c *broccli.CLI) int {
fmt.Fprintf(os.Stdout, VERSION+"\n")
return 0
}
```
## Structs explained
-### CLI
-The main `CLI` object has three arguments such as name, description and author. These guys are displayed when syntax is printed out.
+### Broccli
+The main `Broccli` object has three arguments such as name, usage and author. These guys are displayed when syntax is printed out.
### Commands
Method `AddCmd` creates a new command which has the following properties.
* a `name`, used to call it
-* short `description` - few words to display what the command does on the syntax screen
+* short `usage` - few words to display what the command does on the syntax screen
* `handler` function that is executed when the command is called and all its flags and argument are valid
#### Command Options
Optionally, after command flags and arguments are successfully validated, and just before the execution of `handler`, additional code (func) can be executed. This can be passed as a last argument.
```go
-cmd := cli.AddCmd("start", "Starts the game", startHandler,
+cmd := cli.Command("start", "Starts the game", startHandler,
broccli.OnPostValidation(func(c *broccli.Cmd) {
// do something, even with the command
}),
@@ -97,16 +101,16 @@ To setup a flag in a command, method `AddFlag` is used. It takes the following a
* `name` and `alias` that are used to call the flag (eg. `--help` and `-h`, without the hyphens in the func args)
* `valuePlaceholder`, a placeholder that is printed out on the syntax screen, eg. in `-f PATH_TO_FILE` it is the `PATH_TO_FILE`
-* `description` - few words telling what the command does (syntax screen again)
+* `usage` - few words telling what the command does (syntax screen again)
* `types`, an int64 value that defines the value type, currently one of `TypeString`, `TypeBool`, `TypeInt`, `TypeFloat`, `TypeAlphanumeric` or `TypePathFile` (see `flags.go` for more information)
* `flags`, an int64 value containing validation requirement, eg. `IsRequired|IsExistent|IsDirectory` could be used with `TypePathFile` to require the flag to be a non-empty path to an existing directory (again, navigate to `flags.go` for more detailed information)
Optionally, a function can be attached to a boolean flag that is triggered when a flag is true. The motivation behind that was a use case when setting a certain flag to true would make another string flag required. However, it's not recommended to be used.
-To add an argument for a command, method `AddArg` shall be used. It has almost the same arguments, apart from the fact that `alias` is not there.
+To add an argument for a command, method `Arg` shall be used. It has almost the same arguments, apart from the fact that `alias` is not there.
### Environment variables to check
-Command may require environment variables. `AddEnvVar` can be called to setup environment variables that should be verified before running the command. For example, a variable might need to contain a path to an existing regular file.
+Command may require environment variables. `Env` can be called to setup environment variables that should be verified before running the command. For example, a variable might need to contain a path to an existing regular file.
### Accessing flag and arg values
See sample code that does that below.
@@ -129,3 +133,4 @@ func startHandler(c *broccli.CLI) int {
- [X] Check for file existence and its type (can be directory, regular file or other)
- [X] Post validation hook
- [X] Boolean flag on-true hook before validation
+- [X] Handlers require context
diff --git a/cli.go b/cli.go
index 390dcd1..d2c4d6f 100644
--- a/cli.go
+++ b/cli.go
@@ -1,9 +1,10 @@
package broccli
import (
+ "context"
"flag"
"fmt"
- "io/ioutil"
+ "io"
"os"
"path"
"reflect"
@@ -11,96 +12,96 @@ import (
"text/tabwriter"
)
-// CLI is main CLI application definition.
+// Broccli is main CLI application definition.
// It has a name, description, author which are printed out to the screen in the usage syntax.
-// Each CLI have commands (represented by Cmd). Optionally, it is possible to require environment
+// Each CLI have commands (represented by Command). Optionally, it is possible to require environment
// variables.
-type CLI struct {
+type Broccli struct {
name string
- desc string
+ usage string
author string
- cmds map[string]*Cmd
- envVars map[string]*param
+ commands map[string]*Command
+ env map[string]*param
parsedFlags map[string]string
parsedArgs map[string]string
}
-// NewCLI returns pointer to a new CLI instance. Name, description and author are displayed on the syntax screen.
-func NewCLI(name string, description string, author string) *CLI {
- c := &CLI{
+// NewBroccli returns pointer to a new Broccli instance. Name, usage and author are displayed on the syntax screen.
+func NewBroccli(name, usage, author string) *Broccli {
+ c := &Broccli{
name: name,
- desc: description,
+ usage: usage,
author: author,
- cmds: map[string]*Cmd{},
- envVars: map[string]*param{},
+ commands: map[string]*Command{},
+ env: map[string]*param{},
parsedFlags: map[string]string{},
parsedArgs: map[string]string{},
}
return c
}
-// AddCmd returns pointer to a new command with specified name, description and handler. Handler is a function that
+// Command returns pointer to a new command with specified name, usage and handler. Handler is a function that
// gets called when command is executed.
-// Additionally, there is a set of options that can be passed as arguments. Search for cmdOption for more info.
-func (c *CLI) AddCmd(name string, description string, handler func(cli *CLI) int, opts ...cmdOption) *Cmd {
- c.cmds[name] = &Cmd{
+// Additionally, there is a set of options that can be passed as arguments. Search for commandOption for more info.
+func (c *Broccli) Command(name, usage string, handler func(ctx context.Context, cli *Broccli) int, opts ...commandOption) *Command {
+ c.commands[name] = &Command{
name: name,
- desc: description,
+ usage: usage,
flags: map[string]*param{},
args: map[string]*param{},
- envVars: map[string]*param{},
+ env: map[string]*param{},
handler: handler,
- options: cmdOptions{},
+ options: commandOptions{},
}
for _, o := range opts {
- o(&(c.cmds[name].options))
+ o(&(c.commands[name].options))
}
- return c.cmds[name]
+ return c.commands[name]
}
-// AddEnvVar returns pointer to a new environment variable that is required to run every command.
-// Method requires name, eg. MY_VAR, and description.
-func (c *CLI) AddEnvVar(name string, description string) {
- c.envVars[name] = ¶m{
+// Env returns pointer to a new environment variable that is required to run every command.
+// Method requires name, eg. MY_VAR, and usage.
+func (c *Broccli) Env(name string, usage string) {
+ c.env[name] = ¶m{
name: name,
- desc: description,
+ usage: usage,
flags: IsRequired,
options: paramOptions{},
}
}
// Flag returns value of flag.
-func (c *CLI) Flag(name string) string {
+func (c *Broccli) Flag(name string) string {
return c.parsedFlags[name]
}
// Arg returns value of arg.
-func (c *CLI) Arg(name string) string {
+func (c *Broccli) Arg(name string) string {
return c.parsedArgs[name]
}
// Run parses the arguments, validates them and executes command handler.
// In case of invalid arguments, error is printed to stderr and 1 is returned. Return value should be treated as exit
// code.
-func (c *CLI) Run() int {
+func (c *Broccli) Run(ctx context.Context) int {
// display help, first arg is binary filename
if len(os.Args) < 2 || os.Args[1] == "-h" || os.Args[1] == "--help" {
c.printHelp()
return 0
}
- for _, n := range c.sortedCmds() {
+ for _, n := range c.sortedCommands() {
if n != os.Args[1] {
continue
}
// display command help
if len(os.Args) > 2 && (os.Args[2] == "-h" || os.Args[2] == "--help") {
- c.cmds[n].printHelp()
+ c.commands[n].printHelp()
return 0
}
// check required environment variables
- if len(c.envVars) > 0 {
- for env, param := range c.envVars {
+ if len(c.env) > 0 {
+ for env, param := range c.env {
v := os.Getenv(env)
param.flags = param.flags | IsRequired
err := param.validateValue(v)
@@ -113,21 +114,21 @@ func (c *CLI) Run() int {
}
// parse and validate all the flags and args
- exitCode := c.parseFlags(c.cmds[n])
+ exitCode := c.parseFlags(c.commands[n])
if exitCode > 0 {
return exitCode
}
- return c.cmds[n].handler(c)
+ return c.commands[n].handler(ctx, c)
}
// command not found
- c.printInvalidCmd(os.Args[1])
+ c.printInvalidCommand(os.Args[1])
return 1
}
-func (c *CLI) sortedCmds() []string {
- cmds := reflect.ValueOf(c.cmds).MapKeys()
+func (c *Broccli) sortedCommands() []string {
+ cmds := reflect.ValueOf(c.commands).MapKeys()
scmds := make([]string, len(cmds))
for i, cmd := range cmds {
scmds[i] = cmd.String()
@@ -136,8 +137,8 @@ func (c *CLI) sortedCmds() []string {
return scmds
}
-func (c *CLI) sortedEnvVars() []string {
- evs := reflect.ValueOf(c.envVars).MapKeys()
+func (c *Broccli) sortedEnv() []string {
+ evs := reflect.ValueOf(c.env).MapKeys()
sevs := make([]string, len(evs))
for i, ev := range evs {
sevs[i] = ev.String()
@@ -146,16 +147,16 @@ func (c *CLI) sortedEnvVars() []string {
return sevs
}
-func (c *CLI) printHelp() {
- fmt.Fprintf(os.Stdout, "%s by %s\n%s\n\n", c.name, c.author, c.desc)
+func (c *Broccli) printHelp() {
+ fmt.Fprintf(os.Stdout, "%s by %s\n%s\n\n", c.name, c.author, c.usage)
fmt.Fprintf(os.Stdout, "Usage: %s COMMAND\n\n", path.Base(os.Args[0]))
- if len(c.envVars) > 0 {
+ if len(c.env) > 0 {
fmt.Fprintf(os.Stdout, "Required environment variables:\n")
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
- for _, n := range c.sortedEnvVars() {
- fmt.Fprintf(w, "%s\t%s\n", n, c.envVars[n].desc)
+ for _, n := range c.sortedEnv() {
+ fmt.Fprintf(w, "%s\t%s\n", n, c.env[n].usage)
}
w.Flush()
}
@@ -163,25 +164,25 @@ func (c *CLI) printHelp() {
fmt.Fprintf(os.Stdout, "Commands:\n")
w := new(tabwriter.Writer)
w.Init(os.Stdout, 10, 8, 0, '\t', 0)
- for _, n := range c.sortedCmds() {
- fmt.Fprintf(w, " %s\t%s\n", n, c.cmds[n].desc)
+ for _, n := range c.sortedCommands() {
+ fmt.Fprintf(w, " %s\t%s\n", n, c.commands[n].usage)
}
w.Flush()
fmt.Fprintf(os.Stdout, "\nRun '%s COMMAND --help' for command syntax.\n", path.Base(os.Args[0]))
}
-func (c *CLI) printInvalidCmd(cmd string) {
+func (c *Broccli) printInvalidCommand(cmd string) {
fmt.Fprintf(os.Stderr, "Invalid command: %s\n\n", cmd)
c.printHelp()
}
// getFlagSetPtrs creates flagset instance, parses flags and returns list of pointers to results of parsing the flags.
-func (c *CLI) getFlagSetPtrs(cmd *Cmd) (map[string]interface{}, map[string]interface{}, []string) {
+func (c *Broccli) getFlagSetPtrs(cmd *Command) (map[string]interface{}, map[string]interface{}, []string) {
fset := flag.NewFlagSet("flagset", flag.ContinueOnError)
// nothing should come out of flagset
fset.Usage = func() {}
- fset.SetOutput(ioutil.Discard)
+ fset.SetOutput(io.Discard)
nameFlags := make(map[string]interface{})
aliasFlags := make(map[string]interface{})
@@ -200,12 +201,12 @@ func (c *CLI) getFlagSetPtrs(cmd *Cmd) (map[string]interface{}, map[string]inter
return nameFlags, aliasFlags, fset.Args()
}
-func (c *CLI) checkEnvVars(cmd *Cmd) int {
- if len(cmd.envVars) == 0 {
+func (c *Broccli) checkEnv(cmd *Command) int {
+ if len(cmd.env) == 0 {
return 0
}
- for env, envVar := range cmd.envVars {
+ for env, envVar := range cmd.env {
v := os.Getenv(env)
envVar.flags = envVar.flags | IsRequired
err := envVar.validateValue(v)
@@ -219,7 +220,7 @@ func (c *CLI) checkEnvVars(cmd *Cmd) int {
return 0
}
-func (c *CLI) processOnTrue(cmd *Cmd, fs []string, nflags map[string]interface{}, aflags map[string]interface{}) {
+func (c *Broccli) processOnTrue(cmd *Command, fs []string, nflags map[string]interface{}, aflags map[string]interface{}) {
for _, name := range fs {
if cmd.flags[name].valueType != TypeBool {
continue
@@ -236,7 +237,7 @@ func (c *CLI) processOnTrue(cmd *Cmd, fs []string, nflags map[string]interface{}
}
}
-func (c *CLI) processFlags(cmd *Cmd, fs []string, nflags map[string]interface{}, aflags map[string]interface{}) int {
+func (c *Broccli) processFlags(cmd *Command, fs []string, nflags map[string]interface{}, aflags map[string]interface{}) int {
for _, name := range fs {
flag := cmd.flags[name]
@@ -272,7 +273,7 @@ func (c *CLI) processFlags(cmd *Cmd, fs []string, nflags map[string]interface{},
return 0
}
-func (c *CLI) processArgs(cmd *Cmd, as []string, args []string) int {
+func (c *Broccli) processArgs(cmd *Command, as []string, args []string) int {
for i, n := range as {
v := ""
if len(args) >= i+1 {
@@ -292,7 +293,7 @@ func (c *CLI) processArgs(cmd *Cmd, as []string, args []string) int {
return 0
}
-func (c *CLI) processOnPostValidation(cmd *Cmd) int {
+func (c *Broccli) processOnPostValidation(cmd *Command) int {
if cmd.options.onPostValidation == nil {
return 0
}
@@ -307,9 +308,9 @@ func (c *CLI) processOnPostValidation(cmd *Cmd) int {
return 0
}
-func (c *CLI) parseFlags(cmd *Cmd) int {
+func (c *Broccli) parseFlags(cmd *Command) int {
// check required environment variables
- if exitCode := c.checkEnvVars(cmd); exitCode != 0 {
+ if exitCode := c.checkEnv(cmd); exitCode != 0 {
return exitCode
}
@@ -337,7 +338,7 @@ func (c *CLI) parseFlags(cmd *Cmd) int {
return 0
}
-func (c *CLI) getParamTypeName(t int8) string {
+func (c *Broccli) getParamTypeName(t int8) string {
if t == ParamArg {
return "Argument"
}
diff --git a/cli_test.go b/cli_test.go
index 092530b..24465c0 100644
--- a/cli_test.go
+++ b/cli_test.go
@@ -1,6 +1,7 @@
package broccli
import (
+ "context"
"fmt"
"io"
"log"
@@ -25,54 +26,54 @@ func TestCLI(t *testing.T) {
os.Stdout = devNull
os.Stderr = devNull
- c := NewCLI("Example", "App", "Author ")
- cmd1 := c.AddCmd("cmd1", "Prints out a string", func(c *CLI) int {
+ c := NewBroccli("Example", "App", "Author ")
+ cmd1 := c.Command("cmd1", "Prints out a string", func(ctx context.Context, c *Broccli) int {
fmt.Fprintf(f, "TESTVALUE:%s%s\n\n", c.Flag("tekst"), c.Flag("alphanumdots"))
if c.Flag("bool") == "true" {
fmt.Fprintf(f, "BOOL:true")
}
return 2
})
- cmd1.AddFlag("tekst", "t", "Text", "Text to print", TypeString, IsRequired)
- cmd1.AddFlag("alphanumdots", "a", "Alphanum with dots", "Can have dots", TypeAlphanumeric, AllowDots)
- cmd1.AddFlag("make-required", "r", "", "Make alphanumdots required", TypeBool, 0, OnTrue(func(c *Cmd) {
+ cmd1.Flag("tekst", "t", "Text", "Text to print", TypeString, IsRequired)
+ cmd1.Flag("alphanumdots", "a", "Alphanum with dots", "Can have dots", TypeAlphanumeric, AllowDots)
+ cmd1.Flag("make-required", "r", "", "Make alphanumdots required", TypeBool, 0, OnTrue(func(c *Command) {
c.flags["alphanumdots"].flags = c.flags["alphanumdots"].flags | IsRequired
}))
// Boolean should work fine even when the optional OnTrue is not passed
- cmd1.AddFlag("bool", "b", "", "Bool value", TypeBool, 0)
+ cmd1.Flag("bool", "b", "", "Bool value", TypeBool, 0)
os.Args = []string{"test", "cmd1"}
- got := c.Run()
+ got := c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}
os.Args = []string{"test", "cmd1", "-t", ""}
- got = c.Run()
+ got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}
os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots"}
- got = c.Run()
+ got = c.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}
os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "-r"}
- got = c.Run()
+ got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}
os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots", "aZ0-9"}
- got = c.Run()
+ got = c.Run(context.Background())
if got != 1 {
t.Errorf("CLI.Run() should have returned 1 instead of %d", got)
}
os.Args = []string{"test", "cmd1", "--tekst", "Tekst123", "--alphanumdots", "aZ0.9", "-b"}
- got = c.Run()
+ got = c.Run(context.Background())
if got != 2 {
t.Errorf("CLI.Run() should have returned 2 instead of %d", got)
}
diff --git a/cmd.go b/cmd.go
index 1857be3..10130bf 100644
--- a/cmd.go
+++ b/cmd.go
@@ -1,6 +1,7 @@
package broccli
import (
+ "context"
"fmt"
"log"
"os"
@@ -10,32 +11,32 @@ import (
"text/tabwriter"
)
-// Cmd represent a command which has a name (used in args when calling app), description, a handler that is called.
+// Command represent a command which has a name (used in args when calling app), usage, a handler that is called.
// Such command can have flags and arguments. In addition to that, required environment variables can be set.
-type Cmd struct {
+type Command struct {
name string
- desc string
+ usage string
flags map[string]*param
args map[string]*param
argsOrder []string
argsIdx int
- envVars map[string]*param
- handler func(*CLI) int
- options cmdOptions
+ env map[string]*param
+ handler func(context.Context, *Broccli) int
+ options commandOptions
}
-// AddFlag adds a flag to a command and returns a pointer to Param instance.
+// Flag adds a flag to a command and returns a pointer to Param instance.
// Method requires name (eg. 'data' for '--data', alias (eg. 'd' for '-d'), placeholder for the value displayed on the
-// 'help' screen, description, type of the value and additional validation that is set up with bit flags, eg. IsRequired
+// 'help' screen, usage, type of the value and additional validation that is set up with bit flags, eg. IsRequired
// or AllowMultipleValues. If no additional flags are required, 0 should be used.
-func (c *Cmd) AddFlag(name string, alias string, valuePlaceholder string, description string, types int64, flags int64, opts ...paramOption) {
+func (c *Command) Flag(name, alias, valuePlaceholder, usage string, types, flags int64, opts ...paramOption) {
if c.flags == nil {
c.flags = map[string]*param{}
}
c.flags[name] = ¶m{
name: name,
alias: alias,
- desc: description,
+ usage: usage,
valuePlaceholder: valuePlaceholder,
valueType: types,
flags: flags,
@@ -46,9 +47,9 @@ func (c *Cmd) AddFlag(name string, alias string, valuePlaceholder string, descri
}
}
-// AddArg adds an argument to a command and returns a pointer to Param instance. It is the same as adding flag except
+// Arg adds an argument to a command and returns a pointer to Param instance. It is the same as adding flag except
// it does not have an alias.
-func (c *Cmd) AddArg(name string, valuePlaceholder string, description string, types int64, flags int64, opts ...paramOption) {
+func (c *Command) Arg(name, valuePlaceholder, usage string, types, flags int64, opts ...paramOption) {
if c.argsIdx > 9 {
log.Fatal("Only 10 arguments are allowed")
}
@@ -57,7 +58,7 @@ func (c *Cmd) AddArg(name string, valuePlaceholder string, description string, t
}
c.args[name] = ¶m{
name: name,
- desc: description,
+ usage: usage,
valuePlaceholder: valuePlaceholder,
valueType: types,
flags: flags,
@@ -73,22 +74,22 @@ func (c *Cmd) AddArg(name string, valuePlaceholder string, description string, t
}
}
-// AddEnvVar adds a required environment variable to a command and returns a pointer to Param. It's arguments are very
+// Env adds a required environment variable to a command and returns a pointer to Param. It's arguments are very
// similar to ones in previous AddArg and AddFlag methods.
-func (c *Cmd) AddEnvVar(name string, description string, types int64, flags int64, opts ...paramOption) {
- if c.envVars == nil {
- c.envVars = map[string]*param{}
+func (c *Command) Env(name, usage string, types, flags int64, opts ...paramOption) {
+ if c.env == nil {
+ c.env = map[string]*param{}
}
- c.envVars[name] = ¶m{
+ c.env[name] = ¶m{
name: name,
- desc: description,
+ usage: usage,
valueType: types,
flags: flags,
options: paramOptions{},
}
}
-func (c *Cmd) sortedArgs() []string {
+func (c *Command) sortedArgs() []string {
args := make([]string, c.argsIdx)
idx := 0
for i := 0; i < c.argsIdx; i++ {
@@ -110,7 +111,7 @@ func (c *Cmd) sortedArgs() []string {
return args
}
-func (c *Cmd) sortedFlags() []string {
+func (c *Command) sortedFlags() []string {
fs := reflect.ValueOf(c.flags).MapKeys()
sfs := make([]string, len(fs))
for i, f := range fs {
@@ -120,8 +121,8 @@ func (c *Cmd) sortedFlags() []string {
return sfs
}
-func (c *Cmd) sortedEnvVars() []string {
- evs := reflect.ValueOf(c.envVars).MapKeys()
+func (c *Command) sortedEnv() []string {
+ evs := reflect.ValueOf(c.env).MapKeys()
sevs := make([]string, len(evs))
for i, ev := range evs {
sevs[i] = ev.String()
@@ -131,17 +132,17 @@ func (c *Cmd) sortedEnvVars() []string {
}
// PrintHelp prints command usage information to stdout file.
-func (c *Cmd) printHelp() {
+func (c *Command) printHelp() {
fmt.Fprintf(os.Stdout, "\nUsage: %s %s [FLAGS]%s\n\n", path.Base(os.Args[0]), c.name,
c.argsHelpLine())
- fmt.Fprintf(os.Stdout, "%s\n", c.desc)
+ fmt.Fprintf(os.Stdout, "%s\n", c.usage)
- if len(c.envVars) > 0 {
+ if len(c.env) > 0 {
fmt.Fprintf(os.Stdout, "\nRequired environment variables:\n")
w := new(tabwriter.Writer)
w.Init(os.Stdout, 8, 8, 0, '\t', 0)
- for _, n := range c.sortedEnvVars() {
- fmt.Fprintf(w, "%s\t%s\n", n, c.envVars[n].desc)
+ for _, n := range c.sortedEnv() {
+ fmt.Fprintf(w, "%s\t%s\n", n, c.env[n].usage)
}
w.Flush()
}
@@ -174,7 +175,7 @@ func (c *Cmd) printHelp() {
}
-func (c *Cmd) argsHelpLine() string {
+func (c *Command) argsHelpLine() string {
sr := ""
so := ""
if c.argsIdx > 0 {
diff --git a/cmd_options.go b/cmd_options.go
index e10c2f1..d5e18c4 100644
--- a/cmd_options.go
+++ b/cmd_options.go
@@ -1,13 +1,13 @@
package broccli
-type cmdOptions struct {
- onPostValidation func(c *Cmd) error
+type commandOptions struct {
+ onPostValidation func(c *Command) error
}
-type cmdOption func(opts *cmdOptions)
+type commandOption func(opts *commandOptions)
-func OnPostValidation(fn func(c *Cmd) error) cmdOption {
- return func(opts *cmdOptions) {
+func OnPostValidation(fn func(c *Command) error) commandOption {
+ return func(opts *commandOptions) {
opts.onPostValidation = fn
}
}
diff --git a/cmd_test.go b/cmd_test.go
index 56972fe..de4dbc5 100644
--- a/cmd_test.go
+++ b/cmd_test.go
@@ -5,21 +5,21 @@ import (
"testing"
)
-// TestCmdParams creates a dummy Cmd instance and tests attaching flags, args and environment variables.
-func TestCmdParams(t *testing.T) {
- c := &Cmd{}
- c.AddFlag("flag1", "f1", "int", "Flag 1", TypeInt, IsRequired)
- c.AddFlag("flag2", "f2", "path", "Flag 2", TypePathFile, IsRegularFile)
- c.AddFlag("flag3", "f3", "", "Flag 3", TypeBool, 0, OnTrue(func(c *Cmd) {
+// TestCommandParams creates a dummy Command instance and tests attaching flags, args and environment variables.
+func TestCommandParams(t *testing.T) {
+ c := &Command{}
+ c.Flag("flag1", "f1", "int", "Flag 1", TypeInt, IsRequired)
+ c.Flag("flag2", "f2", "path", "Flag 2", TypePathFile, IsRegularFile)
+ c.Flag("flag3", "f3", "", "Flag 3", TypeBool, 0, OnTrue(func(c *Command) {
c.flags["flag2"].flags = c.flags["flag2"].flags | IsExistent
}))
- c.AddArg("arg1", "ARG1", "Arg 1", TypeInt, IsRequired)
- c.AddArg("arg2", "ARG2", "Arg 2", TypeAlphanumeric, 0)
- c.AddEnvVar("ENVVAR1", "Env var 1", TypeInt, 0)
+ c.Arg("arg1", "ARG1", "Arg 1", TypeInt, IsRequired)
+ c.Arg("arg2", "ARG2", "Arg 2", TypeAlphanumeric, 0)
+ c.Env("ENVVAR1", "Env var 1", TypeInt, 0)
sa := c.sortedArgs()
sf := c.sortedFlags()
- se := c.sortedEnvVars()
+ se := c.sortedEnv()
if len(sa) != 2 || len(sf) != 3 || len(se) != 1 {
t.Errorf("Invalid args or flags or env vars added")
diff --git a/go.mod b/go.mod
index 8d47e16..34e1e39 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
-module gopkg.pl/phings/broccli/v2
+module gopkg.pl/phings/broccli/v3
go 1.22.1
diff --git a/param.go b/param.go
index 9c6735f..9a19dfe 100644
--- a/param.go
+++ b/param.go
@@ -9,7 +9,7 @@ import (
)
// param represends a value and it is used for flags, args and environment variables.
-// It has a name, alias, description, value that is shown when printing help, specific type (eg. TypeBool or TypeInt),
+// It has a name, alias, usage, value that is shown when printing help, specific type (eg. TypeBool or TypeInt),
// If more than one value shoud be allowed, eg. '1,2,3' means "multiple integers" and the separator here is ','.
// Additional characters are used with type of TypeAlphanumeric to allow dots, underscore etc. Hence, the value of that
// arg could be '._-'.
@@ -17,7 +17,7 @@ type param struct {
name string
alias string
valuePlaceholder string
- desc string
+ usage string
valueType int64
flags int64
options paramOptions
@@ -31,7 +31,7 @@ func (p *param) helpLine() string {
} else {
s += fmt.Sprintf(" -%s,\t", p.alias)
}
- s += fmt.Sprintf(" --%s %s \t%s\n", p.name, p.valuePlaceholder, p.desc)
+ s += fmt.Sprintf(" --%s %s \t%s\n", p.name, p.valuePlaceholder, p.usage)
return s
}
diff --git a/param_options.go b/param_options.go
index 87a94d5..359fc20 100644
--- a/param_options.go
+++ b/param_options.go
@@ -1,12 +1,12 @@
package broccli
type paramOptions struct {
- onTrue func(c *Cmd)
+ onTrue func(c *Command)
}
type paramOption func(opts *paramOptions)
-func OnTrue(fn func(c *Cmd)) paramOption {
+func OnTrue(fn func(c *Command)) paramOption {
return func(opts *paramOptions) {
opts.onTrue = fn
}
diff --git a/param_test.go b/param_test.go
index 0545f50..7a94e51 100644
--- a/param_test.go
+++ b/param_test.go
@@ -6,7 +6,7 @@ import (
"testing"
)
-func h(c *CLI) int {
+func h(c *Broccli) int {
return 0
}
diff --git a/version.go b/version.go
index c2fa2f5..8286ce6 100644
--- a/version.go
+++ b/version.go
@@ -1,3 +1,3 @@
package broccli
-const VERSION = "2.2.3"
+const VERSION = "3.0.0"