execute.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package base
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. "sort"
  7. "strings"
  8. )
  9. // Copyright 2011 The Go Authors. All rights reserved.
  10. // Use of this source code is governed by a BSD-style
  11. // copied from "github.com/golang/go/main.go"
  12. // Execute excute the commands
  13. func Execute() {
  14. flag.Usage = func() {
  15. PrintUsage(os.Stderr, RootCommand)
  16. }
  17. flag.Parse()
  18. args := flag.Args()
  19. if len(args) < 1 {
  20. PrintUsage(os.Stderr, RootCommand)
  21. return
  22. }
  23. cmdName := args[0] // for error messages
  24. if args[0] == "help" {
  25. Help(os.Stdout, args[1:])
  26. return
  27. }
  28. BigCmdLoop:
  29. for bigCmd := RootCommand; ; {
  30. for _, cmd := range bigCmd.Commands {
  31. if cmd.Name() != args[0] {
  32. continue
  33. }
  34. if len(cmd.Commands) > 0 {
  35. // test sub commands
  36. bigCmd = cmd
  37. args = args[1:]
  38. if len(args) == 0 {
  39. PrintUsage(os.Stderr, bigCmd)
  40. SetExitStatus(2)
  41. Exit()
  42. }
  43. if args[0] == "help" {
  44. // Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
  45. Help(os.Stdout, append(strings.Split(cmdName, " "), args[1:]...))
  46. return
  47. }
  48. cmdName += " " + args[0]
  49. continue BigCmdLoop
  50. }
  51. if !cmd.Runnable() {
  52. continue
  53. }
  54. cmd.Flag.Usage = func() { cmd.Usage() }
  55. if cmd.CustomFlags {
  56. args = args[1:]
  57. } else {
  58. cmd.Flag.Parse(args[1:])
  59. args = cmd.Flag.Args()
  60. }
  61. buildCommandText(cmd)
  62. cmd.Run(cmd, args)
  63. Exit()
  64. return
  65. }
  66. helpArg := ""
  67. if i := strings.LastIndex(cmdName, " "); i >= 0 {
  68. helpArg = " " + cmdName[:i]
  69. }
  70. fmt.Fprintf(os.Stderr, "%s %s: unknown command\nRun '%s help%s' for usage.\n", CommandEnv.Exec, cmdName, CommandEnv.Exec, helpArg)
  71. SetExitStatus(2)
  72. Exit()
  73. }
  74. }
  75. // SortCommands sorts the first level sub commands
  76. func SortCommands() {
  77. sort.Slice(RootCommand.Commands, func(i, j int) bool {
  78. return SortLessFunc(RootCommand.Commands[i], RootCommand.Commands[j])
  79. })
  80. }
  81. // SortLessFunc used for sort commands list, can be override from outside
  82. var SortLessFunc = func(i, j *Command) bool {
  83. return i.Name() < j.Name()
  84. }