execute.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. buildCommandsText(RootCommand)
  15. flag.Parse()
  16. args := flag.Args()
  17. if len(args) < 1 {
  18. PrintUsage(os.Stderr, RootCommand)
  19. return
  20. }
  21. cmdName := args[0] // for error messages
  22. if args[0] == "help" {
  23. Help(os.Stdout, args[1:])
  24. return
  25. }
  26. BigCmdLoop:
  27. for bigCmd := RootCommand; ; {
  28. for _, cmd := range bigCmd.Commands {
  29. if cmd.Name() != args[0] {
  30. continue
  31. }
  32. if len(cmd.Commands) > 0 {
  33. // test sub commands
  34. bigCmd = cmd
  35. args = args[1:]
  36. if len(args) == 0 {
  37. PrintUsage(os.Stderr, bigCmd)
  38. SetExitStatus(2)
  39. Exit()
  40. }
  41. if args[0] == "help" {
  42. // Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
  43. Help(os.Stdout, append(strings.Split(cmdName, " "), args[1:]...))
  44. return
  45. }
  46. cmdName += " " + args[0]
  47. continue BigCmdLoop
  48. }
  49. if !cmd.Runnable() {
  50. continue
  51. }
  52. cmd.Flag.Usage = func() { cmd.Usage() }
  53. if cmd.CustomFlags {
  54. args = args[1:]
  55. } else {
  56. cmd.Flag.Parse(args[1:])
  57. args = cmd.Flag.Args()
  58. }
  59. cmd.Run(cmd, args)
  60. Exit()
  61. return
  62. }
  63. helpArg := ""
  64. if i := strings.LastIndex(cmdName, " "); i >= 0 {
  65. helpArg = " " + cmdName[:i]
  66. }
  67. fmt.Fprintf(os.Stderr, "%s %s: unknown command\nRun '%s help%s' for usage.\n", CommandEnv.Exec, cmdName, CommandEnv.Exec, helpArg)
  68. SetExitStatus(2)
  69. Exit()
  70. }
  71. }
  72. // SortCommands sorts the first level sub commands
  73. func SortCommands() {
  74. sort.Slice(RootCommand.Commands, func(i, j int) bool {
  75. return SortLessFunc(RootCommand.Commands[i], RootCommand.Commands[j])
  76. })
  77. }
  78. // SortLessFunc used for sort commands list, can be override from outside
  79. var SortLessFunc = func(i, j *Command) bool {
  80. return i.Name() < j.Name()
  81. }