goflag

package module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 7, 2026 License: MIT Imports: 15 Imported by: 2

README

goflag

A simple, type-safe command-line flag parsing library for Go with support for subcommands.

Features

  • Type-safe flag parsing with dedicated methods for common types
  • Support for subcommands with their own flags
  • Required flags validation and custom validators for each flag.
  • Method chaining for cleaner API
  • Rich set of built-in types (strings, numbers, durations, URLs, IPs, emails, etc.)
  • Automatic help generation
  • Bash and zsh completions

Installation

go get github.com/abiiranathan/goflag

Quick Start

package main

import (
    "fmt"
    "log"
    "os"
    "time"
    
    "github.com/abiiranathan/goflag"
)

func main() {
    var (
        config  string
        verbose bool
        timeout time.Duration
        port    int
    )
    
    cli := goflag.New()
    
    // Define flags using helper methods
    cli.String("config", "c", &config, "Path to config file").Required()
    cli.Bool("verbose", "v", &verbose, "Enable verbose output")
    cli.Duration("timeout", "t", &timeout, "Request timeout")
    cli.Int("port", "p", &port, "Port to listen on")
    
    // Parse arguments
    subcmd, err := cli.Parse(os.Args)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Config: %s\n", config)
    fmt.Printf("Verbose: %v\n", verbose)
    fmt.Printf("Timeout: %v\n", timeout)
    fmt.Printf("Port: %d\n", port)

	if subcmd != nil{
		subcmd.Handler()
	}
}

Subcommands

Create subcommands with their own flags:

var (
    name     string = "World"
    greeting string = "Hello"
    upper    bool
)

func greetUser() {
    message := fmt.Sprintf("%s, %s!", greeting, name)
    if upper {
        message = strings.ToUpper(message)
    }
    fmt.Println(message)
}

func main() {
    cli := goflag.New()
    
    // Define a subcommand with flags
    cli.SubCommand("greet", "Greet a person", greetUser).
        String("name", "n", &name, "Name of the person to greet").Required().
        String("greeting", "g", &greeting, "Greeting to use").
        Bool("upper", "u", &upper, "Print in upper case")
    
    subcmd, err := cli.Parse(os.Args)
    if err != nil {
        log.Fatal(err)
    }
    
    if subcmd != nil {
        subcmd.Handler()
        os.Exit(0)
    }
}

Usage:

$ myapp greet --name John --upper
HELLO, JOHN!

$ myapp greet -n Alice -g "Good morning"
Good morning, Alice!

Supported Flag Types

Basic Types
cli.String("name", "n", &str, "String value")
cli.Int("count", "c", &num, "Integer value")
cli.Int64("big", "b", &big, "64-bit integer")
cli.Float32("ratio", "r", &f32, "32-bit float")
cli.Float64("pi", "p", &f64, "64-bit float")
cli.Bool("verbose", "v", &verbose, "Boolean flag")
cli.Rune("char", "c", &char, "Single character")
Time Types
cli.Duration("timeout", "t", &duration, "Duration (e.g., 5s, 2m)")
cli.Time("start", "s", &start, "Timestamp")
Slice Types
cli.StringSlice("origins", "o", &origins, "Allowed origins")
cli.IntSlice("ports", "p", &ports, "Port numbers")
Network Types
cli.IP("address", "a", &ip, "IP address")
cli.MAC("mac", "m", &mac, "MAC address")
cli.URL("endpoint", "e", &url, "URL")
cli.HostPortPair("listen", "l", &hostport, "Host:port pair")
Special Types
cli.Email("contact", "c", &email, "Email address")
cli.UUID("id", "i", &uuid, "UUID")
cli.FilePath("input", "i", &file, "Input file path")
cli.DirPath("output", "o", &dir, "Output directory")

Required Flags

Mark flags as required using the .Required() method:

cli.String("config", "c", &config, "Config file").Required()
cli.Int("port", "p", &port, "Server port").Required()

Complete Example

package main

import (
    "fmt"
    "log"
    "net"
    "net/url"
    "os"
    "time"
    
    "github.com/abiiranathan/goflag"
    "github.com/google/uuid"
)

