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