Skip to content

Commit 7001937

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

File tree

3 files changed

+50
-77
lines changed

3 files changed

+50
-77
lines changed

cli/cmd/external.go

+31-24
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

+18-50
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import (
1212

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

1719
internalHelpModule := func(cmdCtx *cmdcontext.CmdCtx, args []string) error {
1820
fmt.Printf("internalHelpModule: cmdCtx.CommandName=%s\n", cmdCtx.CommandName)
@@ -48,30 +50,8 @@ func configureHelpCommand(rootCmd *cobra.Command, modulesInfo *modules.ModulesIn
4850
return nil
4951
}
5052

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-
7353
var (
74-
usageTemplate = util.Bold("USAGE") + `
54+
usageTemplate = `{{title "USAGE"}}
7555
{{- if (and .Runnable .HasAvailableInheritedFlags)}}
7656
{{.UseLine}}
7757
{{end -}}
@@ -86,37 +66,25 @@ var (
8666
{{end -}}
8767
{{end}}
8868
89-
{{- if gt (len .Aliases) 0}}` + util.Bold("\nALIASES") + `
90-
{{.NameAndAliases}}
91-
{{end -}}
92-
93-
{{if .HasAvailableSubCommands}}` + util.Bold("\nCOMMANDS") + `
94-
{{- range .Commands}}
69+
{{- if gt (len .Aliases) 0}}
70+
{{title "ALIASES"}}
71+
{{.NameAndAliases}}{{end}}{{if .HasAvailableSubCommands}}
9572
96-
{{- if (or .IsAvailableCommand (eq .Name "help"))}}
97-
{{rpad .Name .NamePadding }} {{.Short}}
98-
{{- end -}}
73+
{{title "COMMANDS"}}{{range .Commands}}{{if and (ne .GroupID "External") (or .IsAvailableCommand (eq .Name "help"))}}
74+
{{rpad .Name .NamePadding }} {{if eq .GroupID ""}}{{.Short}}{{else}}{{index (split .Short "|") 0}}{{end}}{{end}}{{end}}{{end}}{{if gt (len .Groups) 0}}
9975
100-
{{end}}
101-
{{end -}}
102-
103-
{{- if not .HasAvailableInheritedFlags}} %s
104-
{{end -}}
76+
{{title "EXTERNAL COMMANDS"}}{{range .Commands}}{{if and (ne .GroupID "") (or .IsAvailableCommand (eq .Name "help"))}}
77+
{{rpad .Name .NamePadding }} {{if eq .GroupID "External"}}{{.Short}}{{else}}{{index (split .Short "|") 1}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
10578
106-
{{- if .HasAvailableLocalFlags}}` + util.Bold("\nFLAGS") + `
107-
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}
108-
{{end -}}
79+
{{title "FLAGS"}}
80+
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
10981
110-
{{- if .HasAvailableInheritedFlags}}` + util.Bold("\nGLOBAL FLAGS") + `
111-
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}
112-
{{end -}}
82+
{{title "GLOBAL FLAGS"}}
83+
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasExample}}
11384
114-
{{- if .HasExample}}` + util.Bold("\nEXAMPLES") + `
115-
{{.Example}}
116-
{{end -}}
85+
{{title "EXAMPLES"}}
86+
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
11787
118-
{{- if .HasAvailableSubCommands}}
119-
Use "{{.CommandPath}} <command> --help" for more information about a command.
120-
{{end -}}
88+
Use "{{.CommandPath}} <command> --help" for more information about a command.{{end}}
12189
`
12290
)

cli/cmd/root.go

+1-3
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)