urfave/cli

A Go package for building simple, fast, and fun command line applications. Features an expressive API.

goclisimplefast

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)
	}
}