var (
    config    string
    verbose   bool
    port      int
    timeout   time.Duration
    start     time.Time
    urlValue  url.URL
    uuidVal   uuid.UUID
    ipVal     net.IP
    macVal    net.HardwareAddr
    emailVal  string
    fileVal   string
    dirVal    string
    origins   []string
    methods   []string
)

func main() {
    log.SetFlags(log.Lshortfile)
    cli := goflag.New()
    
    // Global flags
    cli.String("config", "c", &config, "Path to config file").Required()
    cli.Bool("verbose", "v", &verbose, "Enable verbose output")
    cli.Duration("timeout", "t", &timeout, "Request timeout")
    cli.Int("port", "p", &port, "Port to listen on")
    cli.Time("start", "s", &start, "Start time")
    cli.URL("url", "u", &urlValue, "URL to fetch")
    cli.UUID("uuid", "i", &uuidVal, "UUID to use")
    cli.IP("ip", "", &ipVal, "IP address")
    cli.MAC("mac", "m", &macVal, "MAC address")
    cli.Email("email", "e", &emailVal, "Email address")
    cli.FilePath("file", "f", &fileVal, "File path")
    cli.DirPath("dir", "d", &dirVal, "Directory path")
    cli.StringSlice("origins", "o", &origins, "Allowed origins")
    cli.StringSlice("methods", "", &methods, "HTTP methods")
    
    // Subcommands
    cli.SubCommand("serve", "Start the server", startServer).
        Int("workers", "w", &workers, "Number of workers").Required()
    
    cli.SubCommand("version", "Print version", printVersion).
        Bool("short", "s", &short, "Short version format")
    
    // Parse
    subcmd, err := cli.Parse(os.Args)
    if err != nil {
        log.Fatal(err)
    }
    
    if subcmd != nil {
        subcmd.Handler()
        os.Exit(0)
    }
    
    // Main program logic when no subcommand is provided
    fmt.Printf("Config: %s\n", config)
    fmt.Printf("Verbose: %v\n", verbose)
    fmt.Printf("Port: %d\n", port)
}

Method Chaining

Both global flags and subcommand flags support method chaining:

// Global flags
cli.String("config", "c", &config, "Config file").Required()

// Subcommand flags
cli.SubCommand("deploy", "Deploy application", deployApp).
    String("env", "e", &env, "Environment").Required().
    Bool("dry-run", "d", &dryRun, "Dry run mode").
    StringSlice("tags", "t", &tags, "Deployment tags")

Usage Examples

# Using long flags
$ myapp --config app.json --verbose --port 8080

# Using short flags
$ myapp -c app.json -v -p 8080

# Using subcommands
$ myapp greet --name Alice

# slice flags
$ myapp --origins http://localhost:3000,http://localhost:8080

# Help
$ myapp --help
$ myapp greet --help

API Reference

CLI Methods
  • New() *CLI - Create a new CLI instance
  • Parse(args []string) (*Subcommand, error) - Parse command-line arguments
  • SubCommand(name, description string, handler func()) *Subcommand - Add a subcommand
Flag Definition Methods

All methods follow the pattern: Type(name, shortName string, valuePtr any, usage string) *Flag

Available on both *CLI and *Subcommand:

  • String() - String flag
  • Int() - Integer flag
  • Int64() - 64-bit integer flag
  • Float32() - 32-bit float flag
  • Float64() - 64-bit float flag
  • Bool() - Boolean flag
  • Rune() - Single character flag
  • Duration() - time.Duration flag
  • Time() - time.Time flag
  • StringSlice() - String slice flag
  • IntSlice() - Integer slice flag
  • IP() - IP address flag
  • MAC() - MAC address flag
  • URL() - URL flag
  • UUID() - UUID flag
  • HostPortPair() - Host:port pair flag
  • Email() - Email address flag
  • FilePath() - File path flag
  • DirPath() - Directory path flag
Flag Methods
  • Required() - Mark flag as required
