Skip to content

Commit

Permalink
strict-mode for cmdr parsing; ToggleGroup not yet; strHit; fixed …
Browse files Browse the repository at this point in the history
…wrong `GetStringSlice()`;
  • Loading branch information
hedzr committed May 23, 2019
1 parent e1bb04b commit 1cbcc93
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 140 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ A getopt-like parser of command-line options, compatible with the [getopt_long](

- Groupable commands and options/flags.

Sortable group name with `\d+\..+` format, eg:
Sortable group name with `[0-9A-Za-z]+\..+` format, eg:

`1001.c++`, `1100.golang`, `1200.java`, ….
`1001.c++`, `1100.golang`, `1200.java`, …;

`abcd.c++`, `b999.golang`, `zzzz.java`, …;

- Sortable commands and options/flags. Or sorted by alphabetic order.

Expand Down
11 changes: 11 additions & 0 deletions build_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ func buildRootCrossRefs(root *RootCommand) {
root.plainLongFlags["debug"] = root.allFlags[SysMgmtGroup]["debug"]
root.plainShortFlags["D"] = root.allFlags[SysMgmtGroup]["debug"]
}
if _, ok := root.allFlags[SysMgmtGroup]["strict-mode"]; !ok {
root.allFlags[SysMgmtGroup]["strict-mode"] = &Flag{
BaseOpt: BaseOpt{
Full: "strict-mode",
Description: "strict mode for `cmdr`.",
Hidden: true,
},
DefaultValue: false,
}
root.plainLongFlags["strict-mode"] = root.allFlags[SysMgmtGroup]["strict-mode"]
}
}

