https://github.com/spf13/cobra
Many famous projects such as Kubernetes, Docker, etcd use Cobra to build their command line interfaces.
Overview
The Cobra library provides a simple interface to create a powerful modern command line interface similar to git and go tools.
The main function:
- CLI based on subcommands, such as
app server
,app fetch
- Parameter flags in full compliance with POSIX standards (both long and short flags are supported)
- Nested subcommand
- Global, local and cascaded parameter flags
- By
cobra init appname
andcobra add cmdname
build applications and commands - Smart prompt (app srver… did you mean app server?)
- Automatically generate command line and parameter flags
- Automatic recognition
-h
,--help
etc. - Automatically generate bash autocompletion for the program
- Automatically generate man manuals for applications
- Command alias for easy modification of content without damage
- Flexible definition of your help, usage, etc.
- Optional tight integration with viper
Command line structure
A good command line should be human-like. People can understand how to use the application by reading the command line.
The command line is mainly composed of four parts:
- APPNAME application name, subject
- Commands, predicates
- Args command parameter, object
- Flags flag parameters, how to execute the action of the set command, attributive/adverbial/complement
Such as:
git(主语) clone(谓语) URL(参数,宾语) --bear(参数,定语/状语/补语)
Use Cobra
Suggested code structure
▾ appName/
▾ cmd/
add.go
your.go
commands.go
here.go
main.go
Installation package
go get -u github.com/spf13/cobra/cobra
Use flag parameters (flags)
Define two flag parameters
var Verbose bool
var Source string
Flags (flag parameters) are divided into two categories:
- Persistent (global) flag parameters, also valid for subcommands of a command
rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
- Local flag parameters, only valid for the current command
localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
It is recommended to execute the root command from the main function.
Simple example
File structure
$ tree demo_cobra/
demo_cobra/
├── cmd
│ └── root.go
├── demo_cobra
└── main.go
main.go
package main
import (
"fmt"
"github.com/yourrepo/cmd"
"os"
)
func main() {
if err := cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
cmd/root.go
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"strings"
)
var (
verbose bool
rootCmd = &cobra.Command{
Use: "demo_cobra",
Short: "print flag parameters to screen",
Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(strings.Join(args, " "))
},
}
cloneCmd = &cobra.Command{
Use: "clone [remote repo's url]",
Short: "clone remote repo",
Long: `clone copy a remote repository to your local storage`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
fmt.Print("you are cloning ", args[0])
if verbose == true {
fmt.Println(" with verbose")
}
},
}
)
func Execute() error {
return rootCmd.Execute()
}
func init() {
cloneCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "whether output the detail information")
rootCmd.AddCommand(cloneCmd)
}
operation result
$ go run main.go help clone
clone copy a remote repository to your local storage
Usage:
demo_cobra clone [remote repo's url] [flags]
Flags:
-h, --help help for clone
-v, --verbose whether output the detail information
$ go run main.go abc 123 haha
abc 123 haha
Cobra can also define several hook functions for the Run function
- PersistentPreRun
- PreRun
- Run
- PostRun
- PersistentPostRun
It can also be integrated with Viper to bind configuration file setting values, etc., which is powerful.