From a7be2fca327abbefe1e5b1a6ca592d96bbf0a777 Mon Sep 17 00:00:00 2001 From: Yves Brissaud Date: Thu, 17 Oct 2024 12:10:05 +0200 Subject: [PATCH 1/3] refactor: extract from root command to runx package Signed-off-by: Yves Brissaud --- internal/commands/root/root.go | 293 +++++++-------------------------- internal/runx/md.go | 94 +++++++++++ internal/runx/run.go | 113 +++++++++++++ internal/runx/runx.go | 45 +++++ 4 files changed, 308 insertions(+), 237 deletions(-) create mode 100644 internal/runx/md.go create mode 100644 internal/runx/run.go create mode 100644 internal/runx/runx.go diff --git a/internal/commands/root/root.go b/internal/commands/root/root.go index c9e4c73..f084b89 100644 --- a/internal/commands/root/root.go +++ b/internal/commands/root/root.go @@ -2,15 +2,8 @@ package root import ( "context" - "errors" "fmt" - "io" - "os" - "strings" - "github.com/charmbracelet/huh" - "github.com/charmbracelet/huh/spinner" - "github.com/gertd/go-pluralize" "github.com/spf13/cobra" "github.com/docker/cli/cli" @@ -21,10 +14,9 @@ import ( "github.com/eunomie/docker-runx/internal/commands/help" "github.com/eunomie/docker-runx/internal/commands/version" "github.com/eunomie/docker-runx/internal/constants" - "github.com/eunomie/docker-runx/internal/pizza" "github.com/eunomie/docker-runx/internal/prompt" "github.com/eunomie/docker-runx/internal/registry" - "github.com/eunomie/docker-runx/internal/sugar" + "github.com/eunomie/docker-runx/internal/runx" "github.com/eunomie/docker-runx/internal/tui" "github.com/eunomie/docker-runx/runkit" ) @@ -45,95 +37,71 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { Short: "Docker Run, better", RunE: func(cmd *cobra.Command, args []string) error { var ( - src string - action string - lc = runkit.GetLocalConfig() - localCache = runkit.NewLocalCache(dockerCli) + lc = runkit.GetLocalConfig() + localCache = runkit.NewLocalCache(dockerCli) + src, action, needHelp = parseArgs(cmd.Context(), args, lc) + err error + rk *runkit.RunKit ) - switch len(args) { - case 0: - src = lc.Ref - if src == "" { - return cmd.Help() - } - case 1: - if lc.Ref == "" { - src = args[0] - } else { - // here we need to know if the argument is an image or an action - // there's no easy way, so what we'll do is to check if the argument is a reachable image - if registry.ImageExist(cmd.Context(), args[0]) { - // the image exist, let's say we override the default reference - src = args[0] - } else { - // we can't access the image, let's say it's an action - src = lc.Ref - action = args[0] - } - } - case 2: - src = args[0] - action = args[1] - default: + if needHelp { return cmd.Help() } _ = localCache.EraseNotAccessedInLast30Days() - var ( - err error - rk *runkit.RunKit - ) - - if tui.IsATTY(dockerCli.In().FD()) { - err = spinner.New(). - Type(spinner.Globe). - Title(" Fetching runx details..."). - Action(func() { - rk, err = runkit.Get(cmd.Context(), localCache, src) - if err != nil { - _, _ = fmt.Fprintln(dockerCli.Err(), err) - os.Exit(1) - } - }).Run() - } else { - rk, err = runkit.Get(cmd.Context(), localCache, src) - } + rk, err = runx.Get(cmd.Context(), dockerCli.In().FD(), localCache, src) if err != nil { return err } - if action == "" && !list && !docs && len(rk.Config.Actions) == 0 { + // in case the image only contains the readme, display it + // in this case we ignore the other flags or action as there's no action + // so we can't do anything else + if len(rk.Config.Actions) == 0 { _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(rk.Readme)) return nil } if docs { + var md string if action != "" { - _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(mdAction(rk, action))) + md = runx.MDAction(rk, action) } else { - _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(rk.Readme+"\n---\n"+mdActions(rk))) + md = runx.FullMD(rk) } + _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(md)) return nil } - action = selectAction(action, src, rk.Config.Default) + action = runx.SelectAction(action, src, rk.Config.Default) if list || action == "" { if tui.IsATTY(dockerCli.In().FD()) && len(rk.Config.Actions) > 0 { selectedAction := prompt.SelectAction(rk.Config.Actions) if selectedAction != "" { - return run(cmd.Context(), dockerCli.Err(), src, rk, selectedAction, lc) + return runx.Run(cmd.Context(), dockerCli.Err(), rk, lc, runx.RunConfig{ + Src: src, + Action: selectedAction, + ForceAsk: ask, + NoConfirm: noFlagCheck, + Opts: opts, + }) } } else { - _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(mdActions(rk))) + _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(runx.MDActions(rk))) } return nil } if action != "" { - return run(cmd.Context(), dockerCli.Err(), src, rk, action, lc) + return runx.Run(cmd.Context(), dockerCli.Err(), rk, lc, runx.RunConfig{ + Src: src, + Action: action, + ForceAsk: ask, + NoConfirm: noFlagCheck, + Opts: opts, + }) } return cmd.Help() @@ -179,105 +147,35 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { return cmd } -func getValuesLocal(src, action string) map[string]string { - localOpts := make(map[string]string) - - lc := runkit.GetLocalConfig() - img, ok := lc.Image(src) - if !ok { - return localOpts - } - - if img.AllActions.Opts != nil { - localOpts = img.AllActions.Opts - } - - act, ok := img.Actions[action] - if ok { - for k, v := range act.Opts { - localOpts[k] = v +func parseArgs(ctx context.Context, args []string, lc *runkit.LocalConfig) (src, action string, needHelp bool) { + switch len(args) { + case 0: + src = lc.Ref + if src == "" { + needHelp = true } - } - return localOpts -} - -func run(ctx context.Context, out io.Writer, src string, rk *runkit.RunKit, action string, lc *runkit.LocalConfig) error { - runnable, cleanup, err := rk.GetRunnable(action) - defer cleanup() - if err != nil { - return err - } - - localOpts := map[string]string{} - - if !ask { - localOpts = getValuesLocal(src, action) - - for _, opt := range opts { - if key, value, ok := strings.Cut(opt, "="); ok { - localOpts[key] = value + case 1: + if lc.Ref == "" { + src = args[0] + } else { + // here we need to know if the argument is an image or an action + // there's no easy way, so what we'll do is to check if the argument is a reachable image + if registry.ImageExist(ctx, args[0]) { + // the image exist, let's say we override the default reference + src = args[0] } else { - return fmt.Errorf("invalid option value %s", opt) + // we can't access the image, let's say it's an action + src = lc.Ref + action = args[0] } } + case 2: + src = args[0] + action = args[1] + default: + needHelp = true } - - options, err := prompt.Ask(runnable.Action, localOpts) - if err != nil { - return err - } - - if err = runnable.SetOptionValues(options); err != nil { - return err - } - - mdCommand := fmt.Sprintf(` -> **Running the following command:** - - %s - ---- -`, runnable.Command) - - var flags []string - if !noFlagCheck && !lc.AcceptTheRisk { - flags, err = runnable.CheckFlags() - } - if err != nil { - return err - } else if len(flags) > 0 { - _, _ = fmt.Fprintln(out, tui.Markdown(mdCommand+fmt.Sprintf(` -> **Some flags require your attention:** - -%s -`, strings.Join(pizza.Map(flags, func(flag string) string { - return fmt.Sprintf("- `%s`", flag) - }), "\n")))) - var cont bool - err = huh.NewConfirm().Title("Continue?").Value(&cont).Run() - if err != nil { - return err - } - if !cont { - return errors.New("aborted") - } - } else { - _, _ = fmt.Fprintln(out, tui.Markdown(mdCommand)) - } - - return runnable.Run(ctx) -} - -func selectAction(action, src, defaultAction string) string { - if action != "" { - return action - } - - if conf, ok := runkit.GetLocalConfig().Image(src); ok && conf.Default != "" { - return conf.Default - } - - return defaultAction + return } func commandName(isPlugin bool) string { @@ -287,82 +185,3 @@ func commandName(isPlugin bool) string { } return name } - -func mdAction(rk *runkit.RunKit, action string) string { - var ( - act runkit.Action - found bool - ) - for _, a := range rk.Config.Actions { - if a.ID == action { - found = true - act = a - break - } - } - if !found { - return fmt.Sprintf("> action %q not found\n\n%s", action, mdActions(rk)) - } - - s := strings.Builder{} - if act.Desc != "" { - s.WriteString(fmt.Sprintf("`%s`%s: %s\n", act.ID, sugar.If(act.IsDefault(), " (default)", ""), act.Desc)) - } else { - s.WriteString(fmt.Sprintf("`%s`\n", act.ID)) - } - if len(act.Env) > 0 { - s.WriteString("\n- Environment " + plural("variable", len(act.Env)) + ":\n") - for _, env := range act.Env { - s.WriteString(" - `" + env + "`\n") - } - } - if len(act.Options) > 0 { - s.WriteString("\n- " + plural("Option", len(act.Options)) + ":\n") - for _, opt := range act.Options { - s.WriteString(" - `" + opt.Name + "`" + sugar.If(opt.Description != "", ": "+opt.Description, "") + "\n") - } - } - if len(act.Shell) > 0 { - s.WriteString("\n- Shell " + plural("command", len(act.Shell)) + ":\n") - for name, cmd := range act.Shell { - s.WriteString(" - `" + name + "`: `" + cmd + "`\n") - } - } - s.WriteString("\n- " + capitalizedTypes[act.Type] + " command:\n") - s.WriteString("```\n" + act.Command + "\n```\n") - - return s.String() -} - -var capitalizedTypes = map[runkit.ActionType]string{ - runkit.ActionTypeRun: "Run", - runkit.ActionTypeBuild: "Build", -} - -func mdActions(rk *runkit.RunKit) string { - s := strings.Builder{} - s.WriteString("# Available actions\n\n") - if len(rk.Config.Actions) == 0 { - s.WriteString("> No available action\n") - } else { - for _, action := range rk.Config.Actions { - if action.Desc != "" { - s.WriteString(fmt.Sprintf(" - `%s`%s: %s\n", action.ID, sugar.If(action.IsDefault(), "(default)", ""), action.Desc)) - } else { - s.WriteString(fmt.Sprintf(" - `%s`\n", action.ID)) - } - } - - s.WriteString("\n> Use `docker runx IMAGE ACTION --docs` to get more details about an action\n") - } - - return s.String() -} - -func plural(str string, n int) string { - p := pluralize.NewClient() - if n > 1 { - return p.Plural(str) - } - return str -} diff --git a/internal/runx/md.go b/internal/runx/md.go new file mode 100644 index 0000000..eb0dd6a --- /dev/null +++ b/internal/runx/md.go @@ -0,0 +1,94 @@ +package runx + +import ( + "fmt" + "strings" + + "github.com/gertd/go-pluralize" + + "github.com/eunomie/docker-runx/internal/sugar" + "github.com/eunomie/docker-runx/runkit" +) + +func FullMD(rk *runkit.RunKit) string { + return rk.Readme + "\n---\n" + MDActions(rk) +} + +func MDAction(rk *runkit.RunKit, action string) string { + var ( + act runkit.Action + found bool + ) + for _, a := range rk.Config.Actions { + if a.ID == action { + found = true + act = a + break + } + } + if !found { + return fmt.Sprintf("> action %q not found\n\n%s", action, MDActions(rk)) + } + + s := strings.Builder{} + if act.Desc != "" { + s.WriteString(fmt.Sprintf("`%s`%s: %s\n", act.ID, sugar.If(act.IsDefault(), " (default)", ""), act.Desc)) + } else { + s.WriteString(fmt.Sprintf("`%s`\n", act.ID)) + } + if len(act.Env) > 0 { + s.WriteString("\n- Environment " + plural("variable", len(act.Env)) + ":\n") + for _, env := range act.Env { + s.WriteString(" - `" + env + "`\n") + } + } + if len(act.Options) > 0 { + s.WriteString("\n- " + plural("Option", len(act.Options)) + ":\n") + for _, opt := range act.Options { + s.WriteString(" - `" + opt.Name + "`" + sugar.If(opt.Description != "", ": "+opt.Description, "") + "\n") + } + } + if len(act.Shell) > 0 { + s.WriteString("\n- Shell " + plural("command", len(act.Shell)) + ":\n") + for name, cmd := range act.Shell { + s.WriteString(" - `" + name + "`: `" + cmd + "`\n") + } + } + s.WriteString("\n- " + capitalizedTypes[act.Type] + " command:\n") + s.WriteString("```\n" + act.Command + "\n```\n") + + return s.String() +} + +var capitalizedTypes = map[runkit.ActionType]string{ + runkit.ActionTypeRun: "Run", + runkit.ActionTypeBuild: "Build", +} + +func MDActions(rk *runkit.RunKit) string { + s := strings.Builder{} + s.WriteString("# Available actions\n\n") + if len(rk.Config.Actions) == 0 { + s.WriteString("> No available action\n") + } else { + for _, action := range rk.Config.Actions { + if action.Desc != "" { + s.WriteString(fmt.Sprintf(" - `%s`%s: %s\n", action.ID, sugar.If(action.IsDefault(), "(default)", ""), action.Desc)) + } else { + s.WriteString(fmt.Sprintf(" - `%s`\n", action.ID)) + } + } + + s.WriteString("\n> Use `docker runx IMAGE ACTION --docs` to get more details about an action\n") + } + + return s.String() +} + +func plural(str string, n int) string { + p := pluralize.NewClient() + if n > 1 { + return p.Plural(str) + } + return str +} diff --git a/internal/runx/run.go b/internal/runx/run.go new file mode 100644 index 0000000..fc3a8bd --- /dev/null +++ b/internal/runx/run.go @@ -0,0 +1,113 @@ +package runx + +import ( + "context" + "errors" + "fmt" + "io" + "strings" + + "github.com/charmbracelet/huh" + + "github.com/eunomie/docker-runx/internal/pizza" + "github.com/eunomie/docker-runx/internal/prompt" + "github.com/eunomie/docker-runx/internal/tui" + "github.com/eunomie/docker-runx/runkit" +) + +type RunConfig struct { + Src string + Action string + ForceAsk bool + NoConfirm bool + Opts []string +} + +func Run(ctx context.Context, out io.Writer, rk *runkit.RunKit, lc *runkit.LocalConfig, runConfig RunConfig) error { + runnable, cleanup, err := rk.GetRunnable(runConfig.Action) + defer cleanup() + if err != nil { + return err + } + + localOpts := map[string]string{} + + if !runConfig.ForceAsk { + localOpts = getValuesLocal(runConfig.Src, runConfig.Action) + + for _, opt := range runConfig.Opts { + if key, value, ok := strings.Cut(opt, "="); ok { + localOpts[key] = value + } else { + return fmt.Errorf("invalid option value %s", opt) + } + } + } + + options, err := prompt.Ask(runnable.Action, localOpts) + if err != nil { + return err + } + + if err = runnable.SetOptionValues(options); err != nil { + return err + } + + mdCommand := fmt.Sprintf(` +> **Running the following command:** + + %s + +--- +`, runnable.Command) + + var flags []string + if !runConfig.NoConfirm && !lc.AcceptTheRisk { + flags, err = runnable.CheckFlags() + } + if err != nil { + return err + } else if len(flags) > 0 { + _, _ = fmt.Fprintln(out, tui.Markdown(mdCommand+fmt.Sprintf(` +> **Some flags require your attention:** + +%s +`, strings.Join(pizza.Map(flags, func(flag string) string { + return fmt.Sprintf("- `%s`", flag) + }), "\n")))) + var cont bool + err = huh.NewConfirm().Title("Continue?").Value(&cont).Run() + if err != nil { + return err + } + if !cont { + return errors.New("aborted") + } + } else { + _, _ = fmt.Fprintln(out, tui.Markdown(mdCommand)) + } + + return runnable.Run(ctx) +} + +func getValuesLocal(src, action string) map[string]string { + localOpts := make(map[string]string) + + lc := runkit.GetLocalConfig() + img, ok := lc.Image(src) + if !ok { + return localOpts + } + + if img.AllActions.Opts != nil { + localOpts = img.AllActions.Opts + } + + act, ok := img.Actions[action] + if ok { + for k, v := range act.Opts { + localOpts[k] = v + } + } + return localOpts +} diff --git a/internal/runx/runx.go b/internal/runx/runx.go new file mode 100644 index 0000000..8da7d1c --- /dev/null +++ b/internal/runx/runx.go @@ -0,0 +1,45 @@ +package runx + +import ( + "context" + "errors" + + "github.com/charmbracelet/huh/spinner" + + "github.com/eunomie/docker-runx/internal/tui" + "github.com/eunomie/docker-runx/runkit" +) + +func SelectAction(action, src, defaultAction string) string { + if action != "" { + return action + } + + if conf, ok := runkit.GetLocalConfig().Image(src); ok && conf.Default != "" { + return conf.Default + } + + return defaultAction +} + +func Get(ctx context.Context, fd uintptr, localCache runkit.Cache, src string) (*runkit.RunKit, error) { + var ( + err error + rk *runkit.RunKit + ) + + if tui.IsATTY(fd) { + var getErr error + err = spinner.New(). + Type(spinner.Globe). + Title(" Fetching runx details..."). + Action(func() { + rk, getErr = runkit.Get(ctx, localCache, src) + }).Run() + err = errors.Join(err, getErr) + } else { + rk, err = runkit.Get(ctx, localCache, src) + } + + return rk, err +} From 2ff8d675e05eafefc076e493535715dde1ac91d6 Mon Sep 17 00:00:00 2001 From: Yves Brissaud Date: Thu, 17 Oct 2024 14:13:17 +0200 Subject: [PATCH 2/3] feat: use -h/--help instead of -d/--docs Signed-off-by: Yves Brissaud --- internal/commands/help/help.go | 23 ---------- internal/commands/root/root.go | 77 +++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 25 deletions(-) delete mode 100644 internal/commands/help/help.go diff --git a/internal/commands/help/help.go b/internal/commands/help/help.go deleted file mode 100644 index 9e54d19..0000000 --- a/internal/commands/help/help.go +++ /dev/null @@ -1,23 +0,0 @@ -package help - -import ( - "github.com/spf13/cobra" - - "github.com/docker/cli/cli/command" -) - -const ( - commandName = "help" -) - -func NewCmd(_ command.Cli, rootCmd *cobra.Command) *cobra.Command { - cmd := &cobra.Command{ - Use: commandName, - Short: "Display information about the available commands", - RunE: func(cmd *cobra.Command, args []string) error { - return rootCmd.Help() - }, - } - - return cmd -} diff --git a/internal/commands/root/root.go b/internal/commands/root/root.go index f084b89..01097c5 100644 --- a/internal/commands/root/root.go +++ b/internal/commands/root/root.go @@ -3,6 +3,10 @@ package root import ( "context" "fmt" + "io" + "os" + "strings" + "text/template" "github.com/spf13/cobra" @@ -11,7 +15,6 @@ import ( "github.com/docker/cli/cli/command" "github.com/eunomie/docker-runx/internal/commands/cache" "github.com/eunomie/docker-runx/internal/commands/decorate" - "github.com/eunomie/docker-runx/internal/commands/help" "github.com/eunomie/docker-runx/internal/commands/version" "github.com/eunomie/docker-runx/internal/constants" "github.com/eunomie/docker-runx/internal/prompt" @@ -27,6 +30,7 @@ var ( ask bool opts []string noFlagCheck bool + helpFlag bool ) func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { @@ -109,6 +113,61 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { } ) + cmd.SetHelpFunc(func(c *cobra.Command, args []string) { + var ( + lc = runkit.GetLocalConfig() + localCache = runkit.NewLocalCache(dockerCli) + src string + action string + needHelp bool + err error + rk *runkit.RunKit + md string + ) + + if isPlugin && len(args) > 0 && args[0] == constants.SubCommandName { + args = args[1:] + } + + if len(args) > 0 { + for _, c := range cmd.Commands() { + if strings.HasPrefix(c.Use, args[0]) { + printHelp(c) + return + } + } + } + + if err := c.ParseFlags(args); err != nil { + printHelp(c) + return + } + + args = c.Flags().Args() + src, action, needHelp = parseArgs(c.Context(), args, lc) + if needHelp { + printHelp(c) + return + } + + _ = localCache.EraseNotAccessedInLast30Days() + + rk, err = runx.Get(c.Context(), dockerCli.In().FD(), localCache, src) + if err != nil { + _, _ = fmt.Fprintln(dockerCli.Err(), err) + os.Exit(1) + } + + if action != "" { + md = runx.MDAction(rk, action) + } else { + md = runx.FullMD(rk) + } + _, _ = fmt.Fprintln(dockerCli.Out(), tui.Markdown(md)) + }) + + cmd.PersistentFlags().BoolVarP(&helpFlag, "help", "h", false, "Print usage or runx image/action documentation") + if isPlugin { originalPreRunE := cmd.PersistentPreRunE cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { @@ -131,7 +190,6 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { } cmd.AddCommand( - help.NewCmd(dockerCli, cmd), version.NewCmd(dockerCli), decorate.NewCmd(dockerCli), cache.NewCmd(dockerCli), @@ -139,6 +197,7 @@ func NewCmd(dockerCli command.Cli, isPlugin bool) *cobra.Command { f := cmd.Flags() f.BoolVarP(&docs, "docs", "d", false, "Print the documentation of the image") + _ = f.MarkDeprecated("docs", "use -h/--help instead") f.BoolVarP(&list, "list", "l", false, "List available actions") f.BoolVar(&ask, "ask", false, "Do not read local configuration option values and always ask them") f.StringArrayVar(&opts, "opt", nil, "Set an option value") @@ -178,6 +237,20 @@ func parseArgs(ctx context.Context, args []string, lc *runkit.LocalConfig) (src, return } +func printHelp(c *cobra.Command) { + err := tmpl(c.OutOrStdout(), c.HelpTemplate(), c) + if err != nil { + c.PrintErrln(err) + } +} + +func tmpl(w io.Writer, text string, data interface{}) error { + t := template.New("top") + // t.Funcs(templateFuncs) + template.Must(t.Parse(text)) + return t.Execute(w, data) +} + func commandName(isPlugin bool) string { name := constants.SubCommandName if !isPlugin { From 8d864fd827fd776ce5d7fdb9d0856418f245504c Mon Sep 17 00:00:00 2001 From: Yves Brissaud Date: Thu, 17 Oct 2024 14:15:46 +0200 Subject: [PATCH 3/3] docs: update with --help instead of --docs Signed-off-by: Yves Brissaud --- README.md | 6 +++--- docs/index.markdown | 6 +++--- docs/reference/docker_runx.yaml | 13 +++++++++++-- docs/reference/docker_runx_cache.yaml | 12 ++++++++++++ docs/reference/docker_runx_cache_df.yaml | 12 ++++++++++++ docs/reference/docker_runx_cache_prune.yaml | 12 ++++++++++++ docs/reference/docker_runx_decorate.yaml | 12 ++++++++++++ docs/reference/docker_runx_version.yaml | 12 ++++++++++++ docs/reference/runx.md | 13 ++++++------- docs/reference/runx_cache.md | 6 ++++++ docs/reference/runx_cache_df.md | 6 ++++++ docs/reference/runx_cache_prune.md | 9 +++++---- docs/reference/runx_decorate.md | 1 + docs/reference/runx_version.md | 6 ++++++ internal/runx/md.go | 2 +- 15 files changed, 108 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6e69b74..2296456 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ $ docker runx decorate alpine --tag NAMESPACE/REPOSITORY You can then display the embedded readme: ``` -$ dockedr runx NAMESPACE/REPOSITORY --docs +$ docker runx NAMESPACE/REPOSITORY --help ``` Or run the `hello` action: @@ -69,7 +69,7 @@ See more examples in the [examples](/examples) directory. ### Usage -> `docker runx IMAGE --docs` +> `docker runx IMAGE --help` > > Display the embedded documentation of an image and print the list of available actions. @@ -81,7 +81,7 @@ See more examples in the [examples](/examples) directory. > > Run a specific action on an image. -> `docker runx IMAGE ACTION --docs` +> `docker runx IMAGE ACTION --help` > > Display a detailed documentation of a specific action. This will also display the list of available options, shell scripts, environment variables. diff --git a/docs/index.markdown b/docs/index.markdown index 942bb0c..4fa659d 100644 --- a/docs/index.markdown +++ b/docs/index.markdown @@ -47,7 +47,7 @@ $ docker runx decorate alpine --tag NAMESPACE/REPOSITORY You can then display the embedded readme: ``` -$ dockedr runx NAMESPACE/REPOSITORY --docs +$ docker runx NAMESPACE/REPOSITORY --help ``` Or run the `hello` action: @@ -62,7 +62,7 @@ See more examples in the [examples](https://github.com/eunomie/docker-runx/tree/ ### Usage -> `docker runx IMAGE --docs` +> `docker runx IMAGE --help` > > Display the embedded documentation of an image and print the list of available actions. @@ -74,7 +74,7 @@ See more examples in the [examples](https://github.com/eunomie/docker-runx/tree/ > > Run a specific action on an image. -> `docker runx IMAGE ACTION --docs` +> `docker runx IMAGE ACTION --help` > > Display a detailed documentation of a specific action. This will also display the list of available options, shell scripts, environment variables. diff --git a/docs/reference/docker_runx.yaml b/docs/reference/docker_runx.yaml index 80c9a5c..ed24d0d 100644 --- a/docs/reference/docker_runx.yaml +++ b/docs/reference/docker_runx.yaml @@ -7,12 +7,10 @@ plink: docker.yaml cname: - docker runx cache - docker runx decorate - - docker runx help - docker runx version clink: - docker_runx_cache.yaml - docker_runx_decorate.yaml - - docker_runx_help.yaml - docker_runx_version.yaml options: - option: ask @@ -30,6 +28,17 @@ options: value_type: bool default_value: "false" description: Print the documentation of the image + deprecated: true + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation deprecated: false hidden: false experimental: false diff --git a/docs/reference/docker_runx_cache.yaml b/docs/reference/docker_runx_cache.yaml index 075d9cd..106e2cf 100644 --- a/docs/reference/docker_runx_cache.yaml +++ b/docs/reference/docker_runx_cache.yaml @@ -9,6 +9,18 @@ cname: clink: - docker_runx_cache_df.yaml - docker_runx_cache_prune.yaml +inherited_options: + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/docker_runx_cache_df.yaml b/docs/reference/docker_runx_cache_df.yaml index e0697fe..cbee59b 100644 --- a/docs/reference/docker_runx_cache_df.yaml +++ b/docs/reference/docker_runx_cache_df.yaml @@ -4,6 +4,18 @@ long: Show disk usage usage: docker runx cache df pname: docker runx cache plink: docker_runx_cache.yaml +inherited_options: + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/docker_runx_cache_prune.yaml b/docs/reference/docker_runx_cache_prune.yaml index cf92e13..dd33823 100644 --- a/docs/reference/docker_runx_cache_prune.yaml +++ b/docs/reference/docker_runx_cache_prune.yaml @@ -28,6 +28,18 @@ options: experimentalcli: false kubernetes: false swarm: false +inherited_options: + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/docker_runx_decorate.yaml b/docs/reference/docker_runx_decorate.yaml index 0466999..f5f0cc7 100644 --- a/docs/reference/docker_runx_decorate.yaml +++ b/docs/reference/docker_runx_decorate.yaml @@ -55,6 +55,18 @@ options: experimentalcli: false kubernetes: false swarm: false +inherited_options: + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/docker_runx_version.yaml b/docs/reference/docker_runx_version.yaml index 624900c..dbc7b3b 100644 --- a/docs/reference/docker_runx_version.yaml +++ b/docs/reference/docker_runx_version.yaml @@ -4,6 +4,18 @@ long: Show Docker RunX version information usage: docker runx version pname: docker runx plink: docker_runx.yaml +inherited_options: + - option: help + shorthand: h + value_type: bool + default_value: "false" + description: Print usage or runx image/action documentation + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/docs/reference/runx.md b/docs/reference/runx.md index 0a2b1a4..5fd5de7 100644 --- a/docs/reference/runx.md +++ b/docs/reference/runx.md @@ -5,12 +5,11 @@ Docker Run, better ### Subcommands -| Name | Description | -|:-------------------------------|:-------------------------------------------------| -| [`cache`](runx_cache.md) | Manage Docker RunX cache and temporary files | -| [`decorate`](runx_decorate.md) | Decorate an image by attaching a runx manifest | -| [`help`](runx_help.md) | Display information about the available commands | -| [`version`](runx_version.md) | Show Docker RunX version information | +| Name | Description | +|:-------------------------------|:-----------------------------------------------| +| [`cache`](runx_cache.md) | Manage Docker RunX cache and temporary files | +| [`decorate`](runx_decorate.md) | Decorate an image by attaching a runx manifest | +| [`version`](runx_version.md) | Show Docker RunX version information | ### Options @@ -18,7 +17,7 @@ Docker Run, better | Name | Type | Default | Description | |:---------------|:--------------|:--------|:------------------------------------------------------------------| | `--ask` | `bool` | | Do not read local configuration option values and always ask them | -| `-d`, `--docs` | `bool` | | Print the documentation of the image | +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | | `-l`, `--list` | `bool` | | List available actions | | `--opt` | `stringArray` | | Set an option value | | `-y`, `--yes` | `bool` | | Do not check flags before running the command | diff --git a/docs/reference/runx_cache.md b/docs/reference/runx_cache.md index 49eadde..5e4a68d 100644 --- a/docs/reference/runx_cache.md +++ b/docs/reference/runx_cache.md @@ -11,6 +11,12 @@ Manage Docker RunX cache and temporary files | [`prune`](runx_cache_prune.md) | Remove cache entries not accessed recently | +### Options + +| Name | Type | Default | Description | +|:---------------|:-------|:--------|:-----------------------------------------------| +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | + diff --git a/docs/reference/runx_cache_df.md b/docs/reference/runx_cache_df.md index 698b71c..09a9dee 100644 --- a/docs/reference/runx_cache_df.md +++ b/docs/reference/runx_cache_df.md @@ -3,6 +3,12 @@ Show disk usage +### Options + +| Name | Type | Default | Description | +|:---------------|:-------|:--------|:-----------------------------------------------| +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | + diff --git a/docs/reference/runx_cache_prune.md b/docs/reference/runx_cache_prune.md index c977827..b19865e 100644 --- a/docs/reference/runx_cache_prune.md +++ b/docs/reference/runx_cache_prune.md @@ -5,10 +5,11 @@ By default remove cache entries not accessed in the last 30 days. Use --all/-a t ### Options -| Name | Type | Default | Description | -|:----------------|:-------|:--------|:-------------------------------| -| `-a`, `--all` | `bool` | | Remove all cache entries | -| `-f`, `--force` | `bool` | | Do not prompt for confirmation | +| Name | Type | Default | Description | +|:----------------|:-------|:--------|:-----------------------------------------------| +| `-a`, `--all` | `bool` | | Remove all cache entries | +| `-f`, `--force` | `bool` | | Do not prompt for confirmation | +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | diff --git a/docs/reference/runx_decorate.md b/docs/reference/runx_decorate.md index 67c3473..026a554 100644 --- a/docs/reference/runx_decorate.md +++ b/docs/reference/runx_decorate.md @@ -7,6 +7,7 @@ Decorate an image by attaching a runx manifest | Name | Type | Default | Description | |:----------------|:---------|:------------|:------------------------------------------------| +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | | `--no-config` | `bool` | | Do not attach a runx configuration to the image | | `--no-readme` | `bool` | | Do not attach a README to the image | | `-t`, `--tag` | `string` | | Tag to push the decorated image to | diff --git a/docs/reference/runx_version.md b/docs/reference/runx_version.md index 7a6675c..1156b04 100644 --- a/docs/reference/runx_version.md +++ b/docs/reference/runx_version.md @@ -3,6 +3,12 @@ Show Docker RunX version information +### Options + +| Name | Type | Default | Description | +|:---------------|:-------|:--------|:-----------------------------------------------| +| `-h`, `--help` | `bool` | | Print usage or runx image/action documentation | + diff --git a/internal/runx/md.go b/internal/runx/md.go index eb0dd6a..48bea65 100644 --- a/internal/runx/md.go +++ b/internal/runx/md.go @@ -79,7 +79,7 @@ func MDActions(rk *runkit.RunKit) string { } } - s.WriteString("\n> Use `docker runx IMAGE ACTION --docs` to get more details about an action\n") + s.WriteString("\n> Use `docker runx IMAGE ACTION --help` to get more details about an action\n") } return s.String()