Browse code

Integrating help and usage templates in all commands

fabianofranz authored on 2015/04/02 08:00:08
Showing 9 changed files
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	exregistry "github.com/openshift/origin/pkg/cmd/experimental/registry"
15 15
 	exrouter "github.com/openshift/origin/pkg/cmd/experimental/router"
16 16
 	"github.com/openshift/origin/pkg/cmd/server/admin"
17
-	"github.com/openshift/origin/pkg/cmd/templates"
18 17
 	"github.com/openshift/origin/pkg/cmd/util/clientcmd"
19 18
 	"github.com/openshift/origin/pkg/version"
20 19
 )
... ...
@@ -43,8 +42,6 @@ func NewCommandAdmin(name, fullName string, out io.Writer) *cobra.Command {
43 43
 
44 44
 	f := clientcmd.New(cmds.PersistentFlags())
45 45
 
46
-	templates.UseAdminTemplates(cmds)
47
-
48 46
 	cmds.AddCommand(project.NewCmdNewProject(f, fullName, "new-project"))
49 47
 	cmds.AddCommand(policy.NewCommandPolicy(f, fullName, "policy"))
50 48
 	cmds.AddCommand(exrouter.NewCmdRouter(f, fullName, "router", out))
... ...
@@ -10,7 +10,6 @@ import (
10 10
 
11 11
 	"github.com/openshift/origin/pkg/cmd/cli/cmd"
12 12
 	"github.com/openshift/origin/pkg/cmd/experimental/config"
13
-	"github.com/openshift/origin/pkg/cmd/templates"
14 13
 	"github.com/openshift/origin/pkg/cmd/util/clientcmd"
15 14
 	"github.com/openshift/origin/pkg/version"
16 15
 )
... ...
@@ -62,8 +61,6 @@ func NewCommandCLI(name, fullName string) *cobra.Command {
62 62
 	in := os.Stdin
63 63
 	out := os.Stdout
64 64
 
65
-	templates.UseCliTemplates(cmds)
66
-
67 65
 	cmds.AddCommand(cmd.NewCmdLogin(f, in, out))
68 66
 	cmds.AddCommand(cmd.NewCmdProject(f, out))
69 67
 	cmds.AddCommand(cmd.NewCmdNewApplication(fullName, f, out))
... ...
@@ -47,11 +47,11 @@ func NewCmdLogin(f *osclientcmd.Factory, reader io.Reader, out io.Writer) *cobra
47 47
 	cmds.Flags().StringVarP(&options.Password, "password", "p", "", "Password, will prompt if not provided")
48 48
 
49 49
 	templater := templates.Templater{
50
-		UsageTemplate: templates.CliUsageTemplate(),
51
-		Exposed:       []string{"server", "username", "password", "certificate-authority", "insecure-skip-tls-verify", "context"},
50
+		UsageTemplate: templates.MainUsageTemplate(),
51
+		Exposed:       []string{"server", "certificate-authority", "insecure-skip-tls-verify", "context"},
52 52
 	}
53 53
 	cmds.SetUsageFunc(templater.UsageFunc())
54
-	cmds.SetHelpTemplate(templates.CliHelpTemplate())
54
+	cmds.SetHelpTemplate(templates.MainHelpTemplate())
55 55
 
56 56
 	return cmds
57 57
 }
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"github.com/spf13/cobra"
5 5
 
6 6
 	"github.com/openshift/origin/pkg/build/builder/cmd"
7
-	"github.com/openshift/origin/pkg/cmd/templates"
8 7
 	"github.com/openshift/origin/pkg/version"
9 8
 )
10 9
 
... ...
@@ -26,8 +25,6 @@ func NewCommandSTIBuilder(name string) *cobra.Command {
26 26
 		},
27 27
 	}
28 28
 
29
-	templates.UseMainTemplates(cmd)
30
-
31 29
 	cmd.AddCommand(version.NewVersionCommand(name))
32 30
 	return cmd
33 31
 }
... ...
@@ -49,8 +46,6 @@ func NewCommandDockerBuilder(name string) *cobra.Command {
49 49
 			cmd.RunDockerBuild()
50 50
 		},
51 51
 	}
52
-	cmd.SetUsageTemplate(templates.MainUsageTemplate())
53
-	cmd.SetHelpTemplate(templates.MainHelpTemplate())
54 52
 	cmd.AddCommand(version.NewVersionCommand(name))
55 53
 	return cmd
56 54
 }
... ...
@@ -11,7 +11,6 @@ import (
11 11
 	"github.com/spf13/cobra"
12 12
 
13 13
 	"github.com/openshift/origin/pkg/api/latest"
14
-	"github.com/openshift/origin/pkg/cmd/templates"
15 14
 	"github.com/openshift/origin/pkg/cmd/util"
16 15
 	"github.com/openshift/origin/pkg/cmd/util/clientcmd"
17 16
 	deployapi "github.com/openshift/origin/pkg/deploy/api"
... ...
@@ -67,8 +66,6 @@ func NewCommandDeployer(name string) *cobra.Command {
67 67
 		},
68 68
 	}
