From 68bb106980bd4a49f4c388add19be1d3d835d548 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Tue, 21 Nov 2017 20:40:24 -0800 Subject: [PATCH] Delete some now unused commands lib code License: MIT Signed-off-by: Jeromy --- commands/cli/cmd_suggestion.go | 89 ----- commands/cli/helptext.go | 449 ---------------------- commands/cli/helptext_test.go | 47 --- commands/cli/parse.go | 526 -------------------------- commands/cli/parse_test.go | 313 --------------- commands/http/client.go | 310 --------------- commands/http/handler.go | 466 ----------------------- commands/http/handler_test.go | 348 ----------------- commands/http/multifilereader.go | 126 ------ commands/http/multifilereader_test.go | 114 ------ commands/http/parse.go | 160 -------- 11 files changed, 2948 deletions(-) delete mode 100644 commands/cli/cmd_suggestion.go delete mode 100644 commands/cli/helptext.go delete mode 100644 commands/cli/helptext_test.go delete mode 100644 commands/cli/parse.go delete mode 100644 commands/cli/parse_test.go delete mode 100644 commands/http/client.go delete mode 100644 commands/http/handler.go delete mode 100644 commands/http/handler_test.go delete mode 100644 commands/http/multifilereader.go delete mode 100644 commands/http/multifilereader_test.go delete mode 100644 commands/http/parse.go diff --git a/commands/cli/cmd_suggestion.go b/commands/cli/cmd_suggestion.go deleted file mode 100644 index e40ad6d84..000000000 --- a/commands/cli/cmd_suggestion.go +++ /dev/null @@ -1,89 +0,0 @@ -package cli - -import ( - "fmt" - "sort" - "strings" - - levenshtein "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/texttheater/golang-levenshtein/levenshtein" - cmds "github.com/ipfs/go-ipfs/commands" -) - -// Make a custom slice that can be sorted by its levenshtein value -type suggestionSlice []*suggestion - -type suggestion struct { - cmd string - levenshtein int -} - -func (s suggestionSlice) Len() int { - return len(s) -} - -func (s suggestionSlice) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s suggestionSlice) Less(i, j int) bool { - return s[i].levenshtein < s[j].levenshtein -} - -func suggestUnknownCmd(args []string, root *cmds.Command) []string { - if root == nil { - return nil - } - - arg := args[0] - var suggestions []string - sortableSuggestions := make(suggestionSlice, 0) - var sFinal []string - const MIN_LEVENSHTEIN = 3 - - var options = levenshtein.Options{ - InsCost: 1, - DelCost: 3, - SubCost: 2, - Matches: func(sourceCharacter rune, targetCharacter rune) bool { - return sourceCharacter == targetCharacter - }, - } - - // Start with a simple strings.Contains check - for name := range root.Subcommands { - if strings.Contains(arg, name) { - suggestions = append(suggestions, name) - } - } - - // If the string compare returns a match, return - if len(suggestions) > 0 { - return suggestions - } - - for name := range root.Subcommands { - lev := levenshtein.DistanceForStrings([]rune(arg), []rune(name), options) - if lev <= MIN_LEVENSHTEIN { - sortableSuggestions = append(sortableSuggestions, &suggestion{name, lev}) - } - } - sort.Sort(sortableSuggestions) - - for _, j := range sortableSuggestions { - sFinal = append(sFinal, j.cmd) - } - return sFinal -} - -func printSuggestions(inputs []string, root *cmds.Command) (err error) { - - suggestions := suggestUnknownCmd(inputs, root) - if len(suggestions) > 1 { - err = fmt.Errorf("Unknown Command \"%s\"\n\nDid you mean any of these?\n\n\t%s", inputs[0], strings.Join(suggestions, "\n\t")) - } else if len(suggestions) > 0 { - err = fmt.Errorf("Unknown Command \"%s\"\n\nDid you mean this?\n\n\t%s", inputs[0], suggestions[0]) - } else { - err = fmt.Errorf("Unknown Command %q", inputs[0]) - } - return -} diff --git a/commands/cli/helptext.go b/commands/cli/helptext.go deleted file mode 100644 index 844084176..000000000 --- a/commands/cli/helptext.go +++ /dev/null @@ -1,449 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "sort" - "strings" - "text/template" - - cmds "github.com/ipfs/go-ipfs/commands" - cmdkit "gx/ipfs/QmUyfy4QSr3NXym4etEiRyxBLqqAeKHJuRdi8AACxg63fZ/go-ipfs-cmdkit" -) - -const ( - requiredArg = "<%v>" - optionalArg = "[<%v>]" - variadicArg = "%v..." - shortFlag = "-%v" - longFlag = "--%v" - - indentStr = " " -) - -type helpFields struct { - Indent string - Usage string - Path string - ArgUsage string - Tagline string - Arguments string - Options string - Synopsis string - Subcommands string - Description string - MoreHelp bool -} - -// TrimNewlines removes extra newlines from fields. This makes aligning -// commands easier. Below, the leading + tralining newlines are removed: -// Synopsis: ` -// ipfs config - Get value of -// ipfs config - Set value of to -// ipfs config --show - Show config file -// ipfs config --edit - Edit config file in $EDITOR -// ` -func (f *helpFields) TrimNewlines() { - f.Path = strings.Trim(f.Path, "\n") - f.ArgUsage = strings.Trim(f.ArgUsage, "\n") - f.Tagline = strings.Trim(f.Tagline, "\n") - f.Arguments = strings.Trim(f.Arguments, "\n") - f.Options = strings.Trim(f.Options, "\n") - f.Synopsis = strings.Trim(f.Synopsis, "\n") - f.Subcommands = strings.Trim(f.Subcommands, "\n") - f.Description = strings.Trim(f.Description, "\n") -} - -// Indent adds whitespace the lines of fields. -func (f *helpFields) IndentAll() { - indent := func(s string) string { - if s == "" { - return s - } - return indentString(s, indentStr) - } - - f.Arguments = indent(f.Arguments) - f.Options = indent(f.Options) - f.Synopsis = indent(f.Synopsis) - f.Subcommands = indent(f.Subcommands) - f.Description = indent(f.Description) -} - -const usageFormat = "{{if .Usage}}{{.Usage}}{{else}}{{.Path}}{{if .ArgUsage}} {{.ArgUsage}}{{end}} - {{.Tagline}}{{end}}" - -const longHelpFormat = `USAGE -{{.Indent}}{{template "usage" .}} - -{{if .Synopsis}}SYNOPSIS -{{.Synopsis}} - -{{end}}{{if .Arguments}}ARGUMENTS - -{{.Arguments}} - -{{end}}{{if .Options}}OPTIONS - -{{.Options}} - -{{end}}{{if .Description}}DESCRIPTION - -{{.Description}} - -{{end}}{{if .Subcommands}}SUBCOMMANDS -{{.Subcommands}} - -{{.Indent}}Use '{{.Path}} --help' for more information about each command. -{{end}} -` -const shortHelpFormat = `USAGE -{{.Indent}}{{template "usage" .}} -{{if .Synopsis}} -{{.Synopsis}} -{{end}}{{if .Description}} -{{.Description}} -{{end}}{{if .Subcommands}} -SUBCOMMANDS -{{.Subcommands}} -{{end}}{{if .MoreHelp}} -Use '{{.Path}} --help' for more information about this command. -{{end}} -` - -var usageTemplate *template.Template -var longHelpTemplate *template.Template -var shortHelpTemplate *template.Template - -func init() { - usageTemplate = template.Must(template.New("usage").Parse(usageFormat)) - longHelpTemplate = template.Must(usageTemplate.New("longHelp").Parse(longHelpFormat)) - shortHelpTemplate = template.Must(usageTemplate.New("shortHelp").Parse(shortHelpFormat)) -} - -// LongHelp writes a formatted CLI helptext string to a Writer 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") - } - if len(fields.Synopsis) == 0 { - fields.Synopsis = generateSynopsis(cmd, pathStr) - } - - // trim the extra newlines (see TrimNewlines doc) - fields.TrimNewlines() - - // indent all fields that have been set - fields.IndentAll() - - return longHelpTemplate.Execute(out, fields) -} - -// ShortHelp writes a formatted CLI helptext string to a Writer 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, - Subcommands: cmd.Helptext.Subcommands, - Usage: cmd.Helptext.Usage, - MoreHelp: (cmd != root), - } - - // autogen fields that are empty - if len(fields.Subcommands) == 0 { - fields.Subcommands = strings.Join(subcommandText(cmd, rootName, path), "\n") - } - if len(fields.Synopsis) == 0 { - fields.Synopsis = generateSynopsis(cmd, pathStr) - } - - // trim the extra newlines (see TrimNewlines doc) - fields.TrimNewlines() - - // indent all fields that have been set - fields.IndentAll() - - return shortHelpTemplate.Execute(out, fields) -} - -func generateSynopsis(cmd *cmds.Command, path string) string { - res := path - for _, opt := range cmd.Options { - valopt, ok := cmd.Helptext.SynopsisOptionsValues[opt.Names()[0]] - if !ok { - valopt = opt.Names()[0] - } - sopt := "" - for i, n := range opt.Names() { - pre := "-" - if len(n) > 1 { - pre = "--" - } - if opt.Type() == cmdkit.Bool && opt.Default() == true { - pre = "--" - sopt = fmt.Sprintf("%s%s=false", pre, n) - break - } else { - if i == 0 { - if opt.Type() == cmdkit.Bool { - sopt = fmt.Sprintf("%s%s", pre, n) - } else { - sopt = fmt.Sprintf("%s%s=<%s>", pre, n, valopt) - } - } else { - sopt = fmt.Sprintf("%s | %s%s", sopt, pre, n) - } - } - } - res = fmt.Sprintf("%s [%s]", res, sopt) - } - if len(cmd.Arguments) > 0 { - res = fmt.Sprintf("%s [--]", res) - } - for _, arg := range cmd.Arguments { - sarg := fmt.Sprintf("<%s>", arg.Name) - if arg.Variadic { - sarg = sarg + "..." - } - - if !arg.Required { - sarg = fmt.Sprintf("[%s]", sarg) - } - res = fmt.Sprintf("%s %s", res, sarg) - } - return strings.Trim(res, " ") -} - -func argumentText(cmd *cmds.Command) []string { - lines := make([]string, len(cmd.Arguments)) - - for i, arg := range cmd.Arguments { - lines[i] = argUsageText(arg) - } - lines = align(lines) - for i, arg := range cmd.Arguments { - lines[i] += " - " + arg.Description - } - - return lines -} - -func optionFlag(flag string) string { - if len(flag) == 1 { - return fmt.Sprintf(shortFlag, flag) - } - - return fmt.Sprintf(longFlag, flag) -} - -func optionText(cmd ...*cmds.Command) []string { - // get a slice of the options we want to list out - options := make([]cmdkit.Option, 0) - for _, c := range cmd { - options = append(options, c.Options...) - } - - // add option names to output (with each name aligned) - lines := make([]string, 0) - j := 0 - for { - done := true - i := 0 - for _, opt := range options { - if len(lines) < i+1 { - lines = append(lines, "") - } - - names := sortByLength(opt.Names()) - if len(names) >= j+1 { - lines[i] += optionFlag(names[j]) - } - if len(names) > j+1 { - lines[i] += ", " - done = false - } - - i++ - } - - if done { - break - } - - lines = align(lines) - j++ - } - lines = align(lines) - - // add option types to output - for i, opt := range options { - lines[i] += " " + fmt.Sprintf("%v", opt.Type()) - } - lines = align(lines) - - // add option descriptions to output - for i, opt := range options { - lines[i] += " - " + opt.Description() - } - - return lines -} - -func subcommandText(cmd *cmds.Command, rootName string, path []string) []string { - prefix := fmt.Sprintf("%v %v", rootName, strings.Join(path, " ")) - if len(path) > 0 { - prefix += " " - } - - // Sorting fixes changing order bug #2981. - sortedNames := make([]string, 0) - for name := range cmd.Subcommands { - sortedNames = append(sortedNames, name) - } - sort.Strings(sortedNames) - - subcmds := make([]*cmds.Command, len(cmd.Subcommands)) - lines := make([]string, len(cmd.Subcommands)) - - for i, name := range sortedNames { - sub := cmd.Subcommands[name] - usage := usageText(sub) - if len(usage) > 0 { - usage = " " + usage - } - lines[i] = prefix + name + usage - subcmds[i] = sub - } - - lines = align(lines) - for i, sub := range subcmds { - lines[i] += " - " + sub.Helptext.Tagline - } - - return lines -} - -func usageText(cmd *cmds.Command) string { - s := "" - for i, arg := range cmd.Arguments { - if i != 0 { - s += " " - } - s += argUsageText(arg) - } - - return s -} - -func argUsageText(arg cmdkit.Argument) string { - s := arg.Name - - if arg.Required { - s = fmt.Sprintf(requiredArg, s) - } else { - s = fmt.Sprintf(optionalArg, s) - } - - if arg.Variadic { - s = fmt.Sprintf(variadicArg, s) - } - - return s -} - -func align(lines []string) []string { - longest := 0 - for _, line := range lines { - length := len(line) - if length > longest { - longest = length - } - } - - for i, line := range lines { - length := len(line) - if length > 0 { - lines[i] += strings.Repeat(" ", longest-length) - } - } - - return lines -} - -func indentString(line string, prefix string) string { - return prefix + strings.Replace(line, "\n", "\n"+prefix, -1) -} - -type lengthSlice []string - -func (ls lengthSlice) Len() int { - return len(ls) -} -func (ls lengthSlice) Swap(a, b int) { - ls[a], ls[b] = ls[b], ls[a] -} -func (ls lengthSlice) Less(a, b int) bool { - return len(ls[a]) < len(ls[b]) -} - -func sortByLength(slice []string) []string { - output := make(lengthSlice, len(slice)) - for i, val := range slice { - output[i] = val - } - sort.Sort(output) - return []string(output) -} diff --git a/commands/cli/helptext_test.go b/commands/cli/helptext_test.go deleted file mode 100644 index e4b143871..000000000 --- a/commands/cli/helptext_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package cli - -import ( - "strings" - "testing" - - cmds "github.com/ipfs/go-ipfs/commands" - - "gx/ipfs/QmUyfy4QSr3NXym4etEiRyxBLqqAeKHJuRdi8AACxg63fZ/go-ipfs-cmdkit" -) - -func TestSynopsisGenerator(t *testing.T) { - command := &cmds.Command{ - Arguments: []cmdkit.Argument{ - cmdkit.StringArg("required", true, false, ""), - cmdkit.StringArg("variadic", false, true, ""), - }, - Options: []cmdkit.Option{ - cmdkit.StringOption("opt", "o", "Option"), - }, - Helptext: cmdkit.HelpText{ - SynopsisOptionsValues: map[string]string{ - "opt": "OPTION", - }, - }, - } - syn := generateSynopsis(command, "cmd") - t.Logf("Synopsis is: %s", syn) - if !strings.HasPrefix(syn, "cmd ") { - t.Fatal("Synopsis should start with command name") - } - if !strings.Contains(syn, "[--opt=