cli 開發在golang 的軟件開發中佔用很大,同時開源的比較好用的cli也不少,如下是整理的幾個cligit
這個比較有名了, 好多框架都使用了這個
如下是一個簡單的使用 github
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.
這個也比較有名,好多框架也使用了這個golang
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
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, _
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
這個是hashicorp 好多產品使用的一個cliweb
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
這個cli pacakge 也是你們用的比較多的一個json
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,後期會繼續完善api
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/cliappbash