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", 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.\n", 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

golang 几个好用的cli package的更多相关文章

  1. npm published cli package's default install missing the `-g` flag

    npm published cli package's default install missing the -g flag https://npm.community/t/npm-publishe ...

  2. golang 删除用go get 安装的package

    下面这两种方法都需要手动删除package的源码目录. 1.手动删除 It's safe to just delete the source directory and compiled packag ...

  3. golang (2) package

    综述 golang package是基本的管理单元,package是golang最基本的分发单位和工程管理中依赖关系的体现. 每个golang源代码文件开头都拥有一个package声明,表示该gola ...

  4. go get golang.org/x 包失败解决方法

    由于墙的原因,国内使用 go get安装golang 官方包可能会失败 解决方法 方法1 [不需要FQ] Win10下相关配置: GOPATH : E:\go 安装记录: E:\>go get ...

  5. golang实现ping命令

    // Copyright 2009 The Go Authors.  All rights reserved.// Use of this source code is governed by a B ...

  6. GoLang获取struct的tag

    GoLang获取struct的tag内容:beego的ORM中也通过tag来定义参数的. 获取tag的内容是利用反射包来实现的.示例代码能清楚的看懂! package main import ( &q ...

  7. Golang操作结构体、Map转化为JSON

    结构体生成Json package main import ( "encoding/json" "fmt" ) type IT struct { Company ...

  8. golang 原子操作函数

    golang中的原子操作在sync/atomic package中. 下文以比较和交换操作函数为例,介绍其使用. CompareAndSwapInt32 比较和交换操作是原子性的. // Compar ...

  9. golang之log rotate

    操作系统: CentOS 6.9_x64 go语言版本: 1.8.3 问题描述 golang的log模块提供的有写日志功能,示例代码如下: /* golang log example E-Mail : ...

随机推荐

  1. sqlserver获得数据库非聚集索引的代码

    创建Index DECLARE @zindex_sql NVARCHAR(max); SET @zindex_sql = N''; SELECT @zindex_sql = @zindex_sql + ...

  2. - Permission 运行时权限 总结 翻译 MD

    目录 目录 对运行时权限的一些理解 运行时权限使用案例 开源库:PermissionsDispatcher 注解 使用案例 使用步骤 测试代码 自动生成的类 官方文档:请求权限 Add permiss ...

  3. 基于TCP实现的Socket通讯详解

    Socket通信是基于TCP协议进行的传输层通信,是在应用和应用之间的通信,一般应用在即时通讯上. 建立连接 用Socket创建连接需要在客户端和服务端都使用socket套接字. Linux内存创建S ...

  4. 入门-windows下安装ETH挖矿

    对刚入门的区块链开发者来说,刚开始可以在windows本地搭建私有链,便于操作,毕竟,要想真正挖到币还是有难度的,下面以ETH为例,在windows环境下安装并实现挖矿. 步骤一.安装geth环境.下 ...

  5. Jquery源码解析及案例分析

    本人刚学先上链接(别人写的挺好的)后期同步补上

  6. RabbitMQ学习之Topics(5)

    上一节,我们讲了direct exchange,这节我们讲下topic exchange Topic exchange 发送到topic exchange的messages不可以有一个随意的routi ...

  7. ffmpeg开发文档

    libavcodec - 编码解码器 libavdevice - 输入输出设备的支持 libavfilter - 视音频滤镜支持 libavformat - 视音频等格式的解析 libavutil - ...

  8. Qt Graphics-View的打印功能实现

    本文来研究一下Qt Graphics-View的打印功能实现. 在Qt的官方文档中介绍了Graphics-View的打印相关内容. Qt中对打印的支持是有一个独立的printsupport模块来完成的 ...

  9. python爬虫爬取天气数据并图形化显示

    前言 使用python进行网页数据的爬取现在已经很常见了,而对天气数据的爬取更是入门级的新手操作,很多人学习爬虫都从天气开始,本文便是介绍了从中国天气网爬取天气数据,能够实现输入想要查询的城市,返回该 ...

  10. android studio学习---快捷键

    快捷键学习  TIPS: 1.异常代码块  或者自定义代码块结构  Ctrl+Alt+T  或者   File | Settings | File and Code Templates When yo ...