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. .net Core MongoDB用法演示

    C#驱动MongoDB的本质是将C#的操作代码转换为mongo shell,驱动的API也比较简单明了,方法名和js shell的方法名基本都保持一致,熟悉mongo shell后学习MongoDB的 ...

  2. 百度云 2G 4核 服务器拼团链接

    拼团链接如下: https://cloud.baidu.com/campaign/ABCSale-2019/index.html?teamCode=P3D6DV8T

  3. C# 索引器(C#学习笔记05)

    索引器 索引器能够使对象像数组一样被索引,使用数组的访问方式 object[x] 索引器的声明在某种程度上类似于属性的声明,例如,使用 get 和 set 方法来定义一个索引器. 不同的是,属性值的定 ...

  4. Vue自定义组件中Props中接收数组或对象

    原文:https://www.jianshu.com/p/904551dc6c15 自定义弹框组件时,需要在弹框内展示商品list,所以需要组件中的对应字段接收一个Array数组,默认返回空数组[], ...

  5. 由一个空工程改为SpringBoot工程

    1.先创建一个空的工程,创建springboot 工程  必须继承spring-boot-stater-parent 2.导入依赖 <parent> <groupId>org. ...

  6. springmvc注解一

    org.springframework.web.bind.annotation.RequestParam注解类型用于将指定的请求参数赋值给方法中 的形参 RequestParam注解 package ...

  7. vue 实现滚动到页面底部开始加载更多

    直接上代码: <template> <div class="newsList"> <div v-for="(items, index) in ...

  8. 36、v-charts一些基本配置修改

    例如柱状图: <ve-histogram :settings="chartSettings" :extend="chartExtend" :grid=&q ...

  9. Docker07-数据管理

    目录 将数据保存在容器外部 挂载参数 -v 案例:运行mysql容器,将mysql的数据放在主机/data/mysql-data中. 将数据保存在容器外部 容器在运行项目时会产生数据,比如运行的mys ...

  10. springboot2.1.3 本地加载jar包+打包载入本地jar

    项目已springboot为主,有时候我们需要引入的jar包并非maven公共库中存在(这里不谈私自搭建私库),那我们能否像普通的工程一样,导入自己手动添加的jar包文件呢? 答案是肯定的,来,一起往 ...