Skip to content

Commit

Permalink
Integrating help and usage templates in all commands
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianofranz committed Apr 2, 2015
1 parent f2580dd commit ae0b905
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 135 deletions.
3 changes: 0 additions & 3 deletions pkg/cmd/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
exregistry "github.com/openshift/origin/pkg/cmd/experimental/registry"
exrouter "github.com/openshift/origin/pkg/cmd/experimental/router"
"github.com/openshift/origin/pkg/cmd/server/admin"
"github.com/openshift/origin/pkg/cmd/templates"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
"github.com/openshift/origin/pkg/version"
)
Expand Down Expand Up @@ -43,8 +42,6 @@ func NewCommandAdmin(name, fullName string, out io.Writer) *cobra.Command {

f := clientcmd.New(cmds.PersistentFlags())

templates.UseAdminTemplates(cmds)

cmds.AddCommand(project.NewCmdNewProject(f, fullName, "new-project"))
cmds.AddCommand(policy.NewCommandPolicy(f, fullName, "policy"))
cmds.AddCommand(exrouter.NewCmdRouter(f, fullName, "router", out))
Expand Down
3 changes: 0 additions & 3 deletions pkg/cmd/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/openshift/origin/pkg/cmd/cli/cmd"
"github.com/openshift/origin/pkg/cmd/experimental/config"
"github.com/openshift/origin/pkg/cmd/templates"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
"github.com/openshift/origin/pkg/version"
)
Expand Down Expand Up @@ -62,8 +61,6 @@ func NewCommandCLI(name, fullName string) *cobra.Command {
in := os.Stdin
out := os.Stdout

templates.UseCliTemplates(cmds)

cmds.AddCommand(cmd.NewCmdLogin(f, in, out))
cmds.AddCommand(cmd.NewCmdProject(f, out))
cmds.AddCommand(cmd.NewCmdNewApplication(fullName, f, out))
Expand Down
6 changes: 3 additions & 3 deletions pkg/cmd/cli/cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ func NewCmdLogin(f *osclientcmd.Factory, reader io.Reader, out io.Writer) *cobra
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"},
UsageTemplate: templates.MainUsageTemplate(),
Exposed: []string{"server", "certificate-authority", "insecure-skip-tls-verify", "context"},
}
cmds.SetUsageFunc(templater.UsageFunc())
cmds.SetHelpTemplate(templates.CliHelpTemplate())
cmds.SetHelpTemplate(templates.MainHelpTemplate())

return cmds
}
Expand Down
5 changes: 0 additions & 5 deletions pkg/cmd/infra/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/spf13/cobra"

"github.com/openshift/origin/pkg/build/builder/cmd"
"github.com/openshift/origin/pkg/cmd/templates"
"github.com/openshift/origin/pkg/version"
)

Expand All @@ -26,8 +25,6 @@ func NewCommandSTIBuilder(name string) *cobra.Command {
},
}

templates.UseMainTemplates(cmd)

cmd.AddCommand(version.NewVersionCommand(name))
return cmd
}
Expand All @@ -49,8 +46,6 @@ func NewCommandDockerBuilder(name string) *cobra.Command {
cmd.RunDockerBuild()
},
}
cmd.SetUsageTemplate(templates.MainUsageTemplate())
cmd.SetHelpTemplate(templates.MainHelpTemplate())
cmd.AddCommand(version.NewVersionCommand(name))
return cmd
}
3 changes: 0 additions & 3 deletions pkg/cmd/infra/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/spf13/cobra"

"github.com/openshift/origin/pkg/api/latest"
"github.com/openshift/origin/pkg/cmd/templates"
"github.com/openshift/origin/pkg/cmd/util"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
deployapi "github.com/openshift/origin/pkg/deploy/api"
Expand Down Expand Up @@ -67,8 +66,6 @@ func NewCommandDeployer(name string) *cobra.Command {
},
}

templates.UseMainTemplates(cmd)

cmd.AddCommand(version.NewVersionCommand(name))

flag := cmd.Flags()
Expand Down
3 changes: 0 additions & 3 deletions pkg/cmd/infra/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"

"github.com/openshift/origin/pkg/cmd/templates"
"github.com/openshift/origin/pkg/cmd/util"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
"github.com/openshift/origin/pkg/router"
Expand Down Expand Up @@ -52,8 +51,6 @@ func NewCommandTemplateRouter(name string) *cobra.Command {
},
}

templates.UseMainTemplates(cmd)