if EnableGenerateCommands {
Expand Down
30 changes: 29 additions & 1 deletion def.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ type (
Aliases []string
// group name
Group string
// to-do: Toggle Group
ToggleGroup string

owner *Command
owner *Command
strHit string

Flags []*Flag

Expand Down Expand Up @@ -158,3 +161,28 @@ var (
// ErrShouldBeStopException tips `Exec()` cancelled the following actions after `PreAction()`
ErrShouldBeStopException = errors.New("should be stop right now")
)

// GetStrictMode enables error when opt value missed. such as:
// xxx a b --prefix'' => error: prefix opt has no value specified.
// xxx a b --prefix'/' => ok.
//
// ENV: use `CMDR_APP_STRICT_MODE=true` to enable strict-mode.
// NOTE: `CMDR_APP_` prefix could be set by user (via: `EnvPrefix` && `RxxtPrefix`).
func GetStrictMode() bool {
return GetBool("app.strict-mode")
}

// GetDebugMode returns the flag value of `--debug`/`-D`
func GetDebugMode() bool {
return GetBool("app.debug")
}

// GetDebugMode returns the flag value of `--verbose`/`-v`
func GetVerboseMode() bool {
return GetBool("app.verbose")
}

// GetDebugMode returns the flag value of `--quiet`/`-q`
func GetQuietMode() bool {
return GetBool("app.quiet")
}
12 changes: 6 additions & 6 deletions def_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,30 +183,30 @@ var (
"consul-tags -? -vD --vv kv backup --prefix'' -h ~~debug": func(t *testing.T) error {
if cmdr.GetInt("app.kv.port") != 8500 || cmdr.GetString("app.kv.prefix") != "" ||
!cmdr.GetBool("app.help") || !cmdr.GetBool("debug") ||
!cmdr.GetBool("app.verbose") || !cmdr.GetBool("app.debug") {
return errors.New("something wrong 2.")
!cmdr.GetVerboseMode() || !cmdr.GetDebugMode() {
return errors.New("something wrong 2")
}
return nil
},
"consul-tags -vD --vv ms tags modify --prefix'' --help ~~debug --prefix\"\" --prefix'cmdr' --prefix\"app\" --prefix=/ --prefix/ --prefix /": func(t *testing.T) error {
if cmdr.GetInt("app.ms.tags.port") != 8500 || cmdr.GetString("app.ms.tags.prefix") != "/" ||
!cmdr.GetBool("app.help") || !cmdr.GetBool("debug") ||
!cmdr.GetBool("app.verbose") || !cmdr.GetBool("app.debug") {
!cmdr.GetVerboseMode() || !cmdr.GetDebugMode() {
return fmt.Errorf("something wrong 3. |%v|%v|%v|%v|%v|%v",
cmdr.GetInt("app.ms.tags.port"), cmdr.GetString("app.ms.tags.prefix"),
cmdr.GetBool("app.help"), cmdr.GetBool("debug"),
cmdr.GetBool("app.verbose"), !cmdr.GetBool("app.debug"))
cmdr.GetVerboseMode(), cmdr.GetDebugMode())
}
return nil
},
"consul-tags -vD ms tags modify --prefix'' -? ~~debug --port8509 -p8507 -p=8506 -p 8503": func(t *testing.T) error {
if cmdr.GetInt("app.ms.tags.port") != 8503 || cmdr.GetString("app.ms.tags.prefix") != "" ||
!cmdr.GetBool("app.help") || !cmdr.GetBool("debug") ||
!cmdr.GetBool("app.verbose") || !cmdr.GetBool("app.debug") {
!cmdr.GetVerboseMode() || !cmdr.GetDebugMode() {
return fmt.Errorf("something wrong 4. |%v|%v|%v|%v|%v|%v",
cmdr.GetInt("app.ms.tags.port"), cmdr.GetString("app.ms.tags.prefix"),
cmdr.GetBool("app.help"), cmdr.GetBool("debug"),
cmdr.GetBool("app.verbose"), !cmdr.GetBool("app.debug"))
cmdr.GetVerboseMode(), cmdr.GetDebugMode())
}
return nil
},
Expand Down
7 changes: 4 additions & 3 deletions exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ func InternalExecFor(rootCmd *RootCommand, args []string) (err error) {
} else {
// command, files
if cmd, ok := goCommand.plainCmds[pkg.a]; ok {
cmd.strHit = pkg.a
goCommand = cmd
// logrus.Debugf("-- command '%v' hit, go ahead...", cmd.GetTitleName())
if cmd.PreAction != nil {
Expand Down Expand Up @@ -415,11 +416,11 @@ func preprocessPkg(pkg *ptpkg, args []string) (err error) {
pkg.val = pkg.savedFn
pkg.savedFn = ""
} else {
if pkg.i < len(args) {
if pkg.i < len(args)-1 {
pkg.i++
pkg.val = args[pkg.i]
} else {
err = fmt.Errorf("unexpect end of command line, need more args for %v", pkg)
} else if GetStrictMode() {
err = fmt.Errorf("unexpect end of command line [i=%v,args=(%v)], need more args for %v", pkg.i, args, pkg)
return
}
}
Expand Down
238 changes: 113 additions & 125 deletions generate_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

package cmdr

import "github.com/sirupsen/logrus"

var (
generatorCommands = &Command{
BaseOpt: BaseOpt{
Expand Down Expand Up @@ -67,7 +65,7 @@ var (
Full: "doc",
Aliases: []string{"markdown", "pdf"},
Description: "generate a markdown document, or: pdf/TaX/...",
// Action: genDoc,
Action: genDoc,
Flags: []*Flag{
{
BaseOpt: BaseOpt{
Expand Down Expand Up @@ -99,128 +97,118 @@ var (
},
},
},
SubCommands: []*Command{
{
BaseOpt: BaseOpt{
Short: "rt",
Full: "runtime",
Description: "runtime",
Flags: []*Flag{
{
BaseOpt: BaseOpt{
Short: "hi",
Full: "hello",
Description: "world",
},
},
{
BaseOpt: BaseOpt{
Short: "fi",
Full: "fing",
Description: "finger",
},
},
},
},
SubCommands: []*Command{
{
BaseOpt: BaseOpt{
Short: "ok",
Full: "ready",
Description: "ok ready",
Flags: []*Flag{
{
BaseOpt: BaseOpt{
Short: "a",
Full: "hello",
Description: "hello world",
},
},
{
BaseOpt: BaseOpt{
Short: "b",
Full: "fing",
Description: "ready finger",
},
},
},
},
SubCommands: []*Command{
{
BaseOpt: BaseOpt{
Short: "o1",
Full: "ready1",
Description: "ok ready 1",
Flags: []*Flag{
{
BaseOpt: BaseOpt{
Short: "a1",
Full: "hello1",
Description: "hello world",
},
},
{
BaseOpt: BaseOpt{
Short: "b1",
Full: "fing1",
Description: "ready finger",
},
},
},
},
},
{
BaseOpt: BaseOpt{
Short: "b1",
Full: "bad1",
Description: "bad not ready 1",
},
},
},
},
{
BaseOpt: BaseOpt{
Short: "b",
Full: "bad",
Description: "bad not ready",
},
},
},
},
{
BaseOpt: BaseOpt{
Short: "st",
Full: "static",
Description: "static",
Flags: []*Flag{
{
BaseOpt: BaseOpt{
Short: "hi",
Full: "hello",
Description: "world",
},
},
{
BaseOpt: BaseOpt{
Short: "fi",
Full: "fing",
Description: "finger",
},
},
},
},
},
},
// SubCommands: []*Command{
// {
// BaseOpt: BaseOpt{
// Short: "rt",
// Full: "runtime",
// Description: "runtime",
// Flags: []*Flag{
// {
// BaseOpt: BaseOpt{
// Short: "hi",
// Full: "hello",
// Description: "world",
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "fi",
// Full: "fing",
// Description: "finger",
// },
// },
// },
// },
// SubCommands: []*Command{
// {
// BaseOpt: BaseOpt{
// Short: "ok",
// Full: "ready",
// Description: "ok ready",
// Flags: []*Flag{
// {
// BaseOpt: BaseOpt{
// Short: "a",
// Full: "hello",
// Description: "hello world",
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "b",
// Full: "fing",
// Description: "ready finger",
// },
// },
// },
// },
// SubCommands: []*Command{
// {
// BaseOpt: BaseOpt{
// Short: "o1",
// Full: "ready1",
// Description: "ok ready 1",
// Flags: []*Flag{
// {
// BaseOpt: BaseOpt{
// Short: "a1",
// Full: "hello1",
// Description: "hello world",
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "b1",
// Full: "fing1",
// Description: "ready finger",
// },
// },
// },
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "b1",
// Full: "bad1",
// Description: "bad not ready 1",
// },
// },
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "b",
// Full: "bad",
// Description: "bad not ready",
// },
// },
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "st",
// Full: "static",
// Description: "static",
// Flags: []*Flag{
// {
// BaseOpt: BaseOpt{
// Short: "hi",
// Full: "hello",
// Description: "world",
// },
// },
// {
// BaseOpt: BaseOpt{
// Short: "fi",
// Full: "fing",
// Description: "finger",
// },
// },
// },
// },
// },
// },
}},
}
)

func genManual(cmd *Command, args []string) (err error) {
logrus.Infof("OK gen manul")
return
}

func genDoc(cmd *Command, args []string) (err error) {
logrus.Infof("OK gen doc")
return
}
Loading

0 comments on commit 1cbcc93

Please sign in to comment.