diff --git a/pkg/cmd/cli/cli.go b/pkg/cmd/cli/cli.go index a17c00fd61d7..d7cc4ce56eca 100644 --- a/pkg/cmd/cli/cli.go +++ b/pkg/cmd/cli/cli.go @@ -59,8 +59,7 @@ func NewCommandCLI(name, fullName string) *cobra.Command { in := os.Stdin out := os.Stdout - cmds.SetUsageTemplate(templates.CliUsageTemplate()) - cmds.SetHelpTemplate(templates.CliHelpTemplate()) + templates.UseCliTemplates(cmds) cmds.AddCommand(cmd.NewCmdLogin(f, in, out)) cmds.AddCommand(cmd.NewCmdNewApplication(fullName, f, out)) diff --git a/pkg/cmd/cli/cmd/login.go b/pkg/cmd/cli/cmd/login.go index 59168fe35f70..60d44bbaa9e1 100644 --- a/pkg/cmd/cli/cmd/login.go +++ b/pkg/cmd/cli/cmd/login.go @@ -8,11 +8,12 @@ import ( cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util" "github.com/openshift/origin/pkg/cmd/cli/config" + "github.com/openshift/origin/pkg/cmd/templates" osclientcmd "github.com/openshift/origin/pkg/cmd/util/clientcmd" ) -const longDescription = `Logs in to the OpenShift server and save the session -information to a config file that will be used by every subsequent command. +const longDescription = `Logs in to the OpenShift server and save the session information to a config file that +will be used by every subsequent command. First-time users of the OpenShift client must run this command to configure the server, establish a session against it and save it to a configuration file, usually in the @@ -52,5 +53,13 @@ func NewCmdLogin(f *osclientcmd.Factory, reader io.Reader, out io.Writer) *cobra // Login is the only command that can negotiate a session token against the auth server. cmds.Flags().StringVarP(&options.Username, "username", "u", "", "Username, will prompt if not provided") cmds.Flags().StringVarP(&options.Password, "password", "p", "", "Password, will prompt if not provided") + + templater := templates.Templater{ + UsageTemplate: templates.CliUsageTemplate(), + Exposed: []string{"server", "username", "password", "certificate-authority", "insecure-skip-tls-verify", "context"}, + } + cmds.SetUsageFunc(templater.UsageFunc()) + cmds.SetHelpTemplate(templates.CliHelpTemplate()) + return cmds } diff --git a/pkg/cmd/cli/cmd/options.go b/pkg/cmd/cli/cmd/options.go index 894193fbcec0..73e8d20b962b 100644 --- a/pkg/cmd/cli/cmd/options.go +++ b/pkg/cmd/cli/cmd/options.go @@ -17,8 +17,7 @@ func NewCmdOptions(f *clientcmd.Factory, out io.Writer) *cobra.Command { }, } - cmd.SetUsageTemplate(templates.OptionsUsageTemplate()) - cmd.SetHelpTemplate(templates.OptionsHelpTemplate()) + templates.UseOptionsTemplates(cmd) return cmd } diff --git a/pkg/cmd/infra/builder/builder.go b/pkg/cmd/infra/builder/builder.go index 15c31f07c1c9..197099e7054c 100644 --- a/pkg/cmd/infra/builder/builder.go +++ b/pkg/cmd/infra/builder/builder.go @@ -25,8 +25,9 @@ func NewCommandSTIBuilder(name string) *cobra.Command { cmd.RunSTIBuild() }, } - cmd.SetUsageTemplate(templates.MainUsageTemplate()) - cmd.SetHelpTemplate(templates.MainHelpTemplate()) + + templates.UseMainTemplates(cmd) + cmd.AddCommand(version.NewVersionCommand(name)) return cmd } diff --git a/pkg/cmd/infra/deployer/deployer.go b/pkg/cmd/infra/deployer/deployer.go index 8279b59a9079..eb260c72d2ec 100644 --- a/pkg/cmd/infra/deployer/deployer.go +++ b/pkg/cmd/infra/deployer/deployer.go @@ -67,8 +67,8 @@ func NewCommandDeployer(name string) *cobra.Command { }, } - cmd.SetUsageTemplate(templates.MainUsageTemplate()) - cmd.SetHelpTemplate(templates.MainHelpTemplate()) + templates.UseMainTemplates(cmd) + cmd.AddCommand(version.NewVersionCommand(name)) flag := cmd.Flags() diff --git a/pkg/cmd/infra/router/router.go b/pkg/cmd/infra/router/router.go index e07a816cea85..580a0bfc53a5 100644 --- a/pkg/cmd/infra/router/router.go +++ b/pkg/cmd/infra/router/router.go @@ -52,8 +52,8 @@ func NewCommandTemplateRouter(name string) *cobra.Command { }, } - cmd.SetUsageTemplate(templates.MainUsageTemplate()) - cmd.SetHelpTemplate(templates.MainHelpTemplate()) + templates.UseMainTemplates(cmd) + cmd.AddCommand(version.NewVersionCommand(name)) flag := cmd.Flags() diff --git a/pkg/cmd/openshift/openshift.go b/pkg/cmd/openshift/openshift.go index ea3ca104d531..a1eefaaa8f94 100644 --- a/pkg/cmd/openshift/openshift.go +++ b/pkg/cmd/openshift/openshift.go @@ -76,8 +76,7 @@ func NewCommandOpenShift() *cobra.Command { }, } - root.SetUsageTemplate(templates.MainUsageTemplate()) - root.SetHelpTemplate(templates.MainHelpTemplate()) + templates.UseMainTemplates(root) startAllInOne, _ := start.NewCommandStartAllInOne() root.AddCommand(startAllInOne) diff --git a/pkg/cmd/templates/templater.go b/pkg/cmd/templates/templater.go new file mode 100644 index 000000000000..85e4a3abdac1 --- /dev/null +++ b/pkg/cmd/templates/templater.go @@ -0,0 +1,63 @@ +package templates + +import ( + "fmt" + "strings" + "text/template" + + "github.com/spf13/cobra" + flag "github.com/spf13/pflag" +) + +type Templater struct { + UsageTemplate string + Exposed []string +} + +func (templater *Templater) UsageFunc() func(*cobra.Command) error { + return func(c *cobra.Command) error { + t := template.New("custom") + + t.Funcs(template.FuncMap{ + "trim": strings.TrimSpace, + "gt": cobra.Gt, + "eq": cobra.Eq, + "rpad": func(s string, padding int) string { + template := fmt.Sprintf("%%-%ds", padding) + return fmt.Sprintf(template, s) + }, + "exposed": func(*cobra.Command) *flag.FlagSet { + exposed := flag.NewFlagSet("exposed", flag.ContinueOnError) + if len(templater.Exposed) > 0 { + for _, name := range templater.Exposed { + if flag := c.Flags().Lookup(name); flag != nil { + exposed.AddFlag(flag) + } + } + } + return exposed + }, + }) + + template.Must(t.Parse(templater.UsageTemplate)) + return t.Execute(c.Out(), c) + } +} + +func UseCliTemplates(cmd *cobra.Command) { + cmd.SetHelpTemplate(CliHelpTemplate()) + templater := &Templater{UsageTemplate: CliUsageTemplate()} + cmd.SetUsageFunc(templater.UsageFunc()) +} + +func UseMainTemplates(cmd *cobra.Command) { + cmd.SetHelpTemplate(MainHelpTemplate()) + templater := &Templater{UsageTemplate: MainUsageTemplate()} + cmd.SetUsageFunc(templater.UsageFunc()) +} + +func UseOptionsTemplates(cmd *cobra.Command) { + cmd.SetHelpTemplate(OptionsHelpTemplate()) + templater := &Templater{UsageTemplate: OptionsUsageTemplate()} + cmd.SetUsageFunc(templater.UsageFunc()) +} diff --git a/pkg/cmd/templates/templates.go b/pkg/cmd/templates/templates.go index 3a5b677cc2be..e49e5781b7b9 100644 --- a/pkg/cmd/templates/templates.go +++ b/pkg/cmd/templates/templates.go @@ -2,14 +2,6 @@ package templates import "strings" -func decorate(template string, trim bool) string { - if trim && len(strings.Trim(template, " ")) > 0 { - trimmed := strings.Trim(template, "\n") - return funcs + trimmed - } - return funcs + template -} - func MainHelpTemplate() string { return decorate(mainHelpTemplate, false) } @@ -34,6 +26,14 @@ func OptionsUsageTemplate() string { return decorate(optionsUsageTemplate, false) } +func decorate(template string, trim bool) string { + if trim && len(strings.Trim(template, " ")) > 0 { + trimmed := strings.Trim(template, "\n") + return funcs + trimmed + } + return funcs + template +} + const ( funcs = `{{$isRootCmd := or (and (eq .Name "cli") (eq .Root.Name "openshift")) (eq .Name "osc")}}{{define "rootCli"}}{{if eq .Root.Name "osc"}}osc{{else}}openshift cli{{end}}{{end}}` @@ -61,12 +61,12 @@ Use "{{.Root.Name}} --help" for more information about a given command cliHelpTemplate = `{{.Long | trim}} {{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` - cliUsageTemplate = `{{ $cmd := . }}{{ if .HasSubCommands}} + cliUsageTemplate = `{{ $cmd := . }}{{$exposedFlags := exposed .}}{{ if .HasSubCommands}} Available Commands: {{range .Commands}}{{if .Runnable}}{{if ne .Name "options"}} {{rpad .Name 20 }}{{.Short}}{{end}}{{end}}{{end}} {{end}} -{{ if .HasLocalFlags}}Options: -{{.LocalFlags.FlagUsages}} +{{ if or .HasLocalFlags $exposedFlags.HasFlags}}Options: +{{ if .HasLocalFlags}}{{.LocalFlags.FlagUsages}}{{end}}{{ if $exposedFlags.HasFlags}}{{$exposedFlags.FlagUsages}}{{end}} {{end}}{{ if not $isRootCmd}}Use "{{template "rootCli" .}} --help" for a list of all commands available in {{template "rootCli" .}}. {{end}}{{ if .HasSubCommands }}Use "{{template "rootCli" .}} --help" for more information about a given command. {{end}}{{ if .HasAnyPersistentFlags}}Use "{{template "rootCli" .}} options" for a list of global command-line options (applies to all commands).