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. SQL Server的NTEXT类型不支持等号"="操作(转载)

    SQL SERVER – Fix: Error : 402 The data types ntext and varchar are incompatible in the equal to oper ...

  2. Java静态变量初始化的坑

    class SingleTon { private static SingleTon singleTon = new SingleTon(); public static int count1; pu ...

  3. vue 鼠标右击事件

    使用@contextmenu.prevent即可 参考:https://www.cnblogs.com/sxz2008/p/6953082.html

  4. 使用Nexus3搭建Maven私服+上传第三方jar包到本地maven仓库

    1.搭建Maven私服背景 公司还是按捺不住,要搭建一个自己的Maven本地仓库,可以让开发人员down架包,从内网还是快很多. 这样公司的maven本地仓库就是 开发人员自己电脑上的maven仓库 ...

  5. axios + vue导出excel文件

    (使用到了elementUI框架) <template> <el-button type="primary" size="mini" @cli ...

  6. JSP+SpringMVC框架使用WebUploader插件实现注册时候头像图片的异步上传功能

    一.去官网下载webuploader文件上传插件 https://fex.baidu.com/webuploader/ 下载好后把它放到Javaweb项目的文件夹中(我放到了webcontent下面的 ...

  7. 浏览器标签页切换时jquery动画的问题

    最近公司在做大屏设备上的页面,其中动画的部分居多,开始的时候是用的jquery做的动画,在做完后无意中发现jquery动画存在一个问题,就是浏览器在切换标签页后,过段时间切换回来页面中的动画会出现连续 ...

  8. JS判断是否是数组的四种做法(转载)

    转载来源 https://www.cnblogs.com/echolun/p/10287616.html 一.前言 如何判断一个对象或一个值是否是一个数组,在面试或工作中我们常常会遇到这个问题,既然出 ...

  9. fiddler模拟弱网测试

    1.首先设置手机代理 设置手机代理到本机ip,端口号8888(Fiddler默认设置): 手机访问http://ip:port安装Fiddler证书 2.修改fiddler配置 勾选上后,已经开始限速 ...

  10. Python学习日记(三十九) Mysql数据库篇 七

    Mysql函数 高级函数 1.BIN(N) 返回N的二进制编码 ); 执行结果: 2.BINARY(str) 将字符串str转换为二进制字符串 select BINARY('ASCII'); 执行结果 ...