// ShortHelp returns a formatted CLI helptext string, generated for the given command func ShortHelp(rootName string, root *cmds.Command, path []string, out io.Writer) error { cmd, err := root.Get(path) if err != nil { return err } // default cmd to root if there is no path if path == nil && cmd == nil { cmd = root } pathStr := rootName if len(path) > 0 { pathStr += " " + strings.Join(path, " ") } fields := helpFields{ Indent: indentStr, Path: pathStr, ArgUsage: usageText(cmd), Tagline: cmd.Helptext.Tagline, Synopsis: cmd.Helptext.Synopsis, Description: cmd.Helptext.ShortDescription, Usage: cmd.Helptext.Usage, MoreHelp: (cmd != root), } // trim the extra newlines (see TrimNewlines doc) fields.TrimNewlines() // indent all fields that have been set fields.IndentAll() return shortHelpTemplate.Execute(out, fields) }
// LongHelp returns a formatted CLI helptext string, generated for the given command func LongHelp(rootName string, root *cmds.Command, path []string, out io.Writer) error { cmd, err := root.Get(path) if err != nil { return err } pathStr := rootName if len(path) > 0 { pathStr += " " + strings.Join(path, " ") } fields := helpFields{ Indent: indentStr, Path: pathStr, ArgUsage: usageText(cmd), Tagline: cmd.Helptext.Tagline, Arguments: cmd.Helptext.Arguments, Options: cmd.Helptext.Options, Synopsis: cmd.Helptext.Synopsis, Subcommands: cmd.Helptext.Subcommands, Description: cmd.Helptext.ShortDescription, Usage: cmd.Helptext.Usage, MoreHelp: (cmd != root), } if len(cmd.Helptext.LongDescription) > 0 { fields.Description = cmd.Helptext.LongDescription } // autogen fields that are empty if len(fields.Arguments) == 0 { fields.Arguments = strings.Join(argumentText(cmd), "\n") } if len(fields.Options) == 0 { fields.Options = strings.Join(optionText(cmd), "\n") } if len(fields.Subcommands) == 0 { fields.Subcommands = strings.Join(subcommandText(cmd, rootName, path), "\n") } // trim the extra newlines (see TrimNewlines doc) fields.TrimNewlines() // indent all fields that have been set fields.IndentAll() return longHelpTemplate.Execute(out, fields) }
// Parse parses the data in a http.Request and returns a command Request object func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) { if !strings.HasPrefix(r.URL.Path, ApiPath) { return nil, errors.New("Unexpected path prefix") } path := strings.Split(strings.TrimPrefix(r.URL.Path, ApiPath+"/"), "/") stringArgs := make([]string, 0) cmd, err := root.Get(path[:len(path)-1]) if err != nil { // 404 if there is no command at that path return nil, ErrNotFound } else if sub := cmd.Subcommand(path[len(path)-1]); sub == nil { if len(path) <= 1 { return nil, ErrNotFound } // if the last string in the path isn't a subcommand, use it as an argument // e.g. /objects/Qabc12345 (we are passing "Qabc12345" to the "objects" command) stringArgs = append(stringArgs, path[len(path)-1]) path = path[:len(path)-1] } else { cmd = sub } opts, stringArgs2 := parseOptions(r) stringArgs = append(stringArgs, stringArgs2...) // count required argument definitions numRequired := 0 for _, argDef := range cmd.Arguments { if argDef.Required { numRequired++ } } // count the number of provided argument values valCount := len(stringArgs) args := make([]string, valCount) valIndex := 0 requiredFile := "" for _, argDef := range cmd.Arguments { // skip optional argument definitions if there aren't sufficient remaining values if valCount-valIndex <= numRequired && !argDef.Required { continue } else if argDef.Required { numRequired-- } if argDef.Type == cmds.ArgString { if argDef.Variadic { for _, s := range stringArgs { args[valIndex] = s valIndex++ } valCount -= len(stringArgs) } else if len(stringArgs) > 0 { args[valIndex] = stringArgs[0] stringArgs = stringArgs[1:] valIndex++ } else { break } } else if argDef.Type == cmds.ArgFile && argDef.Required && len(requiredFile) == 0 { requiredFile = argDef.Name } } optDefs, err := root.GetOptions(path) if err != nil { return nil, err } // create cmds.File from multipart/form-data contents contentType := r.Header.Get(contentTypeHeader) mediatype, _, _ := mime.ParseMediaType(contentType) var f *files.MultipartFile if mediatype == "multipart/form-data" { f = &files.MultipartFile{Mediatype: mediatype} f.Reader, err = r.MultipartReader() if err != nil { return nil, err } } // if there is a required filearg, error if no files were provided if len(requiredFile) > 0 && f == nil { return nil, fmt.Errorf("File argument '%s' is required", requiredFile) } req, err := cmds.NewRequest(path, opts, args, f, cmd, optDefs) if err != nil { return nil, err } err = cmd.CheckArguments(req) if err != nil { return nil, err } return req, nil }