Subcommand Methods
  • Handler() - Execute the subcommand handler

License

MIT License

Documentation

Overview

A simple flag package for go. Support for --flag value and -flag values. Built in subcommand support and flag validation. Author: Dr. Abiira Nathan. Date: Sept 25. 2023 License: MIT License

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Choices added in v0.1.5

func Choices[T comparable](choices []T) func(v any) (bool, string)

func Max added in v0.1.5

func Max[T cmp.Ordered](maxValue T) func(v any) (bool, string)

func MaxStringLen added in v0.1.5

func MaxStringLen(length int) func(v any) (bool, string)

func Min added in v0.1.5

func Min[T cmp.Ordered](minValue T) func(v any) (bool, string)

func MinStringLen added in v0.1.5

func MinStringLen(length int) func(v any) (bool, string)

func ParseBool

func ParseBool(value string) (bool, error)

Parse a string to a bool.

func ParseDirPath

func ParseDirPath(value string) (string, error)

Resolve dirname from value and check that it exists.

func ParseDuration

func ParseDuration(value string) (time.Duration, error)

Parse a string to a duration. Uses time.ParseDuration. Supported units are "ns", "us" (or "µs"), "ms", "s", "m", "h". e.g 1h30m, 1h, 1m30s, 1m, 1m30s, 1ms, 1us, 1ns

func ParseEmail

func ParseEmail(value string) (string, error)

parse email from string with mail.Parse

func ParseFilePath

func ParseFilePath(value string) (string, error)

Resolve absolute file path and check that it exists.

func ParseFloat32

func ParseFloat32(value string) (float32, error)

Parse a string to a float32.

func ParseFloat64

func ParseFloat64(value string) (float64, error)

Parse a string to a float64.

func ParseHostPort

func ParseHostPort(value string) (string, error)

parse host:port pair from value An empty string is considered a valid host. :) e.g ":8000" is a valid host-port pair.

func ParseIP

func ParseIP(value string) (net.IP, error)

func ParseInt

func ParseInt(value string) (int, error)

Parse a string to an int.

func ParseInt64

func ParseInt64(value string) (int64, error)

Parse a string to an int64.

func ParseIntSlice

func ParseIntSlice(value string) ([]int, error)

Parse a comma-seperated string into a slice of ints.

func ParseMAC

func ParseMAC(value string) (net.HardwareAddr, error)

func ParseRune

func ParseRune(value string) (rune, error)

Parse a string to a rune.

func ParseStringSlice

func ParseStringSlice(value string) ([]string, error)

Parse a comma-seperated string into a slice of strings.

func ParseTime

func ParseTime(value string) (time.Time, error)

Parse a string to a time.Time. Uses time.Parse. Supported formats are: "2006-01-02T15:04 MST"

func ParseUUID

func ParseUUID(value string) (uuid.UUID, error)

parse UUID using the github.com/google/uuid package.

func ParseUrl

func ParseUrl(value string) (*url.URL, error)

parse url from string with url.Parse.

func Range added in v0.1.5

func Range[T cmp.Ordered](minValue, maxValue T) func(v any) (bool, string)

Types

type CLI added in v0.2.0

type CLI struct {
	// contains filtered or unexported fields
}

Global flag context. Stores global flags and subcommands.

func New added in v0.2.0

func New() *CLI

Create a new command-line interface.

func (*CLI) Bool added in v0.2.0

func (c *CLI) Bool(name, shortName string, valuePtr *bool, usage string) *Flag

Bool adds a boolean flag to the CLI. Boolean flags don't require a value; their presence sets them to true. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a bool variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) DirPath added in v0.2.0

func (c *CLI) DirPath(name, shortName string, valuePtr *string, usage string) *Flag

DirPath adds a directory path flag to the CLI. Can optionally validate that the directory exists. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a string variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Duration added in v0.2.0

func (c *CLI) Duration(name, shortName string, valuePtr *time.Duration, usage string) *Flag

Duration adds a time.Duration flag to the CLI. Accepts duration strings like "5s", "2m", "1h30m", etc. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a time.Duration variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Email added in v0.2.0

