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. PowerBuilder学习笔记之2PowerScript语言(一)

    教材链接:https://wenku.baidu.com/view/1e82d26925c52cc58ad6be05.html?sxts=1565679996440 2.1PowerScript基础 ...

  2. LOJ2874 JOISC2014 历史研究 分块、莫队

    传送门 看到出现次数自然地考虑莫队. 但是发现如果需要删除并动态维护答案的话,则要用一个堆来维护答案,增加了一个\(log\).但是加入操作却没有这个\(log\),所以我们考虑避免删除操作. 分块, ...

  3. Channel延续篇

    上篇文章中介绍了NIO中的Channel,从Channel是什么.特性.分类几个方面做了下简单的介绍.但是后面Channel的分类,个人感觉不够全面,容易误导读者,特此以这篇文章加以补充. Chann ...

  4. MySQL一主二从复制环境切换主从库

    假设有一个一主二从的环境,当主库M出现故障时,需要将其中一个从库S1切换为主库,同时将S2指向新的主库S1,如果可能,需要将故障的主库M修复并重置为新的从库. 搭建一主二从复制环境可参考:mysql5 ...

  5. SQL server数据库创建代码,filegroup文件组修改,

    以下示例在 SQL Server 实例上创建了一个数据库.该数据库包括一个主数据文件.一个用户定义文件组和一个日志文件.主数据文件在主文件组中,而用户定义文件组包含两个次要数据文件.ALTER DAT ...

  6. 【开发笔记】-通过js控制input禁止输入空格

    <input type="text" id="fname" onkeyup="myFunction(id)"> <scri ...

  7. Android实现二维码扫描功能

    1.效果预览 先上图展示效果(模拟器没有摄像头,录出来效果不好,将就看) 2.集成步骤 1.拷贝本项目demo中的com.google.zxing5个包引入到自己的项目中. 2.拷贝本项目demo中的 ...

  8. Django知识点归纳总结之HTTP协议与URL

    Django复习知识点归纳总结 1.HTTP协议 ​ 超文本传输协议(Hyper Text Transfer Protocol),是用于万维网服务器与本地浏览器之间的传输超文本的传送协议. ​ HTT ...

  9. SaltStack--数据系统

    saltstack数据系统 数据系统Grains 1.Grains是SaltStack收集的有关底层管理系统的静态信息.包括操作系统版本.域名.IP地址.内存.内核.CPU.操作系统类型以及许多其他系 ...

  10. 如何为scratch3.0创建一个独立的页面或窗体

    很多人都利用GIT上的scratch3.0做开发,但是苦于有些定制需要个性化开发但是不知道如何动手.本篇文章来做好普及工作吧. 首先需要完成事项如下: 1.需要进行modal定义 2.新增窗口的UI界 ...