69 69
 
70
-	templates.UseMainTemplates(cmd)
71
-
72 70
 	cmd.AddCommand(version.NewVersionCommand(name))
73 71
 
74 72
 	flag := cmd.Flags()
... ...
@@ -7,7 +7,6 @@ import (
7 7
 	"github.com/golang/glog"
8 8
 	"github.com/spf13/cobra"
9 9
 
10
-	"github.com/openshift/origin/pkg/cmd/templates"
11 10
 	"github.com/openshift/origin/pkg/cmd/util"
12 11
 	"github.com/openshift/origin/pkg/cmd/util/clientcmd"
13 12
 	"github.com/openshift/origin/pkg/router"
... ...
@@ -52,8 +51,6 @@ func NewCommandTemplateRouter(name string) *cobra.Command {
52 52
 		},
53 53
 	}
54 54
 
55
-	templates.UseMainTemplates(cmd)
56
-
57 55
 	cmd.AddCommand(version.NewVersionCommand(name))
58 56
 
59 57
 	flag := cmd.Flags()
... ...
@@ -62,6 +62,7 @@ func CommandFor(basename string) *cobra.Command {
62 62
 		cmd = NewCommandOpenShift()
63 63
 	}
64 64
 
65
+	templates.UseMainTemplates(cmd)
65 66
 	flagtypes.GLog(cmd.PersistentFlags())
66 67
 
67 68
 	return cmd
... ...
@@ -79,8 +80,6 @@ func NewCommandOpenShift() *cobra.Command {
79 79
 		},
80 80
 	}
81 81
 
82
-	templates.UseMainTemplates(root)
83
-
84 82
 	startAllInOne, _ := start.NewCommandStartAllInOne()
85 83
 	root.AddCommand(startAllInOne)
86 84
 	root.AddCommand(admin.NewCommandAdmin("admin", "openshift admin", os.Stdout))