func (c *CLI) Email(name, shortName string, valuePtr *string, usage string) *Flag

Email adds an email address flag to the CLI. Validates basic email format. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a string variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) FilePath added in v0.2.0

func (c *CLI) FilePath(name, shortName string, valuePtr *string, usage string) *Flag

FilePath adds a file path flag to the CLI. Can optionally validate that the file exists. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a string variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Float32 added in v0.2.0

func (c *CLI) Float32(name, shortName string, valuePtr *float32, usage string) *Flag

Float32 adds a 32-bit floating point flag to the CLI. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a float32 variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Float64 added in v0.2.0

func (c *CLI) Float64(name, shortName string, valuePtr *float64, usage string) *Flag

Float64 adds a 64-bit floating point flag to the CLI. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a float64 variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) GenBashCompletion added in v0.2.0

func (c *CLI) GenBashCompletion(w io.Writer)

GenBashCompletion generates a bash completion script and writes it to w. The completion script provides intelligent tab completion for commands, subcommands, and flags. Only long-form flags (--flag) are shown in completions to reduce clutter; short flags can still be used but won't appear in completion suggestions.

func (*CLI) GenZshCompletion added in v0.2.0

func (c *CLI) GenZshCompletion(w io.Writer)

GenZshCompletion generates a zsh completion script and writes it to w. The completion script provides intelligent tab completion for commands, subcommands, and flags. Only long-form flags (--flag) are shown in completions to reduce clutter; short flags can still be used but won't appear in completion suggestions.

The completion will show both subcommands and global flags when pressing tab at the command prompt, making it easy to discover both options. GenZshCompletion generates a zsh completion script and writes it to w.

func (*CLI) HostPortPair added in v0.2.0

func (c *CLI) HostPortPair(name, shortName string, valuePtr *string, usage string) *Flag

HostPortPair adds a host:port pair flag to the CLI. Accepts values like "localhost:8080" or "192.168.1.1:443". Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a string variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) IP added in v0.2.0

func (c *CLI) IP(name, shortName string, valuePtr *net.IP, usage string) *Flag

IP adds an IP address flag to the CLI. Accepts both IPv4 and IPv6 addresses. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a net.IP variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) InstallCompletion added in v0.2.0

func (c *CLI) InstallCompletion(shell string) error

InstallCompletion installs shell completion scripts for the CLI application. This function automatically detects the user's shell (bash or zsh) and installs the appropriate completion script to the user's home directory.

For bash, the completion script is installed to ~/.bash_completion.d/<binName> and a source line is added to ~/.bashrc if not already present.

For zsh, the completion script is installed to ~/.zsh/completion/_<binName> and the necessary fpath and compinit lines are added to ~/.zshrc if not already present.

Parameters:

  • shell: The shell to install completions for ("bash" or "zsh")

Returns an error if installation fails.

Example:

cli := goflag.NewCLI()
if err := cli.InstallCompletion("bash"); err != nil {
    fmt.Fprintf(os.Stderr, "Failed to install completion: %v\n", err)
}

func (*CLI) Int added in v0.2.0

func (c *CLI) Int(name, shortName string, valuePtr *int, usage string) *Flag

Int adds an integer flag to the CLI. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to an int variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Int64 added in v0.2.0

func (c *CLI) Int64(name, shortName string, valuePtr *int64, usage string) *Flag

Int64 adds a 64-bit integer flag to the CLI. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to an int64 variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) IntSlice added in v0.2.0

func (c *CLI) IntSlice(name, shortName string, valuePtr *[]int, usage string) *Flag

IntSlice adds an integer slice flag to the CLI. Can be specified multiple times to build a list of integer values. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a []int variable where the parsed values will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) MAC added in v0.2.0

func (c *CLI) MAC(name, shortName string, valuePtr *net.HardwareAddr, usage string) *Flag

MAC adds a MAC address flag to the CLI. Accepts MAC addresses in standard formats (e.g., "01:23:45:67:89:ab"). Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a net.HardwareAddr variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) Parse added in v0.2.0

