zoukankan      html  css  js  c++  java
  • golang 几个好用的cli package

    cli 开发在golang 的软件开发中占用很大,同时开源的比较好用的cli也很多,以下是整理的几个cli

    github.com/spf13/cobra

    这个比较有名了, 好多框架都使用了这个
    以下是一个简单的使用

    • 代码
    package main
    import (
     "github.com/spf13/cobra"
    )
    func main() {
     cmd := newCommand()
     cmd.AddCommand(newNestedCommand())
     rootCmd := &cobra.Command{}
     rootCmd.AddCommand(cmd)
     if err := rootCmd.Execute(); err != nil {
      println(err.Error())
     }
    }
    func newCommand() *cobra.Command {
     cmd := &cobra.Command{
      Run: func(cmd *cobra.Command, args []string) {
       println(`Foo`)
      },
      Use: `foo`,
      Short: "Command foo",
      Long: "This is a command",
     }
     return cmd
    }
    func newNestedCommand() *cobra.Command {
     cmd := &cobra.Command{
      Run: func(cmd *cobra.Command, args []string) {
       println(`Bar`)
      },
      Use: `bar`,
      Short: "Command bar",
      Long: "This is a nested command",
     }
     return cmd
    }
     
     
    • 效果
    go run main.go
    Usage:
       [command]
    Available Commands:
      foo Command foo
      help Help about any command
    Flags:
      -h, --help help for this command
    Use " [command] --help" for more information about a command.
     

    github.com/urfave/cli

    这个也比较有名,好多框架也使用了这个

    • 代码
    package main
    import (
     "log"
     "os"
     "sort"
     "github.com/urfave/cli"
    )
    func main() {
     app := cli.NewApp()
     app.Flags = []cli.Flag{
      cli.StringFlag{
       Name: "lang, l",
       Value: "english",
       Usage: "Language for the greeting",
      },
      cli.StringFlag{
       Name: "config, c",
       Usage: "Load configuration from `FILE`",
      },
     }
     app.Commands = []cli.Command{
      {
       Name: "complete",
       Aliases: []string{"c"},
       Usage: "complete a task on the list",
       Action: func(c *cli.Context) error {
        log.Print("ddd")
        return nil
       },
      },
      {
       Name: "add",
       Aliases: []string{"a"},
       Usage: "add a task to the list",
       Action: func(c *cli.Context) error {
        return nil
       },
      },
     }
     sort.Sort(cli.FlagsByName(app.Flags))
     sort.Sort(cli.CommandsByName(app.Commands))
     err := app.Run(os.Args)
     if err != nil {
      log.Fatal(err)
     }
    }
    • 运行效果
    go run cmd/cli/main.go 
    NAME:
       main - A new cli application
    USAGE:
       main [global options] command [command options] [arguments...]
    VERSION:
       0.0.0
    COMMANDS:
       add, a add a task to the list
       complete, c complete a task on the list
       help, h Shows a list of commands or help for one command
    GLOBAL OPTIONS:
       --config FILE, -c FILE Load configuration from FILE
       --lang value, -l value Language for the greeting (default: "english")
       --help, -h show help
       --version, -v print the version 

    github.com/google/subcommands

    • 代码
    package main
    import (
       "context"
       "flag"
       "fmt"
       "os"
       "strings"
       "github.com/google/subcommands"
    )
    type printCmd struct {
       capitalize bool
    }
    func (*printCmd) Name() string { return "print" }
    func (*printCmd) Synopsis() string { return "Print args to stdout." }
    func (*printCmd) Usage() string {
       return `print [-capitalize] <some text>:
       Print args to stdout.
      `
    }
    func (p *printCmd) SetFlags(f *flag.FlagSet) {
       f.BoolVar(&p.capitalize, "capitalize", false, "capitalize output")
    }
    func (p *printCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
       for _, arg := range f.Args() {
          if p.capitalize {
             arg = strings.ToUpper(arg)
          }
          fmt.Printf("%s ", arg)
       }
       fmt.Println()
       return subcommands.ExitSuccess
    }
    func main() {
       subcommands.Register(subcommands.HelpCommand(), "")
       subcommands.Register(subcommands.FlagsCommand(), "")
       subcommands.Register(subcommands.CommandsCommand(), "")
       subcommands.Register(&printCmd{}, "")
       flag.Parse()
       ctx := context.Background()
       os.Exit(int(subcommands.Execute(ctx)))
    }
     
     
    • 效果
    go run cmd/subcommands/main.go       
    Usage: main <flags> <subcommand> <subcommand args>
    Subcommands:
            commands list all command names
            flags describe all known top-level flags
            help describe subcommands and their syntax
            print Print args to stdout.
    Use "main flags" for a list of top-level flags
    exit status 2

    github.com/mitchellh/cli

    这个是hashicorp 好多产品使用的一个cli

    • 代码
    package main
    import (
       "fmt"
       "log"
       "os"
       "github.com/mitchellh/cli"
    )
    func fooCommandFactory() (cli.Command, error) {
       return new(FooCommand), nil
    }
    func barCommandFactory() (cli.Command, error) {
       return new(BarCommand), nil
    }
    // FooCommand fooCommand
    type FooCommand struct{}
    // Help should return long-form help text that includes the command-line
    // usage, a brief few sentences explaining the function of the command,
    // and the complete list of flags the command accepts.
    func (f *FooCommand) Help() string {
       return "help foo"
    }
    // Run should run the actual command with the given CLI instance and
    // command-line arguments. It should return the exit status when it is
    // finished.
    //
    // There are a handful of special exit codes this can return documented
    // above that change behavior.
    func (f *FooCommand) Run(args []string) int {
       fmt.Println("Foo Command is running")
       return 1
    }
    // Synopsis should return a one-line, short synopsis of the command.
    // This should be less than 50 characters ideally.
    func (f *FooCommand) Synopsis() string {
       return "foo command Synopsis"
    }
    // BarCommand barCommand
    type BarCommand struct{}
    // Help should return long-form help text that includes the command-line
    // usage, a brief few sentences explaining the function of the command,
    // and the complete list of flags the command accepts.
    func (b *BarCommand) Help() string {
       return "help bar"
    }
    // Run should run the actual command with the given CLI instance and
    // command-line arguments. It should return the exit status when it is
    // finished.
    //
    // There are a handful of special exit codes this can return documented
    // above that change behavior.
    func (b *BarCommand) Run(args []string) int {
       fmt.Println("bar Command is running")
       return 1
    }
    // Synopsis should return a one-line, short synopsis of the command.
    // This should be less than 50 characters ideally.
    func (b *BarCommand) Synopsis() string {
       return "bar command Synopsis"
    }
    func main() {
       c := cli.NewCLI("app", "1.0.0")
       c.Args = os.Args[1:]
       c.Commands = map[string]cli.CommandFactory{
          "foo": fooCommandFactory,
          "bar": barCommandFactory,
       }
       exitStatus, err := c.Run()
       if err != nil {
          log.Println(err)
       }
       os.Exit(exitStatus)
    } 
    • 运行效果
    go run cmd/hashicorp-cli/main.go       
    Usage: app [--version] [--help] <command> [<args>]
    Available commands are:
        bar bar command Synopsis
        foo foo command Synopsis

    github.com/alecthomas/kingpin

    这个cli pacakge 也是大家用的比较多的一个

    • 代码
    package main
    import (
       "fmt"
       "os"
       "gopkg.in/alecthomas/kingpin.v2"
    )
    func listHosts() []string {
       // Provide a dynamic list of hosts from a hosts file or otherwise
       // for bash completion. In this example we simply return static slice.
       // You could use this functionality to reach into a hosts file to provide
       // completion for a list of known hosts.
       return []string{"sshhost.example", "webhost.example", "ftphost.example"}
    }
    type NetcatCommand struct {
       hostName string
       port int
       format string
    }
    func (n *NetcatCommand) run(c *kingpin.ParseContext) error {
       fmt.Printf("Would have run netcat to hostname %v, port %d, and output format %v
    ", n.hostName, n.port, n.format)
       return nil
    }
    func configureNetcatCommand(app *kingpin.Application) {
       c := &NetcatCommand{}
       nc := app.Command("nc", "Connect to a Host").Action(c.run)
       nc.Flag("nop-flag", "Example of a flag with no options").Bool()
       // You can provide hint options using a function to generate them
       nc.Flag("host", "Provide a hostname to nc").
          Required().
          HintAction(listHosts).
          StringVar(&c.hostName)
       // You can provide hint options statically
       nc.Flag("port", "Provide a port to connect to").
          Required().
          HintOptions("80", "443", "8080").
          IntVar(&c.port)
       // Enum/EnumVar options will be turned into completion options automatically
       nc.Flag("format", "Define the output format").
          Default("raw").
          EnumVar(&c.format, "raw", "json")
       // You can combine HintOptions with HintAction too
       nc.Flag("host-with-multi", "Define a hostname").
          HintAction(listHosts).
          HintOptions("myhost.com").
          String()
       // And combine with themselves
       nc.Flag("host-with-multi-options", "Define a hostname").
          HintOptions("myhost.com").
          HintOptions("myhost2.com").
          String()
       // If you specify HintOptions/HintActions for Enum/EnumVar, the options
       // provided for Enum/EnumVar will be overridden.
       nc.Flag("format-with-override-1", "Define a format").
          HintAction(listHosts).
          Enum("option1", "option2")
       nc.Flag("format-with-override-2", "Define a format").
          HintOptions("myhost.com", "myhost2.com").
          Enum("option1", "option2")
    }
    func addSubCommand(app *kingpin.Application, name string, description string) {
       c := app.Command(name, description).Action(func(c *kingpin.ParseContext) error {
          fmt.Printf("Would have run command %s.
    ", name)
          return nil
       })
       c.Flag("nop-flag", "Example of a flag with no options").Bool()
    }
    func main() {
       app := kingpin.New("completion", "My application with bash completion.")
       app.Flag("flag-1", "").String()
       app.Flag("flag-2", "").HintOptions("opt1", "opt2").String()
       configureNetcatCommand(app)
       // Add some additional top level commands
       addSubCommand(app, "ls", "Additional top level command to show command completion")
       addSubCommand(app, "ping", "Additional top level command to show command completion")
       addSubCommand(app, "nmap", "Additional top level command to show command completion")
       kingpin.MustParse(app.Parse(os.Args[1:]))
    }
    • 运行效果
    go run cmd/kingpin/main.go 
    usage: completion [<flags>] <command> [<args> ...]
    My application with bash completion.
    Flags:
      --help Show context-sensitive help (also try --help-long and --help-man).
      --flag-1=FLAG-1  
      --flag-2=FLAG-2  
    Commands:
      help [<command>...]
        Show help.
      nc --host=HOST --port=PORT [<flags>]
        Connect to a Host
      ls [<flags>]
        Additional top level command to show command completion
      ping [<flags>]
        Additional top level command to show command completion
      nmap [<flags>]
        Additional top level command to show command completion

    说明

    以上是几个整理的cli,后期会继续完善

    参考资料

    https://github.com/google/subcommands
    https://github.com/urfave/cli
    https://github.com/mitchellh/cli
    https://github.com/alecthomas/kingpin
    http://github.com/spf13/cobra
    https://github.com/rongfengliang/cliapp

  • 相关阅读:
    Deadlock Detecting--转
    java.util.concurrent包详细分析--转
    spring源码分析之spring-core总结篇
    Google和Baidu常用的搜索技巧--转
    极速发展的饿了么订单系统架构演进--转
    唯品会订单分库分表的实践总结以及关键步骤--转
    数据扩展性探讨和总结--转
    MAT使用--转
    Java 8 Stream API详解--转
    论海明威的存在主义宗教意识——存在主义虚无主义。注:部分观点个人不赞同
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/11685336.html
Copyright © 2011-2022 走看看