// Complete sets any default behavior for the command func (o *NewAppOptions) Complete(commandName string, f *clientcmd.Factory, c *cobra.Command, args []string, out io.Writer) error { o.Out = out o.ErrOut = c.Out() o.Output = kcmdutil.GetFlagString(c, "output") // Only output="" should print descriptions of intermediate steps. Everything // else should print only some specific output (json, yaml, go-template, ...) if len(o.Output) == 0 { o.Config.Out = o.Out } else { o.Config.Out = ioutil.Discard } o.Config.ErrOut = o.ErrOut o.Action.Out, o.Action.ErrOut = o.Out, o.ErrOut o.Action.Bulk.Mapper = clientcmd.ResourceMapper(f) o.Action.Bulk.Op = configcmd.Create // Retry is used to support previous versions of the API server that will // consider the presence of an unknown trigger type to be an error. o.Action.Bulk.Retry = retryBuildConfig o.Config.DryRun = o.Action.DryRun o.CommandPath = c.CommandPath() o.CommandName = commandName mapper, _ := f.Object(false) o.PrintObject = cmdutil.VersionedPrintObject(f.PrintObject, c, mapper, out) o.LogsForObject = f.LogsForObject if err := CompleteAppConfig(o.Config, f, c, args); err != nil { return err } if err := setAppConfigLabels(c, o.Config); err != nil { return err } return nil }
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil { return err } } basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md" filename := filepath.Join(dir, basename) f, err := os.Create(filename) if err != nil { return err } defer f.Close() if _, err := io.WriteString(f, filePrepender(filename)); err != nil { return err } if err := GenMarkdownCustom(cmd, f, linkHandler); err != nil { return err } return nil }
func handleBuildError(c *cobra.Command, err error, fullName string) error { if err == nil { return nil } if errs, ok := err.(errors.Aggregate); ok { if len(errs.Errors()) == 1 { err = errs.Errors()[0] } } switch t := err.(type) { case newapp.ErrNoMatch: return fmt.Errorf(`%[1]v The '%[2]s' command will match arguments to the following types: 1. Images tagged into image streams in the current project or the 'openshift' project - if you don't specify a tag, we'll add ':latest' 2. Images in the Docker Hub, on remote registries, or on the local Docker engine 3. Git repository URLs or local paths that point to Git repositories --allow-missing-images can be used to point to an image that does not exist yet or is only on the local system. See '%[2]s -h' for examples. `, t, c.CommandPath()) } switch err { case newcmd.ErrNoInputs: // TODO: suggest things to the user return cmdutil.UsageError(c, newBuildNoInput, fullName) default: return err } }
// Complete sets any default behavior for the command func (o *NewAppOptions) Complete(commandName string, f *clientcmd.Factory, c *cobra.Command, args []string, out io.Writer) error { o.Out = out o.ErrOut = c.Out() o.Output = kcmdutil.GetFlagString(c, "output") // Only output="" should print descriptions of intermediate steps. Everything // else should print only some specific output (json, yaml, go-template, ...) if len(o.Output) == 0 { o.Config.Out = o.Out } else { o.Config.Out = ioutil.Discard } o.Config.ErrOut = o.ErrOut o.CommandPath = c.CommandPath() o.CommandName = commandName o.PrintObject = cmdutil.VersionedPrintObject(f.PrintObject, c, out) o.LogsForObject = f.LogsForObject if err := CompleteAppConfig(o.Config, f, c, args); err != nil { return err } if err := setAppConfigLabels(c, o.Config); err != nil { return err } return nil }
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string) string) { for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler) } out := new(bytes.Buffer) GenMarkdownCustom(cmd, out, linkHandler) filename := cmd.CommandPath() filename = dir + strings.Replace(filename, " ", "_", -1) + ".md" outFile, err := os.Create(filename) if err != nil { fmt.Println(err) os.Exit(1) } defer outFile.Close() _, err = outFile.WriteString(filePrepender(filename)) if err != nil { fmt.Println(err) os.Exit(1) } _, err = outFile.Write(out.Bytes()) if err != nil { fmt.Println(err) os.Exit(1) } }
// GenManTreeFromOpts generates a man page for the command and all descendants. // The pages are written to the opts.Path directory. func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error { header := opts.Header if header == nil { header = &GenManHeader{} } for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } if err := GenManTreeFromOpts(c, opts); err != nil { return err } } section := "1" if header.Section != "" { section = header.Section } separator := "_" if opts.CommandSeparator != "" { separator = opts.CommandSeparator } basename := strings.Replace(cmd.CommandPath(), " ", separator, -1) filename := filepath.Join(opts.Path, basename+"."+section) f, err := os.Create(filename) if err != nil { return err } defer f.Close() headerCopy := *header return GenMan(cmd, &headerCopy, f) }
// GenManTree will generate a man page for this command and all decendants // in the directory given. The header may be nil. This function may not work // correctly if your command names have - in them. If you have `cmd` with two // subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third` // it is undefined which help output will be in the file `cmd-sub-third.1`. func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) { if header == nil { header = &GenManHeader{} } for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } GenManTree(c, header, dir) } out := new(bytes.Buffer) needToResetTitle := header.Title == "" GenMan(cmd, header, out) if needToResetTitle { header.Title = "" } filename := cmd.CommandPath() filename = dir + strings.Replace(filename, " ", "-", -1) + ".1" outFile, err := os.Create(filename) if err != nil { fmt.Println(err) os.Exit(1) } defer outFile.Close() _, err = outFile.Write(out.Bytes()) if err != nil { fmt.Println(err) os.Exit(1) } }
func CheckCmdTree(cmd *cobra.Command, checks []CmdCheck, skip []string) []error { cmdPath := cmd.CommandPath() for _, skipCmdPath := range skip { if cmdPath == skipCmdPath { fmt.Fprintf(os.Stdout, "-----+ skipping command %s\n", cmdPath) return []error{} } } errors := []error{} if cmd.HasSubCommands() { for _, subCmd := range cmd.Commands() { errors = append(errors, CheckCmdTree(subCmd, checks, skip)...) } } fmt.Fprintf(os.Stdout, "-----+ checking command %s\n", cmdPath) for _, check := range checks { if err := check(cmd); err != nil && len(err) > 0 { errors = append(errors, err...) } } return errors }
func tryContainer(cmd *cobra.Command, args []string) bool { if insideContainer() { return false } if !dockerExistsByName("glu") { return false } fmt.Fprintln(os.Stderr, "* Using glu container") args = append(strings.Split(cmd.CommandPath(), " "), args...) var newCmd []string var binary string var err error if os.Getenv("CIRCLECI") == "true" { if binary, err = exec.LookPath("sudo"); err != nil { return false } os.Setenv("GLU_CONTAINER", "true") newCmd = []string{"sudo", "-E", "lxc-attach", "-n", dockerID("glu"), "--", "/bin/glu"} newCmd = append(newCmd, args[1:]...) } else { if binary, err = exec.LookPath("docker"); err != nil { return false } newCmd = []string{"docker", "exec", "glu"} newCmd = append(newCmd, args...) } syscall.Exec(binary, newCmd, os.Environ()) return true }
// GenManTree will generate a man page for this command and all descendants // in the directory given. The header may be nil. This function may not work // correctly if your command names have - in them. If you have `cmd` with two // subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third` // it is undefined which help output will be in the file `cmd-sub-third.1`. func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error { if header == nil { header = &GenManHeader{} } for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } if err := GenManTree(c, header, dir); err != nil { return err } } needToResetTitle := header.Title == "" basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".1" filename := filepath.Join(dir, basename) f, err := os.Create(filename) if err != nil { return err } defer f.Close() if err := GenMan(cmd, header, f); err != nil { return err } if needToResetTitle { header.Title = "" } return nil }
// Complete verifies command line arguments and loads data from the command environment func (p *AttachOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string) error { if len(argsIn) == 0 { return cmdutil.UsageError(cmd, "POD is required for attach") } if len(argsIn) > 1 { return cmdutil.UsageError(cmd, fmt.Sprintf("expected a single argument: POD, saw %d: %s", len(argsIn), argsIn)) } p.PodName = argsIn[0] namespace, _, err := f.DefaultNamespace() if err != nil { return err } p.Namespace = namespace config, err := f.ClientConfig() if err != nil { return err } p.Config = config client, err := f.Client() if err != nil { return err } p.Client = client if p.CommandName == "" { p.CommandName = cmd.CommandPath() } return nil }
func handleRunError(c *cobra.Command, err error, fullName string) error { if err == nil { return nil } if errs, ok := err.(errors.Aggregate); ok { if len(errs.Errors()) == 1 { err = errs.Errors()[0] } } switch t := err.(type) { case newcmd.ErrRequiresExplicitAccess: if t.Input.Token != nil && t.Input.Token.ServiceAccount { return fmt.Errorf(`installing %q requires an 'installer' service account with project editor access WARNING: This will allow the pod to create and manage resources within your namespace - ensure you trust the image with those permissions before you continue. You can see more information about the image by adding the --dry-run flag. If you trust the provided image, include the flag --grant-install-rights.`, t.Match.Value) } return fmt.Errorf(`installing %q requires that you grant the image access to run with your credentials WARNING: This will allow the pod to act as you across the entire cluster - ensure you trust the image with those permissions before you continue. You can see more information about the image by adding the --dry-run flag. If you trust the provided image, include the flag --grant-install-rights.`, t.Match.Value) case newapp.ErrNoMatch: return fmt.Errorf(`%[1]v The '%[2]s' command will match arguments to the following types: 1. Images tagged into image streams in the current project or the 'openshift' project - if you don't specify a tag, we'll add ':latest' 2. Images in the Docker Hub, on remote registries, or on the local Docker engine 3. Templates in the current project or the 'openshift' project 4. Git repository URLs or local paths that point to Git repositories --allow-missing-images can be used to point to an image that does not exist yet. See '%[2]s -h' for examples. `, t, c.CommandPath()) case newapp.ErrMultipleMatches: return fmt.Errorf(err.(newapp.ErrMultipleMatches).UsageError("")) case newapp.ErrPartialMatch: return fmt.Errorf(err.(newapp.ErrPartialMatch).UsageError("")) } switch err { case errNoTokenAvailable: // TODO: improve by allowing token generation return fmt.Errorf("to install components you must be logged in with an OAuth token (instead of only a certificate)") case newcmd.ErrNoInputs: // TODO: suggest things to the user return cmdutil.UsageError(c, newAppNoInput, fullName) default: return err } }
func GenMarkdownCustom(cmd *cobra.Command, out io.Writer, linkHandler func(string) string) { name := cmd.CommandPath() short := cmd.Short long := cmd.Long if len(long) == 0 { long = short } fmt.Fprintf(out, "## %s\n\n", name) fmt.Fprintf(out, "%s\n\n", short) fmt.Fprintf(out, "### Synopsis\n\n") fmt.Fprintf(out, "\n%s\n\n", long) if cmd.Runnable() { fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.UseLine()) } if len(cmd.Example) > 0 { fmt.Fprintf(out, "### Examples\n\n") fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.Example) } printOptions(out, cmd, name) if hasSeeAlso(cmd) { fmt.Fprintf(out, "### SEE ALSO\n") if cmd.HasParent() { parent := cmd.Parent() pname := parent.CommandPath() link := pname + ".md" link = strings.Replace(link, " ", "_", -1) fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short) cmd.VisitParents(func(c *cobra.Command) { if c.DisableAutoGenTag { cmd.DisableAutoGenTag = c.DisableAutoGenTag } }) } children := cmd.Commands() sort.Sort(byName(children)) for _, child := range children { if !child.IsAvailableCommand() || child.IsHelpCommand() { continue } cname := name + " " + child.Name() link := cname + ".md" link = strings.Replace(link, " ", "_", -1) fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short) } fmt.Fprintf(out, "\n") } if !cmd.DisableAutoGenTag { fmt.Fprintf(out, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006")) } }
// GenMan will generate a man page for the given command and write it to // w. The header argument may be nil, however obviously w may not. func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error { if header == nil { header = &GenManHeader{} } fillHeader(header, cmd.CommandPath()) b := genMan(cmd, header) _, err := w.Write(mangen.Render(b)) return err }
func CheckLongDesc(cmd *cobra.Command) []error { cmdPath := cmd.CommandPath() long := cmd.Long if len(long) > 0 { if strings.Trim(long, " \t\n") != long { return []error{fmt.Errorf(`command %q: long description is not normalized ↳ make sure you are calling templates.LongDesc (from pkg/cmd/templates) before assigning cmd.Long`, cmdPath)} } } return nil }
// FlagErrorFunc prints an error messages which matches the format of the // docker/docker/cli error messages func FlagErrorFunc(cmd *cobra.Command, err error) error { if err == nil { return err } usage := "" if cmd.HasSubCommands() { usage = "\n\n" + cmd.UsageString() } return fmt.Errorf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage) }
func genMan(cmd *cobra.Command, header *GenManHeader) []byte { // something like `rootcmd subcmd1 subcmd2` commandName := cmd.CommandPath() // something like `rootcmd-subcmd1-subcmd2` dashCommandName := strings.Replace(commandName, " ", "-", -1) fillHeader(header, commandName) buf := new(bytes.Buffer) short := cmd.Short long := cmd.Long if len(long) == 0 { long = short } manPreamble(buf, header, commandName, short, long) manPrintOptions(buf, cmd) if len(cmd.Example) > 0 { fmt.Fprintf(buf, "# EXAMPLE\n") fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example) } if hasSeeAlso(cmd) { fmt.Fprintf(buf, "# SEE ALSO\n") seealsos := make([]string, 0) if cmd.HasParent() { parentPath := cmd.Parent().CommandPath() dashParentPath := strings.Replace(parentPath, " ", "-", -1) seealso := fmt.Sprintf("**%s(%s)**", dashParentPath, header.Section) seealsos = append(seealsos, seealso) cmd.VisitParents(func(c *cobra.Command) { if c.DisableAutoGenTag { cmd.DisableAutoGenTag = c.DisableAutoGenTag } }) } children := cmd.Commands() sort.Sort(byName(children)) for _, c := range children { if !c.IsAvailableCommand() || c.IsHelpCommand() { continue } seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section) seealsos = append(seealsos, seealso) } fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", ")) } if !cmd.DisableAutoGenTag { fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006")) } return buf.Bytes() }
// FlagErrorFunc prints an error message which matches the format of the // docker/docker/cli error messages func FlagErrorFunc(cmd *cobra.Command, err error) error { if err == nil { return err } usage := "" if cmd.HasSubCommands() { usage = "\n\n" + cmd.UsageString() } return StatusError{ Status: fmt.Sprintf("%s\nSee '%s --help'.%s", err, cmd.CommandPath(), usage), StatusCode: 125, } }
// Complete sets any default behavior for the command func (o *NewBuildOptions) Complete(baseName, commandName string, f *clientcmd.Factory, c *cobra.Command, args []string, out, errout io.Writer, in io.Reader) error { o.In = in o.Out = out o.ErrOut = errout o.Output = kcmdutil.GetFlagString(c, "output") // Only output="" should print descriptions of intermediate steps. Everything // else should print only some specific output (json, yaml, go-template, ...) o.Config.In = in if len(o.Output) == 0 { o.Config.Out = o.Out } else { o.Config.Out = ioutil.Discard } o.Config.ErrOut = o.ErrOut o.Action.Out, o.Action.ErrOut = o.Out, o.ErrOut o.Action.Bulk.Mapper = clientcmd.ResourceMapper(f) o.Action.Bulk.Op = configcmd.Create // Retry is used to support previous versions of the API server that will // consider the presence of an unknown trigger type to be an error. o.Action.Bulk.Retry = retryBuildConfig o.Config.DryRun = o.Action.DryRun o.Config.AllowNonNumericExposedPorts = true o.BaseName = baseName o.CommandPath = c.CommandPath() o.CommandName = commandName cmdutil.WarnAboutCommaSeparation(o.ErrOut, o.Config.Environment, "--env") mapper, _ := f.Object(false) o.PrintObject = cmdutil.VersionedPrintObject(f.PrintObject, c, mapper, out) o.LogsForObject = f.LogsForObject if err := CompleteAppConfig(o.Config, f, c, args); err != nil { return err } if o.Config.Dockerfile == "-" { data, err := ioutil.ReadAll(in) if err != nil { return err } o.Config.Dockerfile = string(data) } if err := setAppConfigLabels(c, o.Config); err != nil { return err } return nil }
func RenderFiles(cmdRaw *cobra.Command, tmpl *template.Template) error { this_entry := &docs.Entry{ Title: cmdRaw.CommandPath(), Specifications: Specs, Examples: Examples, BaseURL: strings.Replace(RenderDir, ".", "", 1), Template: tmpl, FileName: docs.GenerateFileName(RenderDir, cmdRaw.CommandPath()), } cmd := &Cmd{ Command: cmdRaw, Entry: this_entry, Description: Description, } for _, command := range cmd.Command.Commands() { RenderFiles(command, tmpl) } if !cmd.Command.HasParent() { entries := append(cmd.Entry.Specifications, cmd.Entry.Examples...) for _, entry := range entries { entry.Specifications = cmd.Entry.Specifications entry.Examples = cmd.Entry.Examples entry.CmdEntryPoint = cmd.Entry.Title entry.BaseURL = cmd.Entry.BaseURL if err := docs.RenderEntry(entry); err != nil { return err } } } outFile, err := os.Create(cmd.Entry.FileName) if err != nil { return err } defer outFile.Close() err = cmd.Entry.Template.Execute(outFile, cmd) if err != nil { return err } return nil }
// NoArgs validate args and returns an error if there are any args func NoArgs(cmd *cobra.Command, args []string) error { if len(args) == 0 { return nil } if cmd.HasSubCommands() { return fmt.Errorf("\n" + strings.TrimRight(cmd.UsageString(), "\n")) } return fmt.Errorf( "\"%s\" accepts no argument(s).\nSee '%s --help'.\n\nUsage: %s\n\n%s", cmd.CommandPath(), cmd.CommandPath(), cmd.UseLine(), cmd.Short, ) }
func CheckExamples(cmd *cobra.Command) []error { cmdPath := cmd.CommandPath() examples := cmd.Example errors := []error{} if len(examples) > 0 { for _, line := range strings.Split(examples, "\n") { if !strings.HasPrefix(line, templates.Indentation) { errors = append(errors, fmt.Errorf(`command %q: examples are not normalized ↳ make sure you are calling templates.Examples (from pkg/cmd/templates) before assigning cmd.Example`, cmdPath)) } if trimmed := strings.TrimSpace(line); strings.HasPrefix(trimmed, "//") { errors = append(errors, fmt.Errorf(`command %q: we use # to start comments in examples instead of //`, cmdPath)) } } } return errors }
func scaleArgs(cmd *cobra.Command, args []string) error { if err := cli.RequiresMinArgs(1)(cmd, args); err != nil { return err } for _, arg := range args { if parts := strings.SplitN(arg, "=", 2); len(parts) != 2 { return fmt.Errorf( "Invalid scale specifier '%s'.\nSee '%s --help'.\n\nUsage: %s\n\n%s", arg, cmd.CommandPath(), cmd.UseLine(), cmd.Short, ) } } return nil }
func GenerateTree(cmd *cobra.Command, dir string, specs []string, front_matter, base_url string) { filePrepender := func(s string) string { s = strings.Replace(s, dir, "", 1) s = strings.Replace(s, ".md", "", -1) s = strings.Replace(s, "_", " ", -1) pre := strings.Replace(front_matter, "{{}}", s, -1) return pre } linkHandler := func(s string) string { s = strings.Replace(s, ".md", "/", -1) link := base_url + s return link } for _, c := range cmd.Commands() { GenerateTree(c, dir, specs, front_matter, base_url) } out := new(bytes.Buffer) GenerateSingle(cmd, out, linkHandler, specs, dir) filename := cmd.CommandPath() filename = dir + strings.Replace(filename, " ", "_", -1) + ".md" outFile, err := os.Create(filename) if err != nil { fmt.Println(err) os.Exit(1) } defer outFile.Close() _, err = outFile.WriteString(filePrepender(filename)) if err != nil { fmt.Println(err) os.Exit(1) } _, err = outFile.Write(out.Bytes()) if err != nil { fmt.Println(err) os.Exit(1) } }
func extractExamples(cmd *cobra.Command) Examples { objs := Examples{} for _, c := range cmd.Commands() { if len(c.Deprecated) > 0 { continue } objs = append(objs, extractExamples(c)...) } if cmd.HasExample() { o := &runtime.Unstructured{ Object: make(map[string]interface{}), } o.Object["name"] = cmd.Name() o.Object["fullName"] = cmd.CommandPath() o.Object["description"] = cmd.Short o.Object["examples"] = cmd.Example objs = append(objs, o) } sort.Sort(objs) return objs }
func transformBuildError(err error, c *cobra.Command, fullName string, groups errorGroups) { switch t := err.(type) { case newapp.ErrNoMatch: groups.Add( "no-matches", Df(` The '%[1]s' command will match arguments to the following types: 1. Images tagged into image streams in the current project or the 'openshift' project - if you don't specify a tag, we'll add ':latest' 2. Images in the Docker Hub, on remote registries, or on the local Docker engine 3. Git repository URLs or local paths that point to Git repositories --allow-missing-images can be used to force the use of an image that was not matched See '%[1]s -h' for examples.`, c.CommandPath(), ), t, t.Errs..., ) return } transformError(err, c, fullName, groups) }
// Generate prints API docs for a command func Generate(cmd *cobra.Command) string { buf := new(bytes.Buffer) cmds := genCmdList(cmd) sort.Sort(byName(cmds)) for _, cmd := range cmds { if len(strings.Split(cmd.CommandPath(), " ")) == 1 { fmt.Fprint(buf, "**Options**\n\n") printOptions(buf, cmd) fmt.Fprintln(buf) continue } depth := len(strings.Split(cmd.CommandPath(), " ")) fmt.Fprint(buf, header(depth, cmd.CommandPath())) fmt.Fprint(buf, cmd.Long, "\n\n") if cmd.Runnable() { fmt.Fprint(buf, "**Usage:** ", "`", cmd.UseLine(), "`", "\n\n") } if cmd.HasLocalFlags() || cmd.HasPersistentFlags() { fmt.Fprint(buf, "**Options**\n\n") printOptions(buf, cmd) } if cmd.Example != "" { fmt.Fprint(buf, "**Example**\n\n") fmt.Fprint(buf, "```", "\n", cmd.Example, "```", "\n\n") } } return buf.String() }
func UsageError(cmd *cobra.Command, format string, args ...interface{}) error { msg := fmt.Sprintf(format, args...) return fmt.Errorf("%s\nSee '%s -h' for help and examples.", msg, cmd.CommandPath()) }
func usageError(cmd *cobra.Command, format string, args ...interface{}) { glog.Errorf(format, args...) glog.Errorf("See '%s -h' for help.", cmd.CommandPath()) os.Exit(1) }
func transformError(err error, c *cobra.Command, fullName string, groups errorGroups) { switch t := err.(type) { case newcmd.ErrRequiresExplicitAccess: if t.Input.Token != nil && t.Input.Token.ServiceAccount { groups.Add( "explicit-access-installer", D(` WARNING: This will allow the pod to create and manage resources within your namespace - ensure you trust the image with those permissions before you continue. You can see more information about the image by adding the --dry-run flag. If you trust the provided image, include the flag --grant-install-rights.`, ), fmt.Errorf("installing %q requires an 'installer' service account with project editor access", t.Match.Value), ) } else { groups.Add( "explicit-access-you", D(` WARNING: This will allow the pod to act as you across the entire cluster - ensure you trust the image with those permissions before you continue. You can see more information about the image by adding the --dry-run flag. If you trust the provided image, include the flag --grant-install-rights.`, ), fmt.Errorf("installing %q requires that you grant the image access to run with your credentials", t.Match.Value), ) } return case newapp.ErrNoMatch: groups.Add( "no-matches", Df(` The '%[1]s' command will match arguments to the following types: 1. Images tagged into image streams in the current project or the 'openshift' project - if you don't specify a tag, we'll add ':latest' 2. Images in the Docker Hub, on remote registries, or on the local Docker engine 3. Templates in the current project or the 'openshift' project 4. Git repository URLs or local paths that point to Git repositories --allow-missing-images can be used to point to an image that does not exist yet. See '%[1]s -h' for examples.`, c.CommandPath(), ), t, t.Errs..., ) return case newapp.ErrMultipleMatches: buf := &bytes.Buffer{} for _, match := range t.Matches { fmt.Fprintf(buf, "* %s\n", match.Description) fmt.Fprintf(buf, " Use %[1]s to specify this image or template\n\n", match.Argument) } groups.Add( "multiple-matches", Df(` The argument %[1]q could apply to the following Docker images or OpenShift image streams: %[2]s`, t.Value, buf.String(), ), t, t.Errs..., ) return case newapp.ErrPartialMatch: buf := &bytes.Buffer{} fmt.Fprintf(buf, "* %s\n", t.Match.Description) fmt.Fprintf(buf, " Use %[1]s to specify this image or template\n\n", t.Match.Argument) groups.Add( "partial-match", Df(` The argument %[1]q only partially matched the following Docker image or OpenShift image stream: %[2]s`, t.Value, buf.String(), ), t, t.Errs..., ) return case newapp.ErrNoTagsFound: buf := &bytes.Buffer{} fmt.Fprintf(buf, " Use --allow-missing-imagestream-tags to use this image stream\n\n") groups.Add( "no-tags", Df(` The image stream %[1]q exists, but it has no tags. %[2]s`, t.Match.Name, buf.String(), ), t, t.Errs..., ) return } switch err { case errNoTokenAvailable: // TODO: improve by allowing token generation groups.Add("", "", fmt.Errorf("to install components you must be logged in with an OAuth token (instead of only a certificate)")) case newcmd.ErrNoInputs: // TODO: suggest things to the user groups.Add("", "", kcmdutil.UsageError(c, newAppNoInput, fullName)) default: groups.Add("", "", err) } }