func (c *CLI) Parse(argv []string) (*subcommand, error)

Parse the flags and subcommands. args should be os.Args. The first argument is ignored as it is the program name.

Populates the values of the flags and also finds the matching subcommand. Returns the matching subcommand.

func (*CLI) PrintUsage added in v0.2.0

func (c *CLI) PrintUsage(w io.Writer)

Print the usage to the writer. Called by Parse if the help flag is present. help flag is automatically added to the context. May be called as help, --help, -h, --h

Help for a given subcommand can be printed by passing the subcommand name as the glag --subcommand or -c. e.g. --help -c greet

func (*CLI) Rune added in v0.2.0

func (c *CLI) Rune(name, shortName string, valuePtr *rune, usage string) *Flag

Rune adds a single Unicode character flag to the CLI. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a rune variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) String added in v0.2.0

func (c *CLI) String(name, shortName string, valuePtr *string, usage string) *Flag

String adds a string flag to the CLI. Parameters:

  • name: The long name of the flag (e.g., "output")
  • shortName: The short name of the flag (e.g., "o"), can be empty
  • valuePtr: Pointer to a string variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration (e.g., setting required status).

func (*CLI) StringSlice added in v0.2.0

func (c *CLI) StringSlice(name, shortName string, valuePtr *[]string, usage string) *Flag

StringSlice adds a string slice flag to the CLI. Can be specified multiple times to build a list of values. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a []string variable where the parsed values will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) SubCommand added in v0.2.0

func (c *CLI) SubCommand(name, description string, handler func()) *subcommand

Add a subcommand to the command-line context.

func (*CLI) Time added in v0.2.0

func (c *CLI) Time(name, shortName string, valuePtr *time.Time, usage string) *Flag

Time adds a time.Time flag to the CLI. Accepts various time formats for parsing. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a time.Time variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) URL added in v0.2.0

func (c *CLI) URL(name, shortName string, valuePtr *url.URL, usage string) *Flag

URL adds a URL flag to the CLI. Validates and parses URLs according to RFC 3986. Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a *url.URL variable where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) UUID added in v0.2.0

func (c *CLI) UUID(name, shortName string, valuePtr *uuid.UUID, usage string) *Flag

UUID adds a UUID flag to the CLI. Accepts UUIDs in standard format (e.g., "550e8400-e29b-41d4-a716-446655440000"). Parameters:

  • name: The long name of the flag
  • shortName: The short name of the flag, can be empty
  • valuePtr: Pointer to a string or UUID type where the parsed value will be stored
  • usage: Description of the flag shown in help text

Returns the created Flag for further configuration.

func (*CLI) UninstallCompletion added in v0.2.0

func (c *CLI) UninstallCompletion(shell string) error

UninstallCompletion removes shell completion scripts for the CLI application. This function removes the completion script from the user's home directory and cleans up any references to it in shell configuration files.

For bash, the completion script is removed from ~/.bash_completion.d/<binName> and the source line is removed from ~/.bashrc.

For zsh, the completion script is removed from ~/.zsh/completion/_<binName>. Note that fpath and compinit lines remain in ~/.zshrc as they may be used by other completions.

Parameters:

  • shell: The shell to uninstall completions for ("bash" or "zsh")

Returns an error if uninstallation fails.

Example:

cli := goflag.NewCLI()
if err := cli.UninstallCompletion("bash"); err != nil {
    fmt.Fprintf(os.Stderr, "Failed to uninstall completion: %v\n", err)
}

type Flag added in v0.1.0

type Flag struct {
	// contains filtered or unexported fields
}

A Flag as parsed from the command line.

func (*Flag) Required added in v0.1.0

func (flag *Flag) Required() *Flag

func (*Flag) Validate added in v0.1.0

func (flag *Flag) Validate(validators ...FlagValidator) *Flag

Add validator to last flag in the subcommand chain. If no flag exists, it panics.

type FlagValidator added in v0.3.0

type FlagValidator func(value any) (valid bool, errmsg string)

Directories

Path Synopsis
cmd
example command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL