flagx

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: MIT Imports: 13 Imported by: 1

README

flagx

Test Status Coverage Status MIT License PkgGoDev

Flag aliases and formatted help, built on Go's standard flag.FlagSet. No dependencies or changes to flag parsing.

Synopsis

fs := flagx.NewFlagSet("myapp", flag.ExitOnError)

var output string
var verbose bool
var jobs int
var timeout time.Duration

fs.StringVar(&output, "output|o", "", "write to `file`")
fs.BoolVar(&verbose, "verbose|v", false, "verbose output")
fs.IntVar(&jobs, "jobs|j", 4, "number of `workers`")
fs.DurationVar(&timeout, "timeout|t", 30*time.Second, "timeout after `duration`")

fs.Usage = func() {
    fs.PrintUsage(fs.Output(), "myapp [options] <input>", "Process input files.")
}
fs.Parse(os.Args[1:])

Import github.com/Songmu/flagx alongside flag, os, and time. Running myapp --help prints:

Usage: myapp [options] <input>

Process input files.

Options:
  -output, -o file       write to file
  -verbose, -v           verbose output
  -jobs, -j workers      number of workers (default 4)
  -timeout, -t duration  timeout after duration (default 30s)
  -help, -h              Show this help message

Description

NewFlagSet(name, errorHandling) returns a *flagx.FlagSet embedding flag.FlagSet. Its registration methods accept one or more |-separated names. String, Bool, Int, Int64, Uint, Uint64, Float64, and Duration return a pointer shared by all names; their Var forms bind an existing variable. TextVar binds a value implementing encoding.TextUnmarshaler, and Var accepts a custom flag.Value. Func and BoolFunc invoke a callback for each occurrence; BoolFunc allows omitting the value. Defaults and parsing follow the corresponding standard flag.FlagSet methods.

Default help uses the flag set's current name as the synopsis and prints the formatted option list. Assign fs.Usage to customize it, as above. The zero value is usable with an empty name and flag.ContinueOnError; Init sets the name and error policy without clearing flags or custom help. Do not copy a FlagSet after first use.

The package-level registration and help functions remain available for existing *flag.FlagSet values, taking the flag set as an argument:

fs := flag.NewFlagSet("myapp", flag.ExitOnError)
flagx.String(fs, "output|o", "", "write to `file`")
fs.Usage = flagx.Usage(fs, "myapp [options]", "")

Use &fs.FlagSet when passing a *flagx.FlagSet to these functions or other APIs accepting a *flag.FlagSet. If another API parses &fs.FlagSet while Usage is nil (including a zero-value set), call fs.Init(fs.Name(), fs.ErrorHandling()) before handing it off to install flagx's default help.

Names omit leading hyphens and are split literally, without trimming whitespace. Empty names panic; duplicate and invalid names otherwise follow the standard library's behavior.

Names are aliases, not a required long/short pair: "output", "output|o", "o|output", "aa|bb", and "output|out|o" are all accepted. Help preserves the specified name order, so "o|output" displays as -o, -output string.

Both -output and --output work, as do -o and --o. Standard flag semantics still apply: parsing stops at the first positional argument, short flags cannot be bundled, and bool flags do not require a value.

Help combines names registered together and also values with the same pointer and concrete type, including flags registered directly through flag.FlagSet. Within each option, flagx-registered names retain their registration order; directly registered names follow, sorted long before short and lexicographically within each kind because their registration order is unavailable. All names have one hyphen.

Options registered through flagx come first, in registration order. Options registered only through flag.FlagSet follow, sorted by their lexicographically smallest long name, or their smallest short name if there is no long name. An option combining both kinds of registration uses its first flagx registration position. The first displayed name supplies the usage and default value when aliases have different metadata.

Pointer-based grouping of separately registered flags is a heuristic. Non-pointer values and pointers to zero-sized values are grouped only when their names are registered together. Backquoted placeholders use flag.UnquoteUsage; bool placeholders are omitted. Nonzero registration-time defaults are shown, with string defaults quoted. Custom values are compared with their type's zero value; if its String method panics, the default is shown without interrupting help output.

help and h are not registered: standard flag handles undefined help names. The option list displays missing help names and preserves explicitly registered ones. An explicitly registered help flag has its normal parsing behavior, so the application is responsible for handling it.

Custom help

Use PrintDefaults to embed just the option list in your own help:

fs.Usage = func() {
    fmt.Fprintln(fs.Output(), "Usage: myapp [options] <input>")
    fmt.Fprintln(fs.Output(), "\nOptions:")
    fs.PrintDefaults()
}

Default help and fs.PrintDefaults() use the current fs.Output(), including later SetOutput changes. fs.PrintUsage(w, synopsis, description) writes a complete help message to an explicit writer without changing the flag set. For a standard *flag.FlagSet, use flagx.PrintDefaults(fs) and flagx.PrintUsage(w, fs, synopsis, description) instead.

flagx does not manage subcommands, groups, required/hidden flags, or Markdown, man page, and shell completion generation.

Installation

% go get github.com/Songmu/flagx

Development

After changing GitHub Actions dependencies, run gh actions-lock and commit .github/workflows/actions.lock with the workflow changes. Install the tool with gh extension install github/gh-actions-lock.

Author

Songmu

Documentation

Overview

Package flagx adds flag aliases and formatted help to the standard library's flag.FlagSet without changing its parsing rules. Use NewFlagSet for a method-based API, or the package functions to extend an existing flag.FlagSet.

Example
package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/Songmu/flagx"
)

func main() {
	fs := flag.NewFlagSet("myapp", flag.ContinueOnError)
	fs.SetOutput(os.Stdout)
	var output string
	var verbose bool
	flagx.StringVar(fs, &output, "output|o", "", "write to `file`")
	flagx.BoolVar(fs, &verbose, "verbose|v", false, "verbose output")
	fs.Usage = flagx.Usage(fs, "myapp [options] <input>", "Process input files.")
	if err := fs.Parse([]string{"-o", "result.txt", "--verbose", "input.txt"}); err != nil {
		return
	}

	fmt.Println(output, verbose, fs.Args())
	fs.Usage()
}
Output:
result.txt true [input.txt]
Usage: myapp [options] <input>

Process input files.

Options:
  -output, -o file  write to file
  -verbose, -v      verbose output
  -help, -h         Show this help message

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool added in v0.0.2

func Bool(fs *flag.FlagSet, names string, value bool, usage string) *bool

Bool registers a boolean flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func BoolFunc added in v0.0.2

func BoolFunc(fs *flag.FlagSet, names, usage string, fn func(string) error)

BoolFunc registers a callback flag under the |-separated names, as in Var. Values are optional and default to "true" when omitted. Each occurrence calls fn with its value; a returned error stops parsing.

func BoolVar

func BoolVar(fs *flag.FlagSet, p *bool, names string, value bool, usage string)

BoolVar registers a boolean flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func Duration added in v0.0.2

func Duration(fs *flag.FlagSet, names string, value time.Duration, usage string) *time.Duration

Duration registers a duration flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func DurationVar

func DurationVar(fs *flag.FlagSet, p *time.Duration, names string, value time.Duration, usage string)

DurationVar registers a duration flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func Float64 added in v0.0.2

func Float64(fs *flag.FlagSet, names string, value float64, usage string) *float64

Float64 registers a float64 flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func Float64Var added in v0.0.2

func Float64Var(fs *flag.FlagSet, p *float64, names string, value float64, usage string)

Float64Var registers a float64 flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func Func added in v0.0.2

func Func(fs *flag.FlagSet, names, usage string, fn func(string) error)

Func registers a callback flag under the |-separated names, as in Var. Each occurrence calls fn with its value; a returned error stops parsing.

func Int added in v0.0.2

func Int(fs *flag.FlagSet, names string, value int, usage string) *int

Int registers an integer flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func Int64 added in v0.0.2

func Int64(fs *flag.FlagSet, names string, value int64, usage string) *int64

Int64 registers an int64 flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func Int64Var added in v0.0.2

func Int64Var(fs *flag.FlagSet, p *int64, names string, value int64, usage string)

Int64Var registers an int64 flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func IntVar

func IntVar(fs *flag.FlagSet, p *int, names string, value int, usage string)

IntVar registers an integer flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func PrintDefaults

func PrintDefaults(fs *flag.FlagSet)

PrintDefaults writes only the formatted option list to fs.Output. Names registered together are displayed in their specified order. Options registered through flagx come first, in registration order, followed by directly registered options in lexical order. Pointers to non-zero-sized values with the same type and address are also displayed as aliases. Missing help and h names are included for flag's built-in help handling, not registered.

func PrintUsage

func PrintUsage(w io.Writer, fs *flag.FlagSet, synopsis, description string)

PrintUsage writes a synopsis, an optional description, and an Options section to w. It does not change fs or its output writer.

func String added in v0.0.2

func String(fs *flag.FlagSet, names, value, usage string) *string

String registers a string flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func StringVar

func StringVar(fs *flag.FlagSet, p *string, names, value, usage string)

StringVar registers a string flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func TextVar added in v0.0.2

func TextVar(fs *flag.FlagSet, p encoding.TextUnmarshaler, names string, value encoding.TextMarshaler, usage string)

TextVar registers a text flag under the |-separated names, as in Var. All names write to p, which is initialized to value. p must be a pointer; value must have its type or the type it points to.

func Uint added in v0.0.2

func Uint(fs *flag.FlagSet, names string, value uint, usage string) *uint

Uint registers an unsigned integer flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func Uint64 added in v0.0.2

func Uint64(fs *flag.FlagSet, names string, value uint64, usage string) *uint64

Uint64 registers a uint64 flag under the |-separated names, as in Var. It returns a pointer to the shared value, initialized to value.

func Uint64Var added in v0.0.2

func Uint64Var(fs *flag.FlagSet, p *uint64, names string, value uint64, usage string)

Uint64Var registers a uint64 flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func UintVar added in v0.0.2

func UintVar(fs *flag.FlagSet, p *uint, names string, value uint, usage string)

UintVar registers an unsigned integer flag under the |-separated names, as in Var. All names write to p, which is initialized to value.

func Usage

func Usage(fs *flag.FlagSet, synopsis, description string) func()

Usage returns a help function suitable for fs.Usage. It uses fs.Output at call time, including subsequent SetOutput changes.

func Var

func Var(fs *flag.FlagSet, value flag.Value, names, usage string)

Var registers value under each name in the |-separated names string. Names omit leading hyphens and are displayed in the specified order. Empty names panic; duplicate and invalid names follow flag.FlagSet behavior.

Types

type FlagSet added in v0.0.4

type FlagSet struct {
	flag.FlagSet
}

FlagSet extends flag.FlagSet with alias-aware registration and formatted help. Registration methods accept |-separated names, as in Var. The zero value has no name and uses flag.ContinueOnError. A FlagSet must not be copied after first use.

func NewFlagSet added in v0.0.4

func NewFlagSet(name string, errorHandling flag.ErrorHandling) *FlagSet

NewFlagSet returns an empty flag set with the specified name and error policy. Its default Usage prints the name and the formatted option list.

Example
package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/Songmu/flagx"
)

func main() {
	fs := flagx.NewFlagSet("myapp", flag.ContinueOnError)
	fs.SetOutput(os.Stdout)
	output := fs.String("output|o", "", "write to `file`")
	verbose := fs.Bool("verbose|v", false, "verbose output")
	if err := fs.Parse([]string{"-o", "result.txt", "--verbose", "input.txt"}); err != nil {
		return
	}
	fmt.Println(*output, *verbose, fs.Args())
	fs.Usage()
}
Output:
result.txt true [input.txt]
Usage: myapp

Options:
  -output, -o file  write to file
  -verbose, -v      verbose output
  -help, -h         Show this help message

func (*FlagSet) Bool added in v0.0.4

func (fs *FlagSet) Bool(names string, value bool, usage string) *bool

Bool registers the |-separated names, as in Bool.

func (*FlagSet) BoolFunc added in v0.0.4

func (fs *FlagSet) BoolFunc(names, usage string, fn func(string) error)

BoolFunc registers a boolean callback under the |-separated names, as in BoolFunc.

func (*FlagSet) BoolVar added in v0.0.4

func (fs *FlagSet) BoolVar(p *bool, names string, value bool, usage string)

BoolVar binds p to the |-separated names, as in BoolVar.

