fix: Show schedule commands in help, improve template (#2923)

* fix: Show schedule commands in help, improve template

* chore: Remove schedule long help, fixed by listing missing commands

* chore: Clean up annotation usage with template function

* fix: Drive-by fix for trailing whitespace for flags

Introduced in c7681370b5.
This commit is contained in:
Mathias Fredriksson
2022-07-12 23:24:53 +03:00
committed by GitHub
parent 2d048803c8
commit 59facdd8dc
2 changed files with 50 additions and 36 deletions

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"text/template"
"time" "time"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -28,7 +29,7 @@ var (
// Applied as annotations to workspace commands // Applied as annotations to workspace commands
// so they display in a separated "help" section. // so they display in a separated "help" section.
workspaceCommand = map[string]string{ workspaceCommand = map[string]string{
"workspaces": " ", "workspaces": "",
} }
) )
@ -52,12 +53,8 @@ var (
) )
func init() { func init() {
// Customizes the color of headings to make subcommands more visually // Set cobra template functions in init to avoid conflicts in tests.
// appealing. cobra.AddTemplateFuncs(templateFunctions)
header := cliui.Styles.Placeholder
cobra.AddTemplateFunc("usageHeader", func(s string) string {
return header.Render(s)
})
} }
func Root() *cobra.Command { func Root() *cobra.Command {
@ -311,6 +308,30 @@ func isTTYOut(cmd *cobra.Command) bool {
return isatty.IsTerminal(file.Fd()) return isatty.IsTerminal(file.Fd())
} }
var templateFunctions = template.FuncMap{
"usageHeader": usageHeader,
"isWorkspaceCommand": isWorkspaceCommand,
}
func usageHeader(s string) string {
// Customizes the color of headings to make subcommands more visually
// appealing.
return cliui.Styles.Placeholder.Render(s)
}
func isWorkspaceCommand(cmd *cobra.Command) bool {
if _, ok := cmd.Annotations["workspaces"]; ok {
return true
}
var ws bool
cmd.VisitParents(func(cmd *cobra.Command) {
if _, ok := cmd.Annotations["workspaces"]; ok {
ws = true
}
})
return ws
}
func usageTemplate() string { func usageTemplate() string {
// usageHeader is defined in init(). // usageHeader is defined in init().
return `{{usageHeader "Usage:"}} return `{{usageHeader "Usage:"}}
@ -331,19 +352,21 @@ func usageTemplate() string {
{{.Example}} {{.Example}}
{{end}} {{end}}
{{- $isRootHelp := (not .HasParent)}}
{{- if .HasAvailableSubCommands}} {{- if .HasAvailableSubCommands}}
{{usageHeader "Commands:"}} {{usageHeader "Commands:"}}
{{- range .Commands}} {{- range .Commands}}
{{- if (or (and .IsAvailableCommand (eq (len .Annotations) 0)) (eq .Name "help"))}} {{- $isRootWorkspaceCommand := (and $isRootHelp (isWorkspaceCommand .))}}
{{- if (or (and .IsAvailableCommand (not $isRootWorkspaceCommand)) (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}} {{rpad .Name .NamePadding }} {{.Short}}
{{- end}} {{- end}}
{{- end}} {{- end}}
{{end}} {{end}}
{{- if and (not .HasParent) .HasAvailableSubCommands}} {{- if (and $isRootHelp .HasAvailableSubCommands)}}
{{usageHeader "Workspace Commands:"}} {{usageHeader "Workspace Commands:"}}
{{- range .Commands}} {{- range .Commands}}
{{- if (and .IsAvailableCommand (ne (index .Annotations "workspaces") ""))}} {{- if (and .IsAvailableCommand (isWorkspaceCommand .))}}
{{rpad .Name .NamePadding }} {{.Short}} {{rpad .Name .NamePadding }} {{.Short}}
{{- end}} {{- end}}
{{- end}} {{- end}}
@ -351,12 +374,12 @@ func usageTemplate() string {
{{- if .HasAvailableLocalFlags}} {{- if .HasAvailableLocalFlags}}
{{usageHeader "Flags:"}} {{usageHeader "Flags:"}}
{{.LocalFlags.FlagUsagesWrapped 100}} {{.LocalFlags.FlagUsagesWrapped 100 | trimTrailingWhitespaces}}
{{end}} {{end}}
{{- if .HasAvailableInheritedFlags}} {{- if .HasAvailableInheritedFlags}}
{{usageHeader "Global Flags:"}} {{usageHeader "Global Flags:"}}
{{.InheritedFlags.FlagUsagesWrapped 100}} {{.InheritedFlags.FlagUsagesWrapped 100 | trimTrailingWhitespaces}}
{{end}} {{end}}
{{- if .HasHelpSubCommands}} {{- if .HasHelpSubCommands}}

View File

@ -17,12 +17,6 @@ import (
) )
const ( const (
scheduleDescriptionLong = `Modify scheduled stop and start times for your workspace:
* schedule show: show workspace schedule
* schedule start: edit workspace start schedule
* schedule stop: edit workspace stop schedule
* schedule override-stop: edit stop time of active workspace
`
scheduleShowDescriptionLong = `Shows the following information for the given workspace: scheduleShowDescriptionLong = `Shows the following information for the given workspace:
* The automatic start schedule * The automatic start schedule
* The next scheduled start time * The next scheduled start time
@ -64,24 +58,24 @@ func schedules() *cobra.Command {
Annotations: workspaceCommand, Annotations: workspaceCommand,
Use: "schedule { show | start | stop | override } <workspace>", Use: "schedule { show | start | stop | override } <workspace>",
Short: "Modify scheduled stop and start times for your workspace", Short: "Modify scheduled stop and start times for your workspace",
Long: scheduleDescriptionLong,
} }
scheduleCmd.AddCommand(scheduleShow()) scheduleCmd.AddCommand(
scheduleCmd.AddCommand(scheduleStart()) scheduleShow(),
scheduleCmd.AddCommand(scheduleStop()) scheduleStart(),
scheduleCmd.AddCommand(scheduleOverride()) scheduleStop(),
scheduleOverride(),
)
return scheduleCmd return scheduleCmd
} }
func scheduleShow() *cobra.Command { func scheduleShow() *cobra.Command {
showCmd := &cobra.Command{ showCmd := &cobra.Command{
Annotations: workspaceCommand, Use: "show <workspace-name>",
Use: "show <workspace-name>", Short: "Show workspace schedule",
Short: "Show workspace schedule", Long: scheduleShowDescriptionLong,
Long: scheduleShowDescriptionLong, Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
client, err := createClient(cmd) client, err := createClient(cmd)
if err != nil { if err != nil {
@ -101,8 +95,7 @@ func scheduleShow() *cobra.Command {
func scheduleStart() *cobra.Command { func scheduleStart() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Annotations: workspaceCommand, Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
Example: formatExamples( Example: formatExamples(
example{ example{
Description: "Set the workspace to start at 9:30am (in Dublin) from Monday to Friday", Description: "Set the workspace to start at 9:30am (in Dublin) from Monday to Friday",
@ -153,9 +146,8 @@ func scheduleStart() *cobra.Command {
func scheduleStop() *cobra.Command { func scheduleStop() *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Annotations: workspaceCommand, Args: cobra.ExactArgs(2),
Args: cobra.ExactArgs(2), Use: "stop <workspace-name> { <duration> | manual }",
Use: "stop <workspace-name> { <duration> | manual }",
Example: formatExamples( Example: formatExamples(
example{ example{
Command: "coder schedule stop my-workspace 2h30m", Command: "coder schedule stop my-workspace 2h30m",
@ -200,9 +192,8 @@ func scheduleStop() *cobra.Command {
func scheduleOverride() *cobra.Command { func scheduleOverride() *cobra.Command {
overrideCmd := &cobra.Command{ overrideCmd := &cobra.Command{
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
Annotations: workspaceCommand, Use: "override-stop <workspace-name> <duration from now>",
Use: "override-stop <workspace-name> <duration from now>",
Example: formatExamples( Example: formatExamples(
example{ example{
Command: "coder schedule override-stop my-workspace 90m", Command: "coder schedule override-stop my-workspace 90m",