diff --git a/cli.go b/cli.go index 4b0788d..084adc7 100644 --- a/cli.go +++ b/cli.go @@ -8,6 +8,7 @@ import ( "github.com/jawher/mow.cli/internal/container" "github.com/jawher/mow.cli/internal/flow" + "github.com/jawher/mow.cli/model" ) /* @@ -65,6 +66,18 @@ func (cli *Cli) Version(name, version string) { cli.version = &cliVersion{version, option} } +func (cli *Cli) Model() model.App { + app := model.App{ + Command: cli.Cmd.Model(), + } + + if cli.version != nil { + app.Version = cli.version.version + } + + return app +} + func (cli *Cli) parse(args []string, entry, inFlow, outFlow *flow.Step) error { // We overload Cmd.parse() and handle cases that only apply to the CLI command, like versioning // After that, we just call Cmd.parse() for the default behavior diff --git a/commands.go b/commands.go index 2bcb335..6ba00a1 100644 --- a/commands.go +++ b/commands.go @@ -12,6 +12,7 @@ import ( "github.com/jawher/mow.cli/internal/fsm" "github.com/jawher/mow.cli/internal/lexer" "github.com/jawher/mow.cli/internal/parser" + "github.com/jawher/mow.cli/model" ) /* @@ -113,6 +114,64 @@ to execute when the command is called */ type CmdInitializer func(*Cmd) +func (c *Cmd) Model() model.Command { + if err := c.doInit(); err != nil { + panic(err) + } + + res := model.Command{ + Name: c.name, + Aliases: c.aliases, + Spec: c.Spec, + Desc: c.desc, + LongDesc: c.LongDesc, + Hidden: c.Hidden, + Options: make([]model.Option, len(c.options)), + Arguments: make([]model.Argument, len(c.args)), + Commands: make([]model.Command, len(c.commands)), + } + + for i, opt := range c.options { + var ( + shortNames []string + longNames []string + ) + + for _, n := range opt.Names { + if strings.HasPrefix(n, "--") { + longNames = append(longNames, n) + continue + } + shortNames = append(shortNames, n) + } + + res.Options[i] = model.Option{ + ShortNames: shortNames, + LongNames: longNames, + Desc: opt.Desc, + EnvVar: opt.EnvVar, + HideValue: opt.HideValue, + DefaultValue: opt.Value.String(), + } + } + + for i, arg := range c.args { + res.Arguments[i] = model.Argument{ + Name: arg.Name, + Desc: arg.Desc, + EnvVar: arg.EnvVar, + HideValue: arg.HideValue, + DefaultValue: arg.Value.String(), + } + } + + for i, cmd := range c.commands { + res.Commands[i] = cmd.Model() + } + + return res +} + /* Command adds a new (sub) command to c where name is the command name (what you type in the console), description is what would be shown in the help messages, e.g.: @@ -616,6 +675,7 @@ func formatOptNamesForHelp(o *container.Container) string { default: return "" } + } func formatValueForHelp(hide bool, v string) string { diff --git a/model/model.go b/model/model.go new file mode 100644 index 0000000..6096dbe --- /dev/null +++ b/model/model.go @@ -0,0 +1,35 @@ +package model + +type App struct { + Command + Version string +} + +type Command struct { + Name string + Aliases []string + Spec string + Desc string + LongDesc string + Hidden bool + Options []Option + Arguments []Argument + Commands []Command +} + +type Option struct { + ShortNames []string + LongNames []string + Desc string + EnvVar string + HideValue bool + DefaultValue string +} + +type Argument struct { + Name string + Desc string + EnvVar string + HideValue bool + DefaultValue string +}