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. flag.Parse()
  15. args := flag.Args()
  16. if len(args) < 1 {
  17. PrintUsage(os.Stderr, RootCommand)
  18. return
  19. }
  20. cmdName := args[0] // for error messages
  21. if args[0] == "help" {
  22. Help(os.Stdout, args[1:])
  23. return
  24. }
  25. BigCmdLoop:
  26. for bigCmd := RootCommand; ; {
  27. for _, cmd := range bigCmd.Commands {
  28. if cmd.Name() != args[0] {
  29. continue
  30. }
  31. if len(cmd.Commands) > 0 {
  32. // test sub commands
  33. bigCmd = cmd
  34. args = args[1:]
  35. if len(args) == 0 {
  36. PrintUsage(os.Stderr, bigCmd)
  37. SetExitStatus(2)
  38. Exit()
  39. }
  40. if args[0] == "help" {
  41. // Accept 'go mod help' and 'go mod help foo' for 'go help mod' and 'go help mod foo'.
  42. Help(os.Stdout, append(strings.Split(cmdName, " "), args[1:]...))
  43. return
  44. }
  45. cmdName += " " + args[0]
  46. continue BigCmdLoop
  47. }
  48. if !cmd.Runnable() {
  49. continue
  50. }
  51. cmd.Flag.Usage = func() { cmd.Usage() }
  52. if cmd.CustomFlags {
  53. args = args[1:]
  54. } else {
  55. cmd.Flag.Parse(args[1:])
  56. args = cmd.Flag.Args()
  57. }
  58. buildCommandText(cmd)
  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. // Sort sorts the commands
  73. func Sort() {
  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. }