cmd.AddCommand(version.NewVersionCommand(name))

flag := cmd.Flags()
Expand Down
3 changes: 1 addition & 2 deletions pkg/cmd/openshift/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func CommandFor(basename string) *cobra.Command {
cmd = NewCommandOpenShift()
}

templates.UseMainTemplates(cmd)
flagtypes.GLog(cmd.PersistentFlags())

return cmd
Expand All @@ -79,8 +80,6 @@ func NewCommandOpenShift() *cobra.Command {
},
}

templates.UseMainTemplates(root)

startAllInOne, _ := start.NewCommandStartAllInOne()
root.AddCommand(startAllInOne)
root.AddCommand(admin.NewCommandAdmin("admin", "openshift admin", os.Stdout))
Expand Down
128 changes: 78 additions & 50 deletions pkg/cmd/templates/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ func (templater *Templater) UsageFunc() func(*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 {
"trim": strings.TrimSpace,
"gt": cobra.Gt,
"eq": cobra.Eq,
"rpad": rpad,
"flagsNotIntersected": flagsNotIntersected,
"flagsUsages": flagsUsages,
"rootCmd": rootCmdName,
"isRootCmd": isRootCmd,
"exposed": func(c *cobra.Command) *flag.FlagSet {
exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
if len(templater.Exposed) > 0 {
for _, name := range templater.Exposed {
Expand All @@ -38,55 +39,13 @@ func (templater *Templater) UsageFunc() func(*cobra.Command) error {
}
return exposed
},
"flagsNotIntersected": func(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
l.VisitAll(func(flag *flag.Flag) {
if r.Lookup(flag.Name) == nil {
f.AddFlag(flag)
}
})
return f
},
"flagsUsages": func(f *flag.FlagSet) string {
x := new(bytes.Buffer)

f.VisitAll(func(flag *flag.Flag) {
format := "--%s=%s: %s\n"

if flag.Value.Type() == "string" {
format = "--%s='%s': %s\n"
}

if len(flag.Shorthand) > 0 {
format = " -%s, " + format
} else {
format = " %s " + format
}

fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
})

return x.String()
},
})

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 UseAdminTemplates(cmd *cobra.Command) {
cmd.SetHelpTemplate(AdminHelpTemplate())
templater := &Templater{UsageTemplate: AdminUsageTemplate()}
cmd.SetUsageFunc(templater.UsageFunc())
}

func UseMainTemplates(cmd *cobra.Command) {
cmd.SetHelpTemplate(MainHelpTemplate())
templater := &Templater{UsageTemplate: MainUsageTemplate()}
Expand All @@ -98,3 +57,72 @@ func UseOptionsTemplates(cmd *cobra.Command) {
templater := &Templater{UsageTemplate: OptionsUsageTemplate()}
cmd.SetUsageFunc(templater.UsageFunc())
}

func rootCmd(c *cobra.Command) []string {
root := []string{}

var appendCmdName func(*cobra.Command)
appendCmdName = func(x *cobra.Command) {
if x.HasParent() {
appendCmdName(x.Parent())
root = append(root, x.Parent().Name())
}
}
appendCmdName(c)

if cName := c.Name(); c.HasSubCommands() && len(root) == 1 && root[0] == "openshift" && cName != "openshift" {
root = append(root, cName)
}

if len(root) == 0 {
root = append(root, c.Name())
}

return root
}

func rootCmdName(c *cobra.Command) string {
return strings.Join(rootCmd(c), " ")
}

func isRootCmd(c *cobra.Command) bool {
r := rootCmd(c)
return c.HasSubCommands() && r[len(r)-1] == c.Name()
}

func flagsUsages(f *flag.FlagSet) string {
x := new(bytes.Buffer)

f.VisitAll(func(flag *flag.Flag) {
format := "--%s=%s: %s\n"

if flag.Value.Type() == "string" {
format = "--%s='%s': %s\n"
}

if len(flag.Shorthand) > 0 {
format = " -%s, " + format
} else {
format = " %s " + format
}

fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
})

return x.String()
}

func rpad(s string, padding int) string {
template := fmt.Sprintf("%%-%ds", padding)
return fmt.Sprintf(template, s)
}

func flagsNotIntersected(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
l.VisitAll(func(flag *flag.Flag) {
if r.Lookup(flag.Name) == nil {
f.AddFlag(flag)
}
})
return f
}
74 changes: 11 additions & 63 deletions pkg/cmd/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,7 @@ func MainHelpTemplate() string {
}

func MainUsageTemplate() string {
return decorate(mainUsageTemplate, false)
}

func CliHelpTemplate() string {
return decorate(cliHelpTemplate, false)
}

func CliUsageTemplate() string {
return decorate(cliUsageTemplate, true)
}

func AdminHelpTemplate() string {
return decorate(adminHelpTemplate, false)
}

func AdminUsageTemplate() string {
return decorate(adminUsageTemplate, true)
return decorate(mainUsageTemplate, true)
}

func OptionsHelpTemplate() string {
Expand All @@ -36,65 +20,29 @@ func OptionsUsageTemplate() string {

func decorate(template string, trim bool) string {
if trim && len(strings.Trim(template, " ")) > 0 {
trimmed := strings.Trim(template, "\n")
return funcs + trimmed
template = strings.Trim(template, "\n")
}
return funcs + template
return template
}

const (
// TODO: $isRootCmd should be done in code, not in the template
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")}}`
funcRootCli = `{{define "rootCli"}}{{if eq .Root.Name "osadm"}}osadm{{else}}{{if eq .Root.Name "osc"}}osc{{else}}openshift {{.Name}}{{end}}{{end}}{{end}}`
funcs = funcIsRootCmd + funcRootCli
vars = `{{$isRootCmd := isRootCmd .}}` +
`{{$rootCmd := rootCmd .}}` +
`{{$explicitlyExposedFlags := exposed .}}` +
`{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}`

mainHelpTemplate = `{{.Long | trim}}
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`

mainUsageTemplate = `{{ $cmd := . }}
Usage: {{if .Runnable}}
{{.UseLine}}{{if .HasFlags}} [options]{{end}}{{end}}{{if .HasSubCommands}}
{{ .CommandPath}} <command>{{end}}{{if gt .Aliases 0}}
Aliases:
{{.NameAndAliases}}{{end}}
{{ if .HasSubCommands}}
Available Commands: {{range .Commands}}{{if .Runnable}}
{{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}}
{{end}}
{{ if .HasLocalFlags}}Options:
{{flagsUsages .LocalFlags}}{{end}}
{{ if .HasInheritedFlags}}Global Options:
{{flagsUsages .InheritedFlags}}{{end}}{{ if .HasSubCommands }}
Use "{{.Root.Name}} <command> --help" for more information about a given command.
{{end}}`

cliHelpTemplate = `{{.Long | trim}}
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`

cliUsageTemplate = `{{ $cmd := . }}{{$explicitlyExposedFlags := exposed .}}{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}{{ if .HasSubCommands}}
Available Commands: {{range .Commands}}{{if .Runnable}}{{if ne .Name "options"}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}
{{end}}
{{ if or $localNotPersistentFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
{{ if $localNotPersistentFlags.HasFlags}}{{flagsUsages $localNotPersistentFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{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" .}} <command> --help" for more information about a given command.
{{end}}{{ if .HasInheritedFlags}}Use "{{template "rootCli" .}} options" for a list of global command-line options (applies to all commands).
{{end}}`

adminHelpTemplate = `{{.Long | trim}}
{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`

adminUsageTemplate = `{{ $cmd := . }}{{$explicitlyExposedFlags := exposed .}}{{$localNotPersistentFlags := flagsNotIntersected .LocalFlags .PersistentFlags}}{{ if .HasSubCommands}}
mainUsageTemplate = vars + `{{ $cmd := . }}{{ if .HasSubCommands}}
Available Commands: {{range .Commands}}{{if .Runnable}}{{if ne .Name "options"}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}
{{end}}
{{ if or $localNotPersistentFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
{{ if $localNotPersistentFlags.HasFlags}}{{flagsUsages $localNotPersistentFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{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" .}} <command> --help" for more information about a given command.
{{end}}{{ if .HasInheritedFlags}}Use "{{template "rootCli" .}} options" for a list of global command-line options (applies to all commands).
{{end}}{{ if not $isRootCmd}}Use "{{$rootCmd}} --help" for a list of all commands available in {{$rootCmd}}.
{{end}}{{ if .HasSubCommands }}Use "{{$rootCmd}} <command> --help" for more information about a given command.
{{end}}{{ if and .HasInheritedFlags (not $isRootCmd)}}Use "{{$rootCmd}} options" for a list of global command-line options (applies to all commands).
{{end}}`

optionsHelpTemplate = ``
Expand Down

0 comments on commit ae0b905

Please sign in to comment.