|
1 | 1 | package cmd |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
| 5 | + "fmt" |
| 6 | + "regexp" |
4 | 7 | "strings" |
5 | 8 |
|
6 | 9 | "github.com/spf13/cobra" |
7 | 10 | "k8s.io/kubectl/pkg/util/templates" |
8 | 11 | ) |
9 | 12 |
|
| 13 | +var ( |
| 14 | + usageOptionsSuffixPattern = regexp.MustCompile(`(?m)^(\s*.+?) \[options\]\s*$`) |
| 15 | + globalOptionsHintPattern = regexp.MustCompile(`(?m)^Use ".* options" for a list of global command-line options \(applies to all commands\)\.\n?`) |
| 16 | +) |
| 17 | + |
10 | 18 | /* |
11 | 19 | Create root Cobra command group for Educates CLI . |
12 | 20 | */ |
@@ -82,9 +90,63 @@ func (p *ProjectInfo) NewEducatesCmdGroup() *cobra.Command { |
82 | 90 |
|
83 | 91 | commandGroups.Add(c) |
84 | 92 |
|
85 | | - templates.ActsAsRootCommand(c, []string{"--help"}, commandGroups...) |
86 | | - |
87 | 93 | c.AddCommand(p.NewProjectVersionCmd()) |
| 94 | + configureRootHelpTemplates(c, []string{"--help"}, commandGroups...) |
88 | 95 |
|
89 | 96 | return c |
90 | 97 | } |
| 98 | + |
| 99 | +// configureRootHelpTemplates preserves grouped command help output from cobra |
| 100 | +// templates, while removing the synthetic [options] usage suffix and global |
| 101 | +// options hint from displayed usage text. |
| 102 | +func configureRootHelpTemplates(c *cobra.Command, filters []string, groups ...templates.CommandGroup) { |
| 103 | + templates.ActsAsRootCommand(c, filters, groups...) |
| 104 | + |
| 105 | + sanitizeCommandUsage(c) |
| 106 | +} |
| 107 | + |
| 108 | +func sanitizeCommandUsage(command *cobra.Command) { |
| 109 | + originalUsageFunc := command.UsageFunc() |
| 110 | + originalHelpFunc := command.HelpFunc() |
| 111 | + |
| 112 | + command.SetUsageFunc(func(cmd *cobra.Command) error { |
| 113 | + usageBuffer := bytes.NewBuffer(nil) |
| 114 | + |
| 115 | + originalErr := cmd.ErrOrStderr() |
| 116 | + cmd.SetErr(usageBuffer) |
| 117 | + defer cmd.SetErr(originalErr) |
| 118 | + |
| 119 | + if err := originalUsageFunc(cmd); err != nil { |
| 120 | + return err |
| 121 | + } |
| 122 | + |
| 123 | + _, err := fmt.Fprint(originalErr, sanitizeUsageOutput(usageBuffer.String())) |
| 124 | + return err |
| 125 | + }) |
| 126 | + |
| 127 | + command.SetHelpFunc(func(cmd *cobra.Command, args []string) { |
| 128 | + helpBuffer := bytes.NewBuffer(nil) |
| 129 | + |
| 130 | + originalOut := cmd.OutOrStdout() |
| 131 | + cmd.SetOut(helpBuffer) |
| 132 | + defer cmd.SetOut(originalOut) |
| 133 | + |
| 134 | + originalHelpFunc(cmd, args) |
| 135 | + fmt.Fprint(originalOut, sanitizeUsageOutput(helpBuffer.String())) |
| 136 | + }) |
| 137 | + |
| 138 | + for _, child := range command.Commands() { |
| 139 | + sanitizeCommandUsage(child) |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +func sanitizeUsageOutput(output string) string { |
| 144 | + cleaned := usageOptionsSuffixPattern.ReplaceAllString(output, "$1") |
| 145 | + cleaned = globalOptionsHintPattern.ReplaceAllString(cleaned, "") |
| 146 | + |
| 147 | + for strings.Contains(cleaned, "\n\n\n") { |
| 148 | + cleaned = strings.ReplaceAll(cleaned, "\n\n\n", "\n\n") |
| 149 | + } |
| 150 | + |
| 151 | + return cleaned |
| 152 | +} |
0 commit comments