... ...
@@ -20,14 +20,15 @@ func (templater *Templater) UsageFunc() func(*cobra.Command) error {
20 20
 		t := template.New("custom")
21 21
 
22 22
 		t.Funcs(template.FuncMap{
23
-			"trim": strings.TrimSpace,
24
-			"gt":   cobra.Gt,
25
-			"eq":   cobra.Eq,
26
-			"rpad": func(s string, padding int) string {
27
-				template := fmt.Sprintf("%%-%ds", padding)
28
-				return fmt.Sprintf(template, s)
29
-			},
30
-			"exposed": func(*cobra.Command) *flag.FlagSet {
23
+			"trim":                strings.TrimSpace,
24
+			"gt":                  cobra.Gt,
25
+			"eq":                  cobra.Eq,
26
+			"rpad":                rpad,
27
+			"flagsNotIntersected": flagsNotIntersected,
28
+			"flagsUsages":         flagsUsages,
29
+			"rootCmd":             rootCmdName,
30
+			"isRootCmd":           isRootCmd,
31
+			"exposed": func(c *cobra.Command) *flag.FlagSet {
31 32
 				exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
32 33
 				if len(templater.Exposed) > 0 {
33 34
 					for _, name := range templater.Exposed {
... ...
@@ -38,36 +39,6 @@ func (templater *Templater) UsageFunc() func(*cobra.Command) error {
38 38
 				}
39 39
 				return exposed
40 40
 			},
41
-			"flagsNotIntersected": func(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
42
-				f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
43
-				l.VisitAll(func(flag *flag.Flag) {
44
-					if r.Lookup(flag.Name) == nil {
45
-						f.AddFlag(flag)
46
-					}
47
-				})
48
-				return f
49
-			},
50
-			"flagsUsages": func(f *flag.FlagSet) string {
51
-				x := new(bytes.Buffer)
52
-
53
-				f.VisitAll(func(flag *flag.Flag) {
54
-					format := "--%s=%s: %s\n"
55
-
56
-					if flag.Value.Type() == "string" {
57
-						format = "--%s='%s': %s\n"
58
-					}
59
-
60
-					if len(flag.Shorthand) > 0 {
61
-						format = "  -%s, " + format
62
-					} else {
63
-						format = "   %s   " + format
64
-					}
65
-
66
-					fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
67
-				})
68
-
69
-				return x.String()
70
-			},
71 41
 		})
72 42
 
73 43
 		template.Must(t.Parse(templater.UsageTemplate))
... ...
@@ -75,18 +46,6 @@ func (templater *Templater) UsageFunc() func(*cobra.Command) error {
75 75
 	}
76 76
 }
77 77
 
78
-func UseCliTemplates(cmd *cobra.Command) {
79
-	cmd.SetHelpTemplate(CliHelpTemplate())
80
-	templater := &Templater{UsageTemplate: CliUsageTemplate()}
81
-	cmd.SetUsageFunc(templater.UsageFunc())
82
-}
83
-
84
-func UseAdminTemplates(cmd *cobra.Command) {
85
-	cmd.SetHelpTemplate(AdminHelpTemplate())
86
-	templater := &Templater{UsageTemplate: AdminUsageTemplate()}
87
-	cmd.SetUsageFunc(templater.UsageFunc())
88
-}
89
-
90 78
 func UseMainTemplates(cmd *cobra.Command) {
91 79
 	cmd.SetHelpTemplate(MainHelpTemplate())
92 80
 	templater := &Templater{UsageTemplate: MainUsageTemplate()}
... ...
@@ -98,3 +57,72 @@ func UseOptionsTemplates(cmd *cobra.Command) {
98 98
 	templater := &Templater{UsageTemplate: OptionsUsageTemplate()}
99 99
 	cmd.SetUsageFunc(templater.UsageFunc())
100 100
 }
101
+
102
+func rootCmd(c *cobra.Command) []string {
103
+	root := []string{}
104
+
105
+	var appendCmdName func(*cobra.Command)
106
+	appendCmdName = func(x *cobra.Command) {
107
+		if x.HasParent() {
108
+			appendCmdName(x.Parent())
109
+			root = append(root, x.Parent().Name())
110
+		}
111
+	}
112
+	appendCmdName(c)
113
+
114
+	if cName := c.Name(); c.HasSubCommands() && len(root) == 1 && root[0] == "openshift" && cName != "openshift" {
115
+		root = append(root, cName)
116
+	}
117
+
118
+	if len(root) == 0 {
119
+		root = append(root, c.Name())
120
+	}
121
+
122
+	return root
123
+}
124
+
125
+func rootCmdName(c *cobra.Command) string {
126
+	return strings.Join(rootCmd(c), " ")
127
+}
128
+
129
+func isRootCmd(c *cobra.Command) bool {
130
+	r := rootCmd(c)
131
+	return c.HasSubCommands() && r[len(r)-1] == c.Name()
132
+}
133
+
134
+func flagsUsages(f *flag.FlagSet) string {
135
+	x := new(bytes.Buffer)
136
+
137
+	f.VisitAll(func(flag *flag.Flag) {
138
+		format := "--%s=%s: %s\n"
139
+
140
+		if flag.Value.Type() == "string" {
141
+			format = "--%s='%s': %s\n"
142
+		}
143
+
144
+		if len(flag.Shorthand) > 0 {
145
+			format = "  -%s, " + format
146
+		} else {
147
+			format = "   %s   " + format
148
+		}
149
+
150
+		fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
151
+	})
152
+
153
+	return x.String()
154
+}
155
+
156
+func rpad(s string, padding int) string {
157
+	template := fmt.Sprintf("%%-%ds", padding)
158
+	return fmt.Sprintf(template, s)
159
+}
160
+
161
+func flagsNotIntersected(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
162
+	f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
163
+	l.VisitAll(func(flag *flag.Flag) {
164
+		if r.Lookup(flag.Name) == nil {
165
+			f.AddFlag(flag)
166
+		}
167
+	})
168
+	return f
169
+}
... ...
@@ -7,23 +7,7 @@ func MainHelpTemplate() string {
7 7
 }
8 8
 
9 9
 func MainUsageTemplate() string {
10
-	return decorate(mainUsageTemplate, false)
11
-}
12
-
13
-func CliHelpTemplate() string {
14
-	return decorate(cliHelpTemplate, false)
15
-}
16
-
17
-func CliUsageTemplate() string {
18
-	return decorate(cliUsageTemplate, true)
19
-}
20
-
21
-func AdminHelpTemplate() string {
22
-	return decorate(adminHelpTemplate, false)
23
-}
24
-
25
-func AdminUsageTemplate() string {
26
-	return decorate(adminUsageTemplate, true)
10
+	return decorate(mainUsageTemplate, true)
27 11
 }
28 12
 
29 13
 func OptionsHelpTemplate() string {
... ...
@@ -36,65 +20,29 @@ func OptionsUsageTemplate() string {
36 36
 
37 37
 func decorate(template string, trim bool) string {
38 38
 	if trim && len(strings.Trim(template, " ")) > 0 {
39
-		trimmed := strings.Trim(template, "\n")
40
-		return funcs + trimmed
39
+		template = strings.Trim(template, "\n")
41 40
 	}
42
-	return funcs + template
41
+	return template
43 42
 }
44 43
 
45 44
 const (
46
-	// TODO: $isRootCmd should be done in code, not in the template
47
-	funcIsRootCmd = `{{$isRootCmd := or (and (eq .Name "cli") (eq .Root.Name "openshift")) (eq .Name "osc") (and (eq .Name "admin") (eq .Root.Name "openshift")) (eq .Name "osadm")}}`
48
-	funcRootCli   = `{{define "rootCli"}}{{if eq .Root.Name "osadm"}}osadm{{else}}{{if eq .Root.Name "osc"}}osc{{else}}openshift {{.Name}}{{end}}{{end}}{{end}}`
49
-	funcs         = funcIsRootCmd + funcRootCli
45
+	vars = `{{$isRootCmd := isRootCmd .}}` +
46
+		`{{$rootCmd := rootCmd .}}` +
47
+		`{{$explicitlyExposedFlags := exposed .}}` +
48
+		`{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}`
50 49
 
51 50
 	mainHelpTemplate = `{{.Long | trim}}
52 51
 {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
53 52
 
54
-	mainUsageTemplate = `{{ $cmd := . }}
55
-Usage: {{if .Runnable}}
56
-  {{.UseLine}}{{if .HasFlags}} [options]{{end}}{{end}}{{if .HasSubCommands}}
57
-  {{ .CommandPath}} <command>{{end}}{{if gt .Aliases 0}}
58
-
59
-Aliases:
60
-  {{.NameAndAliases}}{{end}}
61
-{{ if .HasSubCommands}}
62
-Available Commands: {{range .Commands}}{{if .Runnable}}
63
-  {{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}}
64
-{{end}}
65
-{{ if .HasLocalFlags}}Options:
66
-{{flagsUsages .LocalFlags}}{{end}}
67
-{{ if .HasInheritedFlags}}Global Options:
68
-{{flagsUsages .InheritedFlags}}{{end}}{{ if .HasSubCommands }}
69
-Use "{{.Root.Name}} <command> --help" for more information about a given command.
70
-{{end}}`
71
-
72
-	cliHelpTemplate = `{{.Long | trim}}
73
-{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
74
-
75
-	cliUsageTemplate = `{{ $cmd := . }}{{$explicitlyExposedFlags := exposed .}}{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}{{ if .HasSubCommands}}
76
-Available Commands: {{range .Commands}}{{if .Runnable}}{{if ne .Name "options"}}
77
-  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}
78
-{{end}}
79
-{{ if or $localNotPersistentFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
80
-{{ if $localNotPersistentFlags.HasFlags}}{{flagsUsages $localNotPersistentFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{end}}
81
-{{end}}{{ if not $isRootCmd}}Use "{{template "rootCli" .}} --help" for a list of all commands available in {{template "rootCli" .}}.
82
-{{end}}{{ if .HasSubCommands }}Use "{{template "rootCli" .}} <command> --help" for more information about a given command.
83
-{{end}}{{ if .HasInheritedFlags}}Use "{{template "rootCli" .}} options" for a list of global command-line options (applies to all commands).
84
-{{end}}`
85
-
86
-	adminHelpTemplate = `{{.Long | trim}}
87
-{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
88
-
89
-	adminUsageTemplate = `{{ $cmd := . }}{{$explicitlyExposedFlags := exposed .}}{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}{{ if .HasSubCommands}}
53
+	mainUsageTemplate = vars + `{{ $cmd := . }}{{ if .HasSubCommands}}
90 54
 Available Commands: {{range .Commands}}{{if .Runnable}}{{if ne .Name "options"}}
91 55
   {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}
92 56
 {{end}}
93 57
 {{ if or $localNotPersistentFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
94 58
 {{ if $localNotPersistentFlags.HasFlags}}{{flagsUsages $localNotPersistentFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{end}}
95
-{{end}}{{ if not $isRootCmd}}Use "{{template "rootCli" .}} --help" for a list of all commands available in {{template "rootCli" .}}.
96
-{{end}}{{ if .HasSubCommands }}Use "{{template "rootCli" .}} <command> --help" for more information about a given command.
97
-{{end}}{{ if .HasInheritedFlags}}Use "{{template "rootCli" .}} options" for a list of global command-line options (applies to all commands).
59
+{{end}}{{ if not $isRootCmd}}Use "{{$rootCmd}} --help" for a list of all commands available in {{$rootCmd}}.
60
+{{end}}{{ if .HasSubCommands }}Use "{{$rootCmd}} <command> --help" for more information about a given command.
61
+{{end}}{{ if and .HasInheritedFlags (not $isRootCmd)}}Use "{{$rootCmd}} options" for a list of global command-line options (applies to all commands).
98 62
 {{end}}`
99 63
 
100 64
 	optionsHelpTemplate = ``