1. 程式人生 > >【golang】第三方命令列 cli 的使用

【golang】第三方命令列 cli 的使用

App 結構體定義了命令列的應用結構,如下很龐大的樣子

// App is the main structure of a cli application. It is recommended that
// an app be created with the cli.NewApp() function
type App struct {
       // The name of the program. Defaults to path.Base(os.Args[0])
Name string
// Full name of command for help, defaults to Name
HelpName string
// Description of the program. Usage string // Text to override the USAGE section of help UsageText string // Description of the program argument format. ArgsUsage string // Version of the program Version string // List of commands to execute Commands []Command // List of flags to parse Flags []Flag // Boolean to enable bash completion commands
EnableBashCompletion bool // Boolean to hide built-in help command HideHelp bool // Boolean to hide built-in version flag and the VERSION section of help HideVersion bool // Populate on app startup, only gettable through method Categories() categories CommandCategories // An action to execute when the bash-completion flag is set
BashComplete BashCompleteFunc // An action to execute before any subcommands are run, but after the context is ready // If a non-nil error is returned, no subcommands are run Before BeforeFunc // An action to execute after any subcommands are run, but after the subcommand has finished // It is run even if Action() panics After AfterFunc // The action to execute when no subcommands are specified // Expects a `cli.ActionFunc` but will accept the *deprecated* signature of `func(*cli.Context) {}` // *Note*: support for the deprecated `Action` signature will be removed in a future version Action interface{} // Execute this function if the proper command cannot be found CommandNotFound CommandNotFoundFunc // Execute this function if an usage error occurs OnUsageError OnUsageErrorFunc // Compilation date Compiled time.Time // List of all authors who contributed Authors []Author // Copyright of the binary if any Copyright string // Name of Author (Note: Use App.Authors, this is deprecated) Author string // Email of Author (Note: Use App.Authors, this is deprecated) Email string // Writer writer to write output to Writer io.Writer // ErrWriter writes error output ErrWriter io.Writer // Other custom info Metadata map[string]interface{} didSetup bool }
// Context is a type that is passed through to
// each Handler action in a cli application. Context
// can be used to retrieve context-specific Args and
// parsed command-line options.
type Context struct {
       App           *App
       Command       Command
       flagSet       *flag.FlagSet
       setFlags      map[string]bool
parentContext *Context
}

初始化 APP
// NewApp creates a new cli Application with some reasonable defaults for Name,
// Usage, Version and Action.
func NewApp() *App {
       return &App{
              Name:         filepath.Base(os.Args[0]),
HelpName:     filepath.Base(os.Args[0]),
Usage:        "A new cli application",
UsageText:    "",
Version:      "0.0.0",
BashComplete: DefaultAppComplete,
Action:       helpCommand.Action,
Compiled:     compileTime(),
Writer:       os.Stdout,
}
}

例子主函式
const (usage      = "xxxxxxxxxxxxxx")
func main() {
       app := cli.NewApp()
       app.Name = "name"
app.Usage = usage

       app.Version = "xxxxx"
       app.Flags = []cli.Flag{
              cli.BoolFlag{
                     Name:  "debug",
Usage: "enable debug output for logging",
},
cli.StringFlag{
                     Name:  "log",
Value: "/dev/null",
Usage: "set the log file path where internal debug information is written",
},}
       app.Commands = []cli.Command{  createCommand,
             deleteCommand,}
       app.Before = func(context *cli.Context) error {
              if context.GlobalBool("debug") {
                     logrus.SetLevel(logrus.DebugLevel)
              }
              if path := context.GlobalString("log"); path != "" {
                     f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
                     if err != nil {
                            return err
                     }
                     logrus.SetOutput(f)
              }
              return nil
}
 
       if err := app.Run(os.Args); err != nil {
              fatal(err)
       }
}

例子子命令

     自命令可以使用模版,在 Action 中呼叫實現的函式

var createCommand = cli.Command{
       Name:  "create",
Usage: "create a xxxxx",
ArgsUsage: `xxxxxxx`,
Flags: []cli.Flag{
              cli.StringFlag{
                     Name:  "bundle, b",
Value: "",
Usage: `path to the root of directory, defaults to the current directory`,
},},
Action: func(context *cli.Context) error {
              do-somethingreturn nil
},
}

例子子命令

     自命令可以使用模版,在 Action 中呼叫實現的函式

// loadSpec loads the specification from the provided path.
func loadSpec(cPath string) (spec *specs.Spec, err error) {
       cf, err := os.Open(cPath)
       if err != nil {
              if os.IsNotExist(err) {
                     return nil, fmt.Errorf("JSON specification file %s not found", cPath)
              }
              return nil, err
       }
       defer cf.Close()

       if err = json.NewDecoder(cf).Decode(&spec); err != nil {
              return nil, err
       }
       return spec, validateProcessSpec(spec.Process)
}

具體可以參考 runc 原始碼 main.go 檔案