func (*FlagSet) Duration added in v0.0.4

func (fs *FlagSet) Duration(names string, value time.Duration, usage string) *time.Duration

Duration registers the |-separated names, as in Duration.

func (*FlagSet) DurationVar added in v0.0.4

func (fs *FlagSet) DurationVar(p *time.Duration, names string, value time.Duration, usage string)

DurationVar binds p to the |-separated names, as in DurationVar.

func (*FlagSet) Float64 added in v0.0.4

func (fs *FlagSet) Float64(names string, value float64, usage string) *float64

Float64 registers the |-separated names, as in Float64.

func (*FlagSet) Float64Var added in v0.0.4

func (fs *FlagSet) Float64Var(p *float64, names string, value float64, usage string)

Float64Var binds p to the |-separated names, as in Float64Var.

func (*FlagSet) Func added in v0.0.4

func (fs *FlagSet) Func(names, usage string, fn func(string) error)

Func registers a callback under the |-separated names, as in Func.

func (*FlagSet) Init added in v0.0.4

func (fs *FlagSet) Init(name string, errorHandling flag.ErrorHandling)

Init sets the name and error policy, installing formatted help if Usage is nil. It preserves registered flags and any existing Usage function.

func (*FlagSet) Int added in v0.0.4

func (fs *FlagSet) Int(names string, value int, usage string) *int

Int registers the |-separated names, as in Int.

func (*FlagSet) Int64 added in v0.0.4

func (fs *FlagSet) Int64(names string, value int64, usage string) *int64

Int64 registers the |-separated names, as in Int64.

func (*FlagSet) Int64Var added in v0.0.4

func (fs *FlagSet) Int64Var(p *int64, names string, value int64, usage string)

Int64Var binds p to the |-separated names, as in Int64Var.

func (*FlagSet) IntVar added in v0.0.4

func (fs *FlagSet) IntVar(p *int, names string, value int, usage string)

IntVar binds p to the |-separated names, as in IntVar.

func (*FlagSet) Parse added in v0.0.4

func (fs *FlagSet) Parse(arguments []string) error

Parse parses arguments using flag.FlagSet's rules. If Usage is nil, it installs the default formatted help before parsing.

func (*FlagSet) PrintDefaults added in v0.0.4

func (fs *FlagSet) PrintDefaults()

PrintDefaults writes the formatted option list to fs.Output.

func (*FlagSet) PrintUsage added in v0.0.4

func (fs *FlagSet) PrintUsage(w io.Writer, synopsis, description string)

PrintUsage writes a synopsis, optional description, and formatted option list to w without changing fs.Output.

func (*FlagSet) String added in v0.0.4

func (fs *FlagSet) String(names, value, usage string) *string

String registers the |-separated names, as in String.

func (*FlagSet) StringVar added in v0.0.4

func (fs *FlagSet) StringVar(p *string, names, value, usage string)

StringVar binds p to the |-separated names, as in StringVar.

func (*FlagSet) TextVar added in v0.0.4

func (fs *FlagSet) TextVar(p encoding.TextUnmarshaler, names string, value encoding.TextMarshaler, usage string)

TextVar binds p to the |-separated names, as in TextVar.

func (*FlagSet) Uint added in v0.0.4

func (fs *FlagSet) Uint(names string, value uint, usage string) *uint

Uint registers the |-separated names, as in Uint.

func (*FlagSet) Uint64 added in v0.0.4

func (fs *FlagSet) Uint64(names string, value uint64, usage string) *uint64

Uint64 registers the |-separated names, as in Uint64.

func (*FlagSet) Uint64Var added in v0.0.4

func (fs *FlagSet) Uint64Var(p *uint64, names string, value uint64, usage string)

Uint64Var binds p to the |-separated names, as in Uint64Var.

func (*FlagSet) UintVar added in v0.0.4

func (fs *FlagSet) UintVar(p *uint, names string, value uint, usage string)

UintVar binds p to the |-separated names, as in UintVar.

func (*FlagSet) Var added in v0.0.4

func (fs *FlagSet) Var(value flag.Value, names, usage string)

Var registers value under each of the |-separated names, as in Var.

Jump to

Keyboard shortcuts

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