Skip to content

Commit 6fc697a

Browse files
committed
help:
Closes #1136
1 parent 37a3fb0 commit 6fc697a

File tree

3 files changed

+80
-83
lines changed

3 files changed

+80
-83
lines changed

cli/cmd/external.go

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package cmd
22

33
import (
4-
"strings"
5-
64
"github.com/spf13/cobra"
75
"github.com/tarantool/tt/cli/modules"
6+
"golang.org/x/exp/slices"
7+
)
8+
9+
var (
10+
commandGroupExternal = &cobra.Group{ID: "External"}
811
)
912

1013
// ExternalCmd configures external commands.
11-
func configureExternalCmd(rootCmd *cobra.Command,
12-
modulesInfo *modules.ModulesInfo, forceInternal bool, args []string) {
14+
func configureExternalCmd(rootCmd *cobra.Command, modulesInfo *modules.ModulesInfo,
15+
forceInternal bool) {
1316
configureExistsCmd(rootCmd, modulesInfo, forceInternal)
14-
configureNonExistentCmd(rootCmd, modulesInfo, args)
17+
configureNonExistentCmd(rootCmd, modulesInfo)
1518
}
1619

1720
// configureExistsCmd configures an external commands
@@ -21,35 +24,32 @@ func configureExistsCmd(rootCmd *cobra.Command, modulesInfo *modules.ModulesInfo
2124
for _, cmd := range rootCmd.Commands() {
2225
if _, found := (*modulesInfo)[cmd.CommandPath()]; found {
2326
cmd.DisableFlagParsing = !forceInternal
27+
cmd.GroupID = "|" + commandGroupExternal.ID
2428
}
2529
}
2630
}
2731

2832
// configureNonExistentCmd configures an external command that
2933
// has no internal implementation within the Tarantool CLI.
30-
func configureNonExistentCmd(rootCmd *cobra.Command,
31-
modulesInfo *modules.ModulesInfo, args []string) {
32-
// Since the user can pass flags, to determine the name of
33-
// an external command we have to take the first non-flag argument.
34-
externalCmd := args[0]
35-
for _, name := range args {
36-
if !strings.HasPrefix(name, "-") && name != "help" {
37-
externalCmd = name
38-
break
39-
}
40-
}
34+
func configureNonExistentCmd(rootCmd *cobra.Command, modulesInfo *modules.ModulesInfo) {
35+
hasExternalCmd := false
4136

42-
// We avoid overwriting existing commands - we should add a command only
43-
// if it doesn't have an internal implementation in Tarantool CLI.
37+
// Prepare list of internal command names.
38+
internalCmdNames := []string{"help"}
4439
for _, cmd := range rootCmd.Commands() {
45-
if cmd.Name() == externalCmd {
46-
return
40+
internalCmdNames = append(internalCmdNames, cmd.Name())
41+
}
42+
43+
// Add external command only if it doesn't have an internal implementation in Tarantool CLI.
44+
for name, manifest := range *modulesInfo {
45+
if !slices.Contains(internalCmdNames, name) {
46+
rootCmd.AddCommand(newExternalCmd(name, manifest))
47+
hasExternalCmd = true
4748
}
4849
}
4950

50-
externalCmdPath := rootCmd.Name() + " " + externalCmd
51-
if _, found := (*modulesInfo)[externalCmdPath]; found {
52-
rootCmd.AddCommand(newExternalCmd(externalCmd))
51+
if hasExternalCmd {
52+
rootCmd.AddGroup(commandGroupExternal)
5353
}
5454
}
5555

@@ -65,11 +65,18 @@ func externalCmdHelpFunc(cmd *cobra.Command, args []string) {
6565

6666
// newExternalCmd returns a pointer to a new external
6767
// command that will call modules.RunCmd.
68-
func newExternalCmd(cmdName string) *cobra.Command {
68+
func newExternalCmd(cmdName string, manifest modules.Manifest) *cobra.Command {
69+
desc, err := modules.GetExternalModuleDescription(manifest)
70+
if err != nil {
71+
desc = "description is absent"
72+
}
73+
6974
var cmd = &cobra.Command{
7075
Use: cmdName,
76+
Short: desc,
7177
Run: RunModuleFunc(nil),
7278
DisableFlagParsing: true,
79+
GroupID: commandGroupExternal.ID,
7380
}
7481
cmd.SetHelpFunc(externalCmdHelpFunc)
7582
return cmd

cli/cmd/help.go

Lines changed: 48 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package cmd
22

33
import (
4-
"fmt"
54
"strings"
65

76
"github.com/spf13/cobra"
@@ -12,19 +11,21 @@ import (
1211

1312
func configureHelpCommand(rootCmd *cobra.Command, modulesInfo *modules.ModulesInfo) error {
1413
// Add information about external modules into help template.
15-
rootCmd.SetUsageTemplate(fmt.Sprintf(usageTemplate, getExternalCommandsString(modulesInfo)))
14+
cobra.AddTemplateFunc("title", util.Bold)
15+
cobra.AddTemplateFunc("split", strings.Split)
16+
rootCmd.SetUsageTemplate(usageTemplate)
1617

1718
internalHelpModule := func(cmdCtx *cmdcontext.CmdCtx, args []string) error {
18-
fmt.Printf("internalHelpModule: cmdCtx.CommandName=%s\n", cmdCtx.CommandName)
19-
fmt.Printf("internalHelpModule: args: %v\n", args)
19+
// fmt.Printf("internalHelpModule: cmdCtx.CommandName=%s\n", cmdCtx.CommandName)
20+
// fmt.Printf("internalHelpModule: args: %v\n", args)
2021
if len(args) == 0 {
2122
rootCmd.Help()
2223
return nil
2324
}
2425

2526
cmd, _, err := rootCmd.Find(args)
26-
fmt.Printf("internalHelpModule: cmd.Name=%s\n", cmd.Name())
27-
fmt.Printf("internalHelpModule: cmd.CommandPath=%s\n", cmd.CommandPath())
27+
// fmt.Printf("internalHelpModule: cmd.Name=%s\n", cmd.Name())
28+
// fmt.Printf("internalHelpModule: cmd.CommandPath=%s\n", cmd.CommandPath())
2829
if err != nil {
2930
return err
3031
}
@@ -48,75 +49,66 @@ func configureHelpCommand(rootCmd *cobra.Command, modulesInfo *modules.ModulesIn
4849
return nil
4950
}
5051

51-
// getExternalCommandString returns a pretty string
52-
// of descriptions for external modules.
53-
func getExternalCommandsString(modulesInfo *modules.ModulesInfo) string {
54-
str := ""
55-
for path, manifest := range *modulesInfo {
56-
helpMsg, err := modules.GetExternalModuleDescription(manifest)
57-
if err != nil {
58-
helpMsg = "description is absent"
59-
}
60-
61-
name := strings.Split(path, " ")[1]
62-
str = fmt.Sprintf("%s %s\t%s\n", str, name, helpMsg)
63-
}
64-
65-
if str != "" {
66-
str = util.Bold("\nEXTERNAL COMMANDS\n") + str
67-
return strings.Trim(str, "\n")
68-
}
69-
70-
return ""
71-
}
72-
7352
var (
74-
usageTemplate = util.Bold("USAGE") + `
53+
usageTemplate = `{{title "USAGE"}}
7554
{{- if (and .Runnable .HasAvailableInheritedFlags)}}
7655
{{.UseLine}}
7756
{{end -}}
7857
7958
{{- if .HasAvailableSubCommands}}
8059
{{.CommandPath}} [flags] <command> [command flags]
81-
{{end -}}
82-
83-
{{if not .HasAvailableSubCommands}}
84-
{{- if .Runnable}}
60+
{{- else if .Runnable}}
8561
{{.UseLine}}
86-
{{end -}}
87-
{{end}}
62+
{{- end}}
63+
{{- if gt (len .Aliases) 0}}
8864
89-
{{- if gt (len .Aliases) 0}}` + util.Bold("\nALIASES") + `
65+
{{title "ALIASES"}}
9066
{{.NameAndAliases}}
91-
{{end -}}
67+
{{- end}}
68+
{{- if .HasAvailableSubCommands}}
9269
93-
{{if .HasAvailableSubCommands}}` + util.Bold("\nCOMMANDS") + `
70+
{{title "COMMANDS"}}
9471
{{- range .Commands}}
95-
96-
{{- if (or .IsAvailableCommand (eq .Name "help"))}}
72+
{{- if or .IsAvailableCommand (eq .Name "help")}}
73+
{{- if eq .GroupID ""}}
9774
{{rpad .Name .NamePadding }} {{.Short}}
98-
{{- end -}}
99-
100-
{{end}}
101-
{{end -}}
102-
103-
{{- if not .HasAvailableInheritedFlags}} %s
104-
{{end -}}
105-
106-
{{- if .HasAvailableLocalFlags}}` + util.Bold("\nFLAGS") + `
75+
{{- else if ne .GroupID "External"}}
76+
{{rpad .Name .NamePadding }} {{index (split .Short "|") 0}}
77+
{{- end}}
78+
{{- end}}
79+
{{- end}}
80+
{{- end}}
81+
{{- if gt (len .Groups) 0}}
82+
83+
{{title "EXTERNAL COMMANDS"}}
84+
{{- range .Commands}}
85+
{{- if or .IsAvailableCommand (eq .Name "help")}}
86+
{{- if eq .GroupID "External"}}
87+
{{rpad .Name .NamePadding }} {{.Short}}
88+
{{- else if ne .GroupID ""}}
89+
{{rpad .Name .NamePadding }} {{index (split .Short "|") 1}}
90+
{{- end}}
91+
{{- end}}
92+
{{- end}}
93+
{{- end}}
94+
{{- if .HasAvailableLocalFlags}}
95+
96+
{{title "FLAGS"}}
10797
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}
108-
{{end -}}
98+
{{- end}}
99+
{{- if .HasAvailableInheritedFlags}}
109100
110-
{{- if .HasAvailableInheritedFlags}}` + util.Bold("\nGLOBAL FLAGS") + `
101+
{{title "GLOBAL FLAGS"}}
111102
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}
112-
{{end -}}
103+
{{- end}}
104+
{{- if .HasExample}}
113105
114-
{{- if .HasExample}}` + util.Bold("\nEXAMPLES") + `
106+
{{title "EXAMPLES"}}
115107
{{.Example}}
116-
{{end -}}
117-
108+
{{- end}}
118109
{{- if .HasAvailableSubCommands}}
110+
119111
Use "{{.CommandPath}} <command> --help" for more information about a command.
120-
{{end -}}
112+
{{- end}}
121113
`
122114
)

cli/cmd/root.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,7 @@ func InitRoot() {
313313

314314
// External commands must be configured in a special way.
315315
// This is necessary, for example, so that we can pass arguments to these commands.
316-
if len(os.Args) > 1 {
317-
configureExternalCmd(rootCmd, &modulesInfo, cmdCtx.Cli.ForceInternal, os.Args[1:])
318-
}
316+
configureExternalCmd(rootCmd, &modulesInfo, cmdCtx.Cli.ForceInternal)
319317

320318
// Configure help command.
321319
err = configureHelpCommand(rootCmd, &modulesInfo)

0 commit comments

Comments
 (0)