goflag

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 2, 2024 License: MIT Imports: 13 Imported by: 2

README

goflag

GoDoc

A simple library for parsing command line arguments. It is designed to be a drop-in replacement for the standard library's flag package.

The main difference is that goflag

  • supports both short and long flags
  • requires no global state
  • has a beatiful API based on the builder pattern that allows you to define your subcommands and flags in a single expression
  • supports subcommands. Subcommands can have their own flags. However, subcommands cannot have subcommands of their own (yet).
  • Beautifully formatted help text, with support for subcommand help text too.
  • Supports custom validation of flags and arguments.
  • Supports custom flag types with -, -- and = syntax.

Installation

go get -u github.com/abiiranathan/goflag

Usage


package main

import (
	"fmt"
	"os"

	"github.com/abiiranathan/goflag"
)

func greetUser(ctx goflag.Getter, cmd goflag.Getter) {
	name := cmd.GetString("name")
	greeting := cmd.GetString("greeting")
	fmt.Println(greeting, name)

	// you have access to global flags
	ctx.GetBool("verbose") // etc

}

func printVersion(ctx *goflag.Context, cmd *goflag.Subcmd) {
	if cmd.Get("short").(bool) {
		fmt.Println("1.0.0")
	} else {
		fmt.Println("1.0.0")
		fmt.Println("Build Date: 2021-01-01")
		fmt.Println("Commit: 1234567890")
	}
}

func main() {
	ctx := goflag.NewContext()

	ctx.AddFlag(goflag.String("config", "c", "config.json", "Path to config file", true))
	ctx.AddFlag(goflag.Bool("verbose", "v", false, "Enable verbose output", false))

	ctx.AddSubCommand(goflag.SubCommand("greet", "Greet a person", greetUser)).
		AddFlag(goflag.String("name", "n", "World", "Name of the person to greet", true)).
		AddFlag(goflag.String("greeting", "g", "Hello", "Greeting to use", false)).
		Validate(func(a any) (bool, string) {
			if a.(string) == "World" {
				return false, "ERR: Name cannot be World"
			}
			return true, ""
		}).AddFlag(goflag.Bool("upper", "u", false, "Print in upper case", false))

	ctx.AddSubCommand(goflag.SubCommand("version", "Print version", printVersion)).
		AddFlag(goflag.Bool("verbose", "v", false, "Enable verbose output", false)).
		AddFlag(goflag.Bool("short", "s", false, "Print short version", false))

	// Parse the command line arguments and return the matching subcommand
	subcmd, err := ctx.Parse(os.Args)
	if err != nil {
		log.Fatalln(err)
	}

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

	fmt.Println(ctx.GetString("config"))
	fmt.Println(ctx.GetBool("verbose"))

}


Accessing flags values.

Note that ctx.Parse() returns the matching subcommand. If no subcommand is matched, it returns nil. The subcommand handler should be called with the context and the subcommand as arguments.

The handler can then access the flags and arguments using the Get or GetString, GetBool etc methods on either the context or the subcommand.

The context carries the global flags and the subcommand carries the subcommand specific flags.

Supported flag types are

  • string
  • bool
  • int
  • int64
  • float64
  • float32
  • time.Duration with format 1h2m3s, 1h, 1h2m, 1m2s, 1m, 1s as supported by the standard library's time.ParseDuration function.
  • time.Time with format 2006-01-02T15:04 MST
  • rune
  • []string (comma separated list of strings) with format a,b,c,d
  • []int (comma separated list of ints) with format 1,2,3,4
  • ip (IP address) with format xxx.xxx.xxx.xxx
  • mac (MAC address) with format xx:xx:xx:xx:xx:xx
  • hostport (IP address with port) pair with format host:port
  • path (file path) with format. Will be converted to be an absolute path and will be validated to exist.
  • url with format scheme://host:port/path?query#fragment
  • email with format local@domain. Validated using the standard library's mail.ParseAddress function.
  • uuid with format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (UUID v4 with Google's UUID package)

See Example for more details. Run the example with ./test.sh to see the output.

Preview of the help text
Usage: ./cli [flags] [subcommand] [flags]

Global Flags:
  --help     -h: Print help message and exit
  --config   -c: Path to config file
  --verbose  -v: Enable verbose output
  --timeout  -t: Timeout for the request
  --port     -p: Port to listen on
  --start    -s: Start time
  --url      -u: URL to fetch
  --uuid     -i: UUID to use
  --ip       -i: IP to use
  --mac      -m: MAC address to use
  --email    -e: Email address to use
  --hostport -h: Host:Port pair to use
  --file     -f: File path to use
  --dir      -d: Directory path to use

Subcommands:
  greet   : Greet a person
         --help     -h: Print help message and exit
         --name     -n: Name of the person to greet
         --greeting -g: Greeting to use
         --upper    -u: Print in upper case

  version : Print version
         --help    -h: Print help message and exit
         --verbose -v: Enable verbose output
         --short   -s: Print short version

  sleep   : Sleep for a while
         --help -h: Print help message and exit
         --time -t: Time to sleep in seconds

  cors    : Enable CORS
         --help        -h: Print help message and exit
         --origins     -o: Allowed origins
         --methods     -m: Allowed methods
         --headers     -d: Allowed headers
         --credentials -c: Allow credentials


Generate completion scripts

goflag automatically adds a subcommand to generate bash and zsh scripts for your CLIs.

mycli completions -zsh -out=script.sh
source script.sh

If no output file is provided, the script is printed to stdout.

Contributing

Contributions are welcome. Please open an issue to discuss your ideas before opening a PR.

License

MIT

TODO

  • Add support for subcommands of subcommands.
  • Implement more tests

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 Bool

func Bool(name, shortName string, value bool, usage string, required ...bool) *gflag

func DirPath

func DirPath(name, shortName string, value string, usage string, required ...bool) *gflag

func Duration

func Duration(name, shortName string, value time.Duration, usage string, required ...bool) *gflag

func Email

func Email(name, shortName string, value string, usage string, required ...bool) *gflag

func FilePath

func FilePath(name, shortName string, value string, usage string, required ...bool) *gflag

func Float32

func Float32(name, shortName string, value float32, usage string, required ...bool) *gflag

func Float64

func Float64(name, shortName string, value float64, usage string, required ...bool) *gflag

func GenerateCompletions

func GenerateCompletions(ctx Getter, cmd Getter)

func HostPortPair

func HostPortPair(name, shortName string, value string, usage string, required ...bool) *gflag

func IP

func IP(name, shortName string, value net.IP, usage string, required ...bool) *gflag

func Int

func Int(name, shortName string, value int, usage string, required ...bool) *gflag

func Int64

func Int64(name, shortName string, value int64, usage string, required ...bool) *gflag

func IntSlice

func IntSlice(name, shortName string, value []int, usage string, required ...bool) *gflag

func MAC

func MAC(name, shortName string, value net.HardwareAddr, usage string, required ...bool) *gflag

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 Rune

func Rune(name, shortName string, value rune, usage string, required ...bool) *gflag

func String

func String(name, shortName string, value string, usage string, required ...bool) *gflag

func StringSlice

func StringSlice(name, shortName string, value []string, usage string, required ...bool) *gflag

func SubCommand

func SubCommand(name, description string, handler Handler) *subcommand

Create a new subcommand.

func Time

func Time(name, shortName string, value time.Time, usage string, required ...bool) *gflag

func URL

func URL(name, shortName string, value *url.URL, usage string, required ...bool) *gflag

func UUID

func UUID(name, shortName string, value uuid.UUID, usage string, required ...bool) *gflag

Types

type Context

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

Global flag context. Stores global flags and subcommands.

func NewContext

func NewContext() *Context

Create a new flag context.

func (*Context) AddFlag

func (ctx *Context) AddFlag(flag *gflag) *gflag

Add a flag to the context.

func (*Context) AddSubCommand

func (ctx *Context) AddSubCommand(cmd *subcommand) *subcommand

Add a subcommand to the context.

func (*Context) GenerateBashCompletions

func (ctx *Context) GenerateBashCompletions(w io.Writer)

GenerateBashCompletions generates a Bash completion script for goflag.

func (*Context) GenerateZshCompletions

func (ctx *Context) GenerateZshCompletions(w io.Writer)

GenerateZshCompletion generates a Zsh completion script for goflag.

func (*Context) Get

func (ctx *Context) Get(name string) any

func (*Context) GetBool

func (ctx *Context) GetBool(name string) bool

Get the value of a flag as a bool. Panics if the flag is not found or the value is not a bool.

func (*Context) GetDirPath

func (ctx *Context) GetDirPath(name string) string

Get the value of a flag as a string. Panics if the flag is not found or the value is not a string.

func (*Context) GetDuration

func (ctx *Context) GetDuration(name string) time.Duration

Get the value of a flag as a time.Duration. Panics if the flag is not found or the value is not a time.Duration.

func (*Context) GetEmail

func (ctx *Context) GetEmail(name string) string

Get the value of a flag as a string. Panics if the flag is not found or the value is not a string.

func (*Context) GetFilePath

func (ctx *Context) GetFilePath(name string) string

Get the value of a flag as a string. Panics if the flag is not found or the value is not a string.

func (*Context) GetFloat32

func (ctx *Context) GetFloat32(name string) float32

Get the value of a flag as a float32. Panics if the flag is not found or the value is not a float32.

func (*Context) GetFloat64

func (ctx *Context) GetFloat64(name string) float64

Get the value of a flag as a float64. Panics if the flag is not found or the value is not a float64.

func (*Context) GetHostPortPair

func (ctx *Context) GetHostPortPair(name string) string

Get the value of a flag as a string. Panics if the flag is not found or the value is not a string.

func (*Context) GetIP

func (ctx *Context) GetIP(name string) net.IP

Get the value of a flag as a net.IP. Panics if the flag is not found or the value is not a net.IP.

func (*Context) GetInt

func (ctx *Context) GetInt(name string) int

Get the value of a flag as a int. Panics if the flag is not found or the value is not a int.

func (*Context) GetInt64

func (ctx *Context) GetInt64(name string) int64

Get the value of a flag as a int64. Panics if the flag is not found or the value is not a int64.

func (*Context) GetIntSlice

func (ctx *Context) GetIntSlice(name string) []int

Get the value of a flag as a []int. Panics if the flag is not found or the value is not a []int.

func (*Context) GetMAC

func (ctx *Context) GetMAC(name string) net.HardwareAddr

Get the value of a flag as a net.HardwareAddr. Panics if the flag is not found or the value is not a net.HardwareAddr.

func (*Context) GetRune

func (ctx *Context) GetRune(name string) rune

Get the value of a flag as a rune. Panics if the flag is not found or the value is not a rune.

func (*Context) GetString

func (ctx *Context) GetString(name string) string

Get the value of a flag as a string. Panics if the flag is not found or the value is not a string.

func (*Context) GetStringSlice

func (ctx *Context) GetStringSlice(name string) []string

Get the value of a flag as a []string. Panics if the flag is not found or the value is not a []string.

func (*Context) GetTime

func (ctx *Context) GetTime(name string) time.Time

Get the value of a flag as a time.Time. Panics if the flag is not found or the value is not a time.Time.

func (*Context) GetURL

func (ctx *Context) GetURL(name string) *url.URL

Get the value of a flag as a *url.URL. Panics if the flag is not found or the value is not a *url.URL.

func (*Context) GetUUID

func (ctx *Context) GetUUID(name string) uuid.UUID

Get the value of a flag as a uuid.UUID. Panics if the flag is not found or the value is not a uuid.UUID.

func (*Context) Parse

func (ctx *Context) 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 (*Context) PrintUsage

func (ctx *Context) 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

type Getter

type Getter interface {
	Get(name string) any
	GetString(name string) string
	GetInt(name string) int
	GetInt64(name string) int64
	GetFloat32(name string) float32
	GetFloat64(name string) float64
	GetBool(name string) bool
	GetStringSlice(name string) []string
	GetRune(name string) rune
	GetTime(name string) time.Time
	GetDuration(name string) time.Duration
	GetIntSlice(name string) []int
}

type Handler

type Handler func(ctx Getter, cmd Getter)

Subcommand callback handler. Will be invoked by user if it matches the subcommand returned by ctx.Parse.

Directories

Path Synopsis
cmd
genc is a code generator for the gflag package.
genc is a code generator for the gflag package.

Jump to

Keyboard shortcuts

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