Kingpin
A Go command line argument parser. Features fluent interface and POSIX/GNU convention support.
Framework
Kingpin
Overview
Kingpin is a Go command line argument parser. It features fluent interface and POSIX/GNU convention support. It provides a simple and intuitive API, making it easy to build complex command-line structures. It's currently in maintenance mode, and other options are recommended for new projects.
Details
Kingpin has been a proven CLI library used by the Go community for many years. Its fluent interface enables highly readable command definitions and has been adopted by many open source projects. However, active development has now ended and it has moved to maintenance mode. For new projects, using more actively developed libraries like cobra or urfave/cli is recommended.
Key Features
- Fluent Interface: Intuitive API through method chaining
- POSIX/GNU Convention Support: Compliant with standard command-line conventions
- Subcommands: Supports hierarchical command structures
- Custom Validation: Enables implementation of custom value validation logic
- Shell Completion: Supports completion for Bash, Zsh, Fish, and PowerShell
- Environment Variable Support: Can retrieve flag default values from environment variables
- Help Generation: Automatic generation of help messages and usage
Pros and Cons
Pros
- Readability: Easy-to-understand code through fluent interface
- Rich Features: Covers all features needed for full-fledged CLI applications
- Standards Compliant: Consistent behavior conforming to POSIX/GNU conventions
- Flexibility: Enables implementation of custom validation and value parsers
- Track Record: Adoption record in many projects
Cons
- Maintenance Status: Currently in maintenance mode with new feature development stopped
- Community: Limited active community support
- Future Viability: Concerns about long-term support
- Learning Cost: Other options are recommended for new projects
Key Links
Example Usage
package main
import (
"fmt"
"net"
"os"
"strings"
"time"
"github.com/alecthomas/kingpin/v2"
)
var (
// Global flags
debug = kingpin.Flag("debug", "Enable debug mode").Bool()
timeout = kingpin.Flag("timeout", "Timeout waiting for ping").
Default("5s").
Envar("PING_TIMEOUT").
Short('t').
Duration()
// Arguments
ip = kingpin.Arg("ip", "IP address to ping").Required().IP()
count = kingpin.Arg("count", "Number of packets to send").Int()
)
func main() {
// Set version
kingpin.Version("0.0.1")
// Parse arguments
kingpin.Parse()
// Execute
fmt.Printf("Would ping: %s with timeout %s and count %d\n", *ip, *timeout, *count)
if *debug {
fmt.Println("Debug mode enabled")
}
}
// Example with subcommands
func withSubcommands() {
var (
app = kingpin.New("chat", "A command-line chat application")
// Global flags
serverIP = app.Flag("server", "Server address").Default("127.0.0.1").IP()
debug = app.Flag("debug", "Enable debug mode").Bool()
// register command
register = app.Command("register", "Register a new user")
registerNick = register.Arg("nick", "Nickname for user").Required().String()
registerName = register.Arg("name", "Name of user").Required().String()
// post command
post = app.Command("post", "Post a message to a channel")
postChannel = post.Arg("channel", "Channel to post to").Required().String()
postText = post.Arg("text", "Text to post").Strings()
postImage = post.Flag("image", "Image to post").File()
)
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case register.FullCommand():
fmt.Printf("Register user: %s (%s)\n", *registerNick, *registerName)
case post.FullCommand():
fmt.Printf("Posting to channel %s\n", *postChannel)
if *postImage != nil {
fmt.Println("With image attachment")
}
if len(*postText) > 0 {
fmt.Printf("Message: %s\n", strings.Join(*postText, " "))
}
}
}