urfave/cli
A Go package for building simple, fast, and fun command line applications. Features an expressive API.
Framework
urfave/cli
Overview
urfave/cli is a Go package for building simple, fast, and fun command-line applications. It features an expressive API and is popular for small to medium-sized CLI tools. It's supported by developers who value simplicity and ease of use, and is adopted in many Go projects.
Details
urfave/cli has been widely used as a Go CLI library for many years, with the v2 series currently provided as the stable version. The v3 series is also under development, planned to provide a more modern API. This library comprehensively provides features necessary for full-fledged CLI applications, including commands, flags, subcommands, automatic help generation, and shell completion.
Key Features
- Expressive API: Enables intuitive and readable code writing
- Flag and Command Support: Rich flag types and subcommand functionality
- Automatic Help Generation: Automatic generation of help messages and usage
- Shell Completion: Supports completion for Bash, Zsh, Fish, and PowerShell
- Flexible Configuration: Detailed customization of applications possible
- Testing Support: Features that facilitate testing CLI applications
- Lightweight: High performance with minimal dependencies
Pros and Cons
Pros
- Low Learning Cost: Simple and intuitive API design
- High Flexibility: Can handle various CLI patterns
- Rich Features: Covers all features needed for full-fledged CLI applications
- Active Community: Continuous development and maintenance
- Excellent Documentation: Abundant examples and tutorials
Cons
- Adoption Rate vs Cobra: Cobra is more widely adopted in Go
- Large Applications: Other options worth considering for very complex CLI structures
- Version Differences: Some API differences between v1, v2, and v3
Key Links
Example Usage
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/urfave/cli/v2"
)
func main() {
app := &cli.App{
Name: "greet",
Usage: "greeting application",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "lang",
Aliases: []string{"l"},
Value: "english",
Usage: "language for greeting",
},
&cli.BoolFlag{
Name: "uppercase",
Aliases: []string{"u"},
Usage: "display in uppercase",
},
},
Commands: []*cli.Command{
{
Name: "hello",
Aliases: []string{"h"},
Usage: "hello command",
Action: func(c *cli.Context) error {
name := "world"
if c.NArg() > 0 {
name = c.Args().Get(0)
}
greeting := "Hello"
if c.String("lang") == "japanese" {
greeting = "こんにちは"
}
msg := fmt.Sprintf("%s %s!", greeting, name)
if c.Bool("uppercase") {
msg = strings.ToUpper(msg)
}
fmt.Println(msg)
return nil
},
},
{
Name: "goodbye",
Usage: "goodbye command",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "formal",
Usage: "use formal greeting",
},
},
Action: func(c *cli.Context) error {
name := "world"
if c.NArg() > 0 {
name = c.Args().Get(0)
}
if c.Bool("formal") {
fmt.Printf("Goodbye, %s\n", name)
} else {
fmt.Printf("Bye, %s!\n", name)
}
return nil
},
},
},
Action: func(c *cli.Context) error {
fmt.Println("This is a greeting application. Use 'help' to display help.")
return nil
},
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}