flagx

package module
v1.5.4 Latest Latest
Warning

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

Go to latest
Published: Feb 2, 2021 License: MIT Imports: 18 Imported by: 0

README

flagx report card GoDoc

Standard flag package extension with more features, such as struct flag, app framework, etc.

Extension Feature

  • Add const ContinueOnUndefined ErrorHandling: ignore provided but undefined flags
  • Add *FlagSet.StructVars: define flags based on struct tags and bind to fields
    • The list of supported types is consistent with the standard package:
      • string
      • bool
      • int
      • int64
      • uint
      • uint64
      • float64
      • time.Duration
  • Add LookupArgs: lookup the value corresponding to a name directly from arguments
  • Provide application framework
  • Support define non-flag
    • Use ?{index} (such as ?0, ?1, ?2) in struct tag to define non-flag
  • For more features, please open the issue

Test Demo

  • Ignore provided but undefined flags
func TestContinueOnUndefined(t *testing.T) {
	var args = []string{"test", "-x=1", "-y"}
	fs := NewFlagSet(args[0], ContinueOnError)
	fs.String("x", "", "")
	err := fs.Parse(args[1:])
	assert.EqualError(t, err, "flag provided but not defined: -y")
	fs.Usage()

	fs = NewFlagSet(args[0], ContinueOnError|ContinueOnUndefined)
	x := fs.String("x", "", "")
	err = fs.Parse(args[1:])
	assert.NoError(t, err)
	assert.Equal(t, "1", *x)
}
  • Define flags based on struct tags and bind to fields
func ExampleStructVars() {
	os.Args = []string{
		"go test",
		"-test.timeout", "30s",
		"-test.v",
		"-test.count", "1",
		"-test.run", "^(TestStructVars)$",
		"flag_test.go",
	}
	type Args struct {
		Run     string        `flag:"test.run; def=.*; usage=function name pattern"`
		Timeout time.Duration `flag:"test.timeout"`
		V       bool          `flag:"test.v"`
		X       int           `flag:"def=10"`
		Y       string        `flag:"?0"` // the first non-flag
	}
	var args Args
	err := StructVars(&args)
	if err != nil {
		panic(err)
	}
	Parse()
	fmt.Printf("%+v\n", args)
	// Output:
	// {Run:^(TestStructVars)$ Timeout:30s V:true X:10 Y:flag_test.go}
}
  • Lookup the value corresponding to a name directly from arguments
func TestLookupArgs(t *testing.T) {
	var args = []string{"-run", "abc", "-t", "5s", "-Cool", "-N=1", "-x"}

	v, ok := LookupArgs(args, "run")
	assert.True(t, ok)
	assert.Equal(t, "abc", v)

	v, ok = LookupArgs(args, "t")
	assert.True(t, ok)
	assert.Equal(t, "5s", v)

	v, ok = LookupArgs(args, "Cool")
	assert.True(t, ok)
	assert.Equal(t, "", v)

	v, ok = LookupArgs(args, "N")
	assert.True(t, ok)
	assert.Equal(t, "1", v)

	v, ok = LookupArgs(args, "x")
	assert.True(t, ok)
	assert.Equal(t, "", v)

	v, ok = LookupArgs(args, "???")
	assert.False(t, ok)
	assert.Equal(t, "", v)
}
  • Aapplication
package flagx_test

import (
	"context"
	"fmt"
	"testing"
	"time"

	vd "github.com/bytedance/go-tagexpr/v2/validator"
	"github.com/henrylee2cn/flagx"
	"github.com/stretchr/testify/assert"
)

func ExampleApp() {
	app := flagx.NewApp()
	app.SetCmdName("testapp")
	app.SetDescription("this is a app for testing")
	app.SetAuthors([]flagx.Author{{
		Name:  "henrylee2cn",
		Email: "henrylee2cn@gmail.com",
	}})
	app.SetValidator(func(v interface{}) error {
		return vd.Validate(v)
	})
	app.AddFilter(new(Filter1))
	// cmd: testapp a
	app.AddSubaction("a", "subcommand a", new(Action1))
	b := app.AddSubcommand("b", "subcommand b", flagx.FilterFunc(Filter2))
	{
		// cmd: testapp b c
		b.AddSubaction("c", "subcommand c", new(Action2))
		// cmd: testapp b d
		b.AddSubaction("d", "subcommand d", flagx.ActionFunc(Action3))
	}
	app.SetNotFound(func(c *flagx.Context) {
		fmt.Printf("NotFound: cmd=%q, uasge=%s\n", c.CmdPathString(), c.UsageText())
	})

	fmt.Println(app.UsageText())

	// test: testapp
	// not found
	stat := app.Exec(context.TODO(), []string{"-g=flagx", "false"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp a
	stat = app.Exec(context.TODO(), []string{"-g=henry", "true", "a", "-id", "1", "~/m/n"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b c
	// not found
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b", "c", "name=henry"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b d
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b", "d"})
	if !stat.OK() {
		panic(stat)
	}

	// Output:
	// testapp - v0.0.1
	//
	// this is a app for testing
	//
	// USAGE:
	//   -g string
	//     	global param g
	//   ?0 bool
	//     	param view
	//   $testapp a
	//     subcommand a
	//     -id int
	//       	param id
	//     ?0 string
	//       	param path
	//   $testapp b ...
	//     subcommand b
	//   $testapp b c
	//     subcommand c
	//     -name string
	//       	param name
	//   $testapp b d
	//     subcommand d
	//
	// AUTHOR:
	//   henrylee2cn <henrylee2cn@gmail.com>
	//
	// NotFound: cmd="testapp", uasge=-g string
	//   	global param g
	// ?0 bool
	//   	param view
	// $testapp a
	//   subcommand a
	//   -id int
	//     	param id
	//   ?0 string
	//     	param path
	// $testapp b ...
	//   subcommand b
	// $testapp b c
	//   subcommand c
	//   -name string
	//     	param name
	// $testapp b d
	//   subcommand d
	//
	// Filter1 start: args=[-g=henry true a -id 1 ~/m/n], G=henry
	// Action1: args=[-g=henry true a -id 1 ~/m/n], path="testapp a", object=&{ID:1 Path:~/m/n}
	// Filter1 end: args=[-g=henry true a -id 1 ~/m/n]
	// NotFound: cmd="testapp b", uasge=$testapp b ...
	//   subcommand b
	// $testapp b c
	//   subcommand c
	//   -name string
	//     	param name
	// $testapp b d
	//   subcommand d
	//
	// Filter1 start: args=[-g=flagx false b c name=henry], V=false
	// Filter2 start: args=[-g=flagx false b c name=henry], start at=2020-02-13 13:48:15 +0800 CST
	// Action2: args=[-g=flagx false b c name=henry], path="testapp b c", object=&{Name:}
	// Filter2 end: args=[-g=flagx false b c name=henry], cost time=1µs
	// Filter1 end: args=[-g=flagx false b c name=henry]
	// Filter1 start: args=[-g=flagx false b d], V=false
	// Filter2 start: args=[-g=flagx false b d], start at=2020-02-13 13:48:15 +0800 CST
	// Action3: args=[-g=flagx false b d], path="testapp b d"
	// Filter2 end: args=[-g=flagx false b d], cost time=1µs
	// Filter1 end: args=[-g=flagx false b d]
}

type Filter1 struct {
	G string `flag:"g;usage=global param g"`
	V bool   `flag:"?0;usage=param view"`
}

func (f *Filter1) Filter(c *flagx.Context, next flagx.ActionFunc) {
	if f.V {
		fmt.Printf("Filter1 start: args=%+v, G=%s\n", c.Args(), f.G)
	} else {
		fmt.Printf("Filter1 start: args=%+v, V=%v\n", c.Args(), f.V)
	}
	defer fmt.Printf("Filter1 end: args=%+v\n", c.Args())
	next(c)
}

func Filter2(c *flagx.Context, next flagx.ActionFunc) {
	t := time.Unix(1581572895, 0)
	fmt.Printf(
		"Filter2 start: args=%+v, start at=%v\n",
		c.Args(), t,
	)
	defer func() {
		fmt.Printf(
			"Filter2 end: args=%+v, cost time=%v\n",
			c.Args(), time.Unix(1581572895, 1000).Sub(t),
		)
	}()
	next(c)
}

type Action1 struct {
	ID   int    `flag:"id;usage=param id" vd:"@:$!=0; msg:'empty ID'"`
	Path string `flag:"?0;usage=param path"`
}

func (a *Action1) Execute(c *flagx.Context) {
	fmt.Printf("Action1: args=%+v, path=%q, object=%+v\n", c.Args(), c.CmdPathString(), a)
}

type Action2 struct {
	Name string `flag:"name;usage=param name"`
}

func (a *Action2) Execute(c *flagx.Context) {
	fmt.Printf("Action2: args=%+v, path=%q, object=%+v\n", c.Args(), c.CmdPathString(), a)
}

func Action3(c *flagx.Context) {
	fmt.Printf("Action3: args=%+v, path=%q\n", c.Args(), c.CmdPathString())
}

Documentation

Index

Examples

Constants

View Source
const (
	StatusBadArgs        int32 = 1
	StatusNotFound       int32 = 2
	StatusParseFailed    int32 = 3
	StatusValidateFailed int32 = 4
	StatusMismatchScope  int32 = 5
)

Status code

Variables

View Source
var (
	// NewStatus creates a message status with code, msg and cause.
	// NOTE:
	//  code=0 means no error
	// TYPE:
	//  func NewStatus(code int32, msg string, cause interface{}) *Status
	NewStatus = status.New

	// NewStatusWithStack creates a message status with code, msg and cause and stack.
	// NOTE:
	//  code=0 means no error
	// TYPE:
	//  func NewStatusWithStack(code int32, msg string, cause interface{}) *Status
	NewStatusWithStack = status.NewWithStack

	// NewStatusFromQuery parses the query bytes to a status object.
	// TYPE:
	//  func NewStatusFromQuery(b []byte, tagStack bool) *Status
	NewStatusFromQuery = status.FromQuery
	// CheckStatus if err!=nil, create a status with stack, and panic.
	// NOTE:
	//  If err!=nil and msg=="", error text is set to msg
	// TYPE:
	//  func Check(err error, code int32, msg string, whenError ...func())
	CheckStatus = status.Check
	// ThrowStatus creates a status with stack, and panic.
	// TYPE:
	//  func Throw(code int32, msg string, cause interface{})
	ThrowStatus = status.Throw
	// CatchStatus recovers the panic and returns status.
	// NOTE:
	//  Set `realStat` to true if a `Status` type is recovered
	// Example:
	//  var stat *Status
	//  defer CatchStatus(&stat)
	// TYPE:
	//  func CatchStatus(statPtr **Status, realStat ...*bool)
	CatchStatus = status.CatchWithStack
)

CommandLine is the default set of command-line flags, parsed from os.Args. The top-level functions such as BoolVar, Arg, and so on are wrappers for the methods of CommandLine.

Functions

func Arg added in v1.1.0

func Arg(i int) string

Arg returns the i'th command-line argument. Arg(0) is the first remaining argument after flags have been processed. Arg returns an empty string if the requested element does not exist.

func Args added in v1.1.0

func Args() []string

Args returns the non-flag command-line arguments.

func Bool added in v1.1.0

func Bool(name string, value bool, usage string) *bool

Bool defines a bool flag with specified name, default value, and usage string. The return value is the address of a bool variable that stores the value of the flag.

func BoolVar added in v1.1.0

func BoolVar(p *bool, name string, value bool, usage string)

BoolVar defines a bool flag with specified name, default value, and usage string. The argument p points to a bool variable in which to store the value of the flag.

func Duration added in v1.1.0

func Duration(name string, value time.Duration, usage string) *time.Duration

Duration defines a time.Duration flag with specified name, default value, and usage string. The return value is the address of a time.Duration variable that stores the value of the flag. The flag accepts a value acceptable to time.ParseDuration.

func DurationVar added in v1.1.0

func DurationVar(p *time.Duration, name string, value time.Duration, usage string)

DurationVar defines a time.Duration flag with specified name, default value, and usage string. The argument p points to a time.Duration variable in which to store the value of the flag. The flag accepts a value acceptable to time.ParseDuration.

func Float64 added in v1.1.0

func Float64(name string, value float64, usage string) *float64

Float64 defines a float64 flag with specified name, default value, and usage string. The return value is the address of a float64 variable that stores the value of the flag.

func Float64Var added in v1.1.0

func Float64Var(p *float64, name string, value float64, usage string)

Float64Var defines a float64 flag with specified name, default value, and usage string. The argument p points to a float64 variable in which to store the value of the flag.

func Int added in v1.1.0

func Int(name string, value int, usage string) *int

Int defines an int flag with specified name, default value, and usage string. The return value is the address of an int variable that stores the value of the flag.

func Int64 added in v1.1.0

func Int64(name string, value int64, usage string) *int64

Int64 defines an int64 flag with specified name, default value, and usage string. The return value is the address of an int64 variable that stores the value of the flag.

func Int64Var added in v1.1.0

func Int64Var(p *int64, name string, value int64, usage string)

Int64Var defines an int64 flag with specified name, default value, and usage string. The argument p points to an int64 variable in which to store the value of the flag.

func IntVar added in v1.1.0

func IntVar(p *int, name string, value int, usage string)

IntVar defines an int flag with specified name, default value, and usage string. The argument p points to an int variable in which to store the value of the flag.

func IsNonFlag added in v1.4.3

func IsNonFlag(f *Flag) bool

IsNonFlag determines if it is non-flag.

func LookupArgs added in v1.1.2

func LookupArgs(arguments []string, name string) (value string, found bool)

LookupArgs lookups the value corresponding to the name directly from the arguments.

func NArg added in v1.1.0

func NArg() int

NArg is the number of arguments remaining after flags have been processed.

func NFlag added in v1.1.0

func NFlag() int

NFlag returns the number of command-line flags that have been set.

func NFormalNonFlag added in v1.4.0

func NFormalNonFlag() int

NFormalNonFlag returns the number of non-flag required in the definition.

func NextArgs added in v1.4.0

func NextArgs() []string

NextArgs returns arguments of the next subcommand.

func NonBool added in v1.4.0

func NonBool(index int, value bool, usage string) *bool

NonBool defines a bool non-flag with specified index, default value, and usage string. The return value is the address of a bool variable that stores the value of the non-flag.

func NonBoolVar added in v1.4.0

func NonBoolVar(p *bool, index int, value bool, usage string)

NonBoolVar defines a bool non-flag with specified index, default value, and usage string. The argument p points to a bool variable in which to store the value of the non-flag.

func NonDuration added in v1.4.0

func NonDuration(index int, value time.Duration, usage string) *time.Duration

NonDuration defines a time.Duration non with specified index, default value, and usage string. The return value is the address of a time.Duration variable that stores the value of the non-flag. The non-flag accepts a value acceptable to time.ParseDuration.

func NonDurationVar added in v1.4.0

func NonDurationVar(p *time.Duration, index int, value time.Duration, usage string)

NonDurationVar defines a time.Duration non-flag with specified index, default value, and usage string. The argument p points to a time.Duration variable in which to store the value of the non-flag. The non-flag accepts a value acceptable to time.ParseDuration.

func NonFlagIndex added in v1.4.3

func NonFlagIndex(nonFlag *Flag) (int, bool)

NonFlagIndex gets the non-flag index from name.

func NonFloat64 added in v1.4.0

func NonFloat64(index int, value float64, usage string) *float64

NonFloat64 defines a float64 non-flag with specified index, default value, and usage string. The return value is the address of a float64 variable that stores the value of the non-flag.

func NonFloat64Var added in v1.4.0

func NonFloat64Var(p *float64, index int, value float64, usage string)

NonFloat64Var defines a float64 non-flag with specified index, default value, and usage string. The argument p points to a float64 variable in which to store the value of the non-flag.

func NonInt added in v1.4.0

func NonInt(index int, value int, usage string) *int

NonInt defines an int non-flag with specified index, default value, and usage string. The return value is the address of an int variable that stores the value of the non-flag.

func NonInt64 added in v1.4.0

func NonInt64(index int, value int64, usage string) *int64

NonInt64 defines an int64 non-flag with specified index, default value, and usage string. The return value is the address of an int64 variable that stores the value of the non-flag.

func NonInt64Var added in v1.4.0

func NonInt64Var(p *int64, index int, value int64, usage string)

NonInt64Var defines an int64 non-flag with specified index, default value, and usage string. The argument p points to an int64 variable in which to store the value of the non-flag.

func NonIntVar added in v1.4.0

func NonIntVar(p *int, index int, value int, usage string)

NonIntVar defines an int non-flag with specified index, default value, and usage string. The argument p points to an int variable in which to store the value of the non-flag.

func NonString added in v1.4.0

func NonString(index int, value string, usage string) *string

NonString defines a string non-flag with specified index, default value, and usage string. The return value is the address of a string variable that stores the value of the non-flag.

func NonStringVar added in v1.4.0

func NonStringVar(p *string, index int, value string, usage string)

NonStringVar defines a string non-flag with specified index, default value, and usage string. The argument p points to a string variable in which to store the value of the non-flag.

func NonUint added in v1.4.0

func NonUint(index int, value uint, usage string) *uint

NonUint defines a uint non-flag with specified index, default value, and usage string. The return value is the address of a uint variable that stores the value of the non-flag.

func NonUint64 added in v1.4.0

func NonUint64(index int, value uint64, usage string) *uint64

NonUint64 defines a uint64 non-flag with specified index, default value, and usage string. The return value is the address of a uint64 variable that stores the value of the non-flag.

func NonUint64Var added in v1.4.0

func NonUint64Var(p *uint64, index int, value uint64, usage string)

NonUint64Var defines a uint64 non-flag with specified index, default value, and usage string. The argument p points to a uint64 variable in which to store the value of the non-flag.

func NonUintVar added in v1.4.0

func NonUintVar(p *uint, index int, value uint, usage string)

NonUintVar defines a uint non-flag with specified index, default value, and usage string. The argument p points to a uint variable in which to store the value of the non-flag.

func NonVar added in v1.4.0

func NonVar(value Value, index int, usage string)

NonVar defines a non-flag with the specified index and usage string.

func NonVisit added in v1.4.0

func NonVisit(fn func(*Flag))

NonVisit visits the command-line non-flags in lexicographical order, calling fn for each. It visits only those non-flags that have been set.

func NonVisitAll added in v1.4.0

func NonVisitAll(fn func(*Flag))

NonVisitAll visits the command-line non-flags in lexicographical order, calling fn for each. It visits all non-flags, even those not set.

func Parse added in v1.1.0

func Parse()

Parse parses the command-line flags from os.Args[1:]. Must be called after all flags are defined and before flags are accessed by the program.

func Parsed added in v1.1.0

func Parsed() bool

Parsed reports whether the command-line flags have been parsed.

func PrintDefaults added in v1.1.0

func PrintDefaults()

PrintDefaults prints, to standard error unless configured otherwise, a usage message showing the default settings of all defined command-line flags. For an integer valued flag x, the default output has the form

-x int
	usage-message-for-x (default 7)

The usage message will appear on a separate line for anything but a bool flag with a one-byte name. For bool flags, the type is omitted and if the flag name is one byte the usage message appears on the same line. The parenthetical default is omitted if the default is the zero value for the type. The listed type, here int, can be changed by placing a back-quoted name in the flag's usage string; the first such item in the message is taken to be a parameter name to show in the message and the back quotes are stripped from the message when displayed. For instance, given

flag.String("I", "", "search `directory` for include files")

the output will be

-I directory
	search directory for include files.

To change the destination for flag messages, call CommandLine.SetOutput.

func Range added in v1.4.0

func Range(fn func(*Flag))

Range visits the command-line flags and non-flags in lexicographical order, calling fn for each. It visits only those flags and non-flags that have been set.

func RangeAll added in v1.4.0

func RangeAll(fn func(*Flag))

RangeAll visits the command-line flags and non-flags in lexicographical order, calling fn for each. It visits all flags and non-flags, even those not set.

func Set added in v1.1.0

func Set(name, value string) error

Set sets the value of the named command-line flag.

func SplitArgs added in v1.3.2

func SplitArgs(arguments []string) (string, []string)

SplitArgs returns the command name and options.

func String added in v1.1.0

func String(name string, value string, usage string) *string

String defines a string flag with specified name, default value, and usage string. The return value is the address of a string variable that stores the value of the flag.

func StringVar added in v1.1.0

func StringVar(p *string, name string, value string, usage string)

StringVar defines a string flag with specified name, default value, and usage string. The argument p points to a string variable in which to store the value of the flag.

func StructVars added in v1.1.0

func StructVars(p interface{}) error

StructVars defines flags based on struct tags and binds to fields. NOTE:

Not support nested fields
Example
os.Args = []string{
	"go test",
	"-test.timeout", "30s",
	"-test.v",
	"-test.count", "1",
	"-test.run", "^(TestStructVars)$",
	"flag_test.go",
}
type Args struct {
	Run     string        `flag:"test.run; def=.*; usage=function name pattern"`
	Timeout time.Duration `flag:"test.timeout"`
	V       bool          `flag:"test.v"`
	X       int           `flag:"def=10"`
	Y       string        `flag:"?0"` // the first non-flag
}
var args Args
err := StructVars(&args)
if err != nil {
	panic(err)
}
Parse()
fmt.Printf("%+v\n", args)
Output:

{Run:^(TestStructVars)$ Timeout:30s V:true X:10 Y:flag_test.go}

func Uint added in v1.1.0

func Uint(name string, value uint, usage string) *uint

Uint defines a uint flag with specified name, default value, and usage string. The return value is the address of a uint variable that stores the value of the flag.

func Uint64 added in v1.1.0

func Uint64(name string, value uint64, usage string) *uint64

Uint64 defines a uint64 flag with specified name, default value, and usage string. The return value is the address of a uint64 variable that stores the value of the flag.

func Uint64Var added in v1.1.0

func Uint64Var(p *uint64, name string, value uint64, usage string)

Uint64Var defines a uint64 flag with specified name, default value, and usage string. The argument p points to a uint64 variable in which to store the value of the flag.

func UintVar added in v1.1.0

func UintVar(p *uint, name string, value uint, usage string)

UintVar defines a uint flag with specified name, default value, and usage string. The argument p points to a uint variable in which to store the value of the flag.

func UnquoteUsage added in v1.1.0

func UnquoteUsage(f *Flag) (name string, usage string)

UnquoteUsage extracts a back-quoted name from the usage string for a flag and returns it and the un-quoted usage. Given "a `name` to show" it returns ("name", "a name to show"). If there are no back quotes, the name is an educated guess of the type of the flag's value, or the empty string if the flag is boolean.

func Usage added in v1.1.2

func Usage()

Usage prints the default usage message.

func Var added in v1.1.0

func Var(value Value, name string, usage string)

Var defines a flag with the specified name and usage string. The type and value of the flag are represented by the first argument, of type Value, which typically holds a user-defined implementation of Value. For instance, the caller could create a flag that turns a comma-separated string into a slice of strings by giving the slice the methods of Value; in particular, Set would decompose the comma-separated string into the slice.

func Visit added in v1.1.0

func Visit(fn func(*Flag))

Visit visits the command-line flags in lexicographical order, calling fn for each. It visits only those flags that have been set.

func VisitAll added in v1.1.0

func VisitAll(fn func(*Flag))

VisitAll visits the command-line flags in lexicographical order, calling fn for each. It visits all flags, even those not set.

Types

type Action added in v1.2.0

type Action interface {
	// Execute executes action.
	// NOTE:
	//  If need to return an error, use *Context.ThrowStatus or *Context.CheckStatus
	Execute(*Context)
}

Action action of action

type ActionCopier added in v1.4.0

type ActionCopier interface {
	DeepCopy() Action
}

ActionCopier an interface that can create its own copy

type ActionFunc added in v1.4.0

type ActionFunc func(*Context)

ActionFunc action function NOTE:

If need to return an error, use *Context.ThrowStatus or *Context.CheckStatus

func (ActionFunc) Execute added in v1.5.0

func (fn ActionFunc) Execute(c *Context)

Execute implements Action interface.

type App added in v1.2.0

type App struct {
	*Command
	// contains filtered or unexported fields
}

App is a application structure. It is recommended that an app be created with the flagx.NewApp() function

Example
package main

import (
	"context"
	"fmt"
	"time"

	vd "github.com/bytedance/go-tagexpr/v2/validator"
	"github.com/henrylee2cn/flagx"
)

func main() {
	app := flagx.NewApp()
	app.SetCmdName("testapp")
	app.SetDescription("this is a app for testing")
	app.SetAuthors([]flagx.Author{{
		Name:  "henrylee2cn",
		Email: "henrylee2cn@gmail.com",
	}})
	app.SetValidator(func(v interface{}) error {
		return vd.Validate(v)
	})
	app.AddFilter(new(Filter1))
	// cmd: testapp a
	app.AddSubaction("a", "subcommand a", new(Action1))
	b := app.AddSubcommand("b", "subcommand b", flagx.FilterFunc(Filter2))
	{
		// cmd: testapp b c
		b.AddSubaction("c", "subcommand c", new(Action2))
		// cmd: testapp b d
		b.AddSubaction("d", "subcommand d", flagx.ActionFunc(Action3))
	}
	app.SetNotFound(func(c *flagx.Context) {
		fmt.Printf("NotFound: cmd=%q, uasge=%s\n", c.CmdPathString(), c.UsageText())
	})

	fmt.Println(app.UsageText())

	// test: testapp
	// not found
	stat := app.Exec(context.TODO(), []string{"-g=flagx", "false"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp a
	stat = app.Exec(context.TODO(), []string{"-g=henry", "true", "a", "-id", "1", "~/m/n"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b c
	// not found
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b", "c", "name=henry"})
	if !stat.OK() {
		panic(stat)
	}

	// test: testapp b d
	stat = app.Exec(context.TODO(), []string{"-g=flagx", "false", "b", "d"})
	if !stat.OK() {
		panic(stat)
	}

}

type Filter1 struct {
	G string `flag:"g;usage=global param g"`
	V bool   `flag:"?0;usage=param view"`
}

func (f *Filter1) Filter(c *flagx.Context, next flagx.ActionFunc) {
	if f.V {
		fmt.Printf("Filter1 start: args=%+v, G=%s\n", c.Args(), f.G)
	} else {
		fmt.Printf("Filter1 start: args=%+v, V=%v\n", c.Args(), f.V)
	}
	defer fmt.Printf("Filter1 end: args=%+v\n", c.Args())
	next(c)
}

func Filter2(c *flagx.Context, next flagx.ActionFunc) {
	t := time.Unix(1581572895, 0)
	fmt.Printf(
		"Filter2 start: args=%+v, start at=%v\n",
		c.Args(), t,
	)
	defer func() {
		fmt.Printf(
			"Filter2 end: args=%+v, cost time=%v\n",
			c.Args(), time.Unix(1581572895, 1000).Sub(t),
		)
	}()
	next(c)
}

type Action1 struct {
	ID   int    `flag:"id;usage=param id" vd:"@:$!=0; msg:'empty ID'"`
	Path string `flag:"?0;usage=param path"`
}

func (a *Action1) Execute(c *flagx.Context) {
	fmt.Printf("Action1: args=%+v, path=%q, object=%+v\n", c.Args(), c.CmdPathString(), a)
}

type Action2 struct {
	Name string `flag:"name;usage=param name"`
}

func (a *Action2) Execute(c *flagx.Context) {
	fmt.Printf("Action2: args=%+v, path=%q, object=%+v\n", c.Args(), c.CmdPathString(), a)
}

func Action3(c *flagx.Context) {
	fmt.Printf("Action3: args=%+v, path=%q\n", c.Args(), c.CmdPathString())
}
Output:

testapp - v0.0.1

this is a app for testing

USAGE:
  -g string
    	global param g
  ?0 bool
    	param view
  $testapp a
    subcommand a
    -id int
      	param id
    ?0 string
      	param path
  $testapp b ...
    subcommand b
  $testapp b c
    subcommand c
    -name string
      	param name
  $testapp b d
    subcommand d

AUTHOR:
  henrylee2cn <henrylee2cn@gmail.com>

NotFound: cmd="testapp", uasge=-g string
  	global param g
?0 bool
  	param view
$testapp a
  subcommand a
  -id int
    	param id
  ?0 string
    	param path
$testapp b ...
  subcommand b
$testapp b c
  subcommand c
  -name string
    	param name
$testapp b d
  subcommand d

Filter1 start: args=[-g=henry true a -id 1 ~/m/n], G=henry
Action1: args=[-g=henry true a -id 1 ~/m/n], path="testapp a", object=&{ID:1 Path:~/m/n}
Filter1 end: args=[-g=henry true a -id 1 ~/m/n]
NotFound: cmd="testapp b", uasge=$testapp b ...
  subcommand b
$testapp b c
  subcommand c
  -name string
    	param name
$testapp b d
  subcommand d

Filter1 start: args=[-g=flagx false b c name=henry], V=false
Filter2 start: args=[-g=flagx false b c name=henry], start at=2020-02-13 13:48:15 +0800 CST
Action2: args=[-g=flagx false b c name=henry], path="testapp b c", object=&{Name:}
Filter2 end: args=[-g=flagx false b c name=henry], cost time=1µs
Filter1 end: args=[-g=flagx false b c name=henry]
Filter1 start: args=[-g=flagx false b d], V=false
Filter2 start: args=[-g=flagx false b d], start at=2020-02-13 13:48:15 +0800 CST
Action3: args=[-g=flagx false b d], path="testapp b d"
Filter2 end: args=[-g=flagx false b d], cost time=1µs
Filter1 end: args=[-g=flagx false b d]

func NewApp added in v1.2.0

func NewApp() *App

NewApp creates a new application.

func (*App) Authors added in v1.2.0

func (a *App) Authors() []Author

Authors returns the list of all authors who contributed.

func (*App) CmdName added in v1.2.0

func (a *App) CmdName() string

CmdName returns the command name of the application. Defaults to filepath.Base(os.Args[0])

func (*App) Compiled added in v1.2.0

func (a *App) Compiled() time.Time

Compiled returns the compilation date.

func (*App) Copyright added in v1.2.0

func (a *App) Copyright() string

Copyright returns the copyright of the binary if any.

func (*App) Description added in v1.2.0

func (a *App) Description() string

Description returns description the of the application.

func (*App) Name added in v1.2.0

func (a *App) Name() string

Name returns the name(title) of the application. Defaults to *App.CmdName()

func (*App) SetAuthors added in v1.2.0

func (a *App) SetAuthors(authors []Author)

SetAuthors sets the list of all authors who contributed.

func (*App) SetCmdName added in v1.2.0

func (a *App) SetCmdName(cmdName string)

SetCmdName sets the command name of the application. NOTE:

remove '-' prefix automatically

func (*App) SetCompiled added in v1.2.0

func (a *App) SetCompiled(date time.Time)

SetCompiled sets the compilation date.

func (*App) SetCopyright added in v1.2.0

func (a *App) SetCopyright(copyright string)

SetCopyright sets copyright of the binary if any.

func (*App) SetDescription added in v1.2.0

func (a *App) SetDescription(description string)

SetDescription sets description the of the application.

func (*App) SetName added in v1.2.0

func (a *App) SetName(appName string)

SetName sets the name(title) of the application.

func (*App) SetNotFound added in v1.2.0

func (a *App) SetNotFound(fn ActionFunc)

SetNotFound sets the action when the correct command cannot be found.

func (*App) SetScopeMatcher added in v1.4.4

func (a *App) SetScopeMatcher(fn func(cmdScope, execScope Scope) error)

SetScopeMatcher sets the scope matching function.

func (*App) SetUsageTemplate added in v1.3.0

func (a *App) SetUsageTemplate(tmpl *template.Template)

SetUsageTemplate sets usage template.

func (*App) SetValidator added in v1.4.0

func (a *App) SetValidator(fn ValidateFunc)

SetValidator sets parameter validator for struct action and struct filter.

func (*App) SetVersion added in v1.2.0

func (a *App) SetVersion(version string)

SetVersion sets the version of the application.

func (*App) UsageText added in v1.2.0

func (a *App) UsageText(execScope ...Scope) string

UsageText returns the usage text by by the executor scope. NOTE:

if @scopes is empty, all command usage are returned.

func (*App) Version added in v1.2.0

func (a *App) Version() string

Version returns the version of the application.

type Author added in v1.2.0

type Author struct {
	Name  string // The Authors name
	Email string // The Authors email
}

Author represents someone who has contributed to a cli project.

func (Author) String added in v1.2.0

func (a Author) String() string

String makes Author comply to the Stringer interface, to allow an easy print in the templating process

type Command added in v1.4.0

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

Command a command object

func (*Command) AddFilter added in v1.4.0

func (c *Command) AddFilter(filters ...Filter)

AddFilter adds the filter action. NOTE:

if filter is a struct, it can implement the copier interface;
panic when something goes wrong

func (*Command) AddSubaction added in v1.4.0

func (c *Command) AddSubaction(cmdName, description string, action Action, scope ...Scope)

AddSubaction adds a subcommand and its action. NOTE:

panic when something goes wrong

func (*Command) AddSubcommand added in v1.4.0

func (c *Command) AddSubcommand(cmdName, description string, filters ...Filter) *Command

AddSubcommand adds a subcommand. NOTE:

panic when something goes wrong

func (*Command) CmdName added in v1.4.0

func (c *Command) CmdName() string

CmdName returns the command name of the command.

func (*Command) Exec added in v1.4.1

func (c *Command) Exec(ctx context.Context, arguments []string, execScope ...Scope) (stat *Status)

Exec executes the command. NOTE:

@arguments does not contain the command name;
the default value of @scope is 0.

func (*Command) FindActionCommands added in v1.4.4

func (c *Command) FindActionCommands(execScope ...Scope) []*Command

FindActionCommands finds list of action commands by the executor scope. NOTE:

if @scopes is empty, all action commands are returned.

func (*Command) Flags added in v1.4.4

func (c *Command) Flags() map[string]*Flag

Flags returns the formal flags.

func (*Command) GetMeta added in v1.4.4

func (c *Command) GetMeta(key interface{}) interface{}

GetMeta gets the command meta.

func (*Command) LookupSubcommand added in v1.4.1

func (c *Command) LookupSubcommand(pathCmdNames ...string) *Command

LookupSubcommand lookups subcommand by path names. NOTE:

returns nil if it does not exist.

func (*Command) Parent added in v1.4.1

func (c *Command) Parent() *Command

Parent returns the parent command. NOTE:

returns nil if it does not exist.

func (*Command) ParentVisible added in v1.4.2

func (c *Command) ParentVisible() bool

ParentVisible returns the visibility in parent command usage.

func (*Command) Path added in v1.4.1

func (c *Command) Path() (p []string)

Path returns the command path slice.

func (*Command) PathString added in v1.4.1

func (c *Command) PathString() string

PathString returns the command path string.

func (*Command) Root added in v1.4.1

func (c *Command) Root() *Command

Root returns the root command. NOTE:

returns nil if it does not exist.

func (*Command) SetAction added in v1.4.0

func (c *Command) SetAction(action Action, scope ...Scope)

SetAction sets the action of the command. NOTE:

if action is a struct, it can implement the copier interface;
panic when something goes wrong.

func (*Command) SetMeta added in v1.4.4

func (c *Command) SetMeta(key interface{}, val interface{})

SetMeta sets the command meta.

func (*Command) SetParentVisible added in v1.4.1

func (c *Command) SetParentVisible(visible bool)

SetParentVisible sets the visibility in parent command usage.

func (*Command) Subcommands added in v1.4.1

func (c *Command) Subcommands() []*Command

Subcommands returns the subcommands.

func (*Command) UsageText added in v1.4.0

func (c *Command) UsageText(execScope ...Scope) string

UsageText returns the usage text by by the executor scope. NOTE:

if @scopes is empty, all command usage are returned.

type Context added in v1.2.0

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

Context context of an action execution

func (*Context) Args added in v1.2.0

func (c *Context) Args() []string

Args returns the command arguments.

func (*Context) CheckStatus added in v1.3.0

func (c *Context) CheckStatus(err error, code int32, msg string, whenError ...func())

CheckStatus if err!=nil, create a status with stack, and panic. NOTE:

If err!=nil and msg=="", error text is set to msg

func (*Context) CmdPath added in v1.4.0

func (c *Context) CmdPath() []string

CmdPath returns the command path slice.

func (*Context) CmdPathString added in v1.4.0

func (c *Context) CmdPathString() string

CmdPathString returns the command path string.

func (*Context) CmdScope added in v1.4.4

func (c *Context) CmdScope() Scope

CmdScope returns the command scope.

func (*Context) ExecScope added in v1.4.4

func (c *Context) ExecScope() Scope

ExecScope returns the executor scope.

func (*Context) GetCmdMeta added in v1.4.4

func (c *Context) GetCmdMeta(key interface{}) interface{}

GetCmdMeta gets the command meta.

func (*Context) ThrowStatus added in v1.3.0

func (c *Context) ThrowStatus(code int32, msg string, cause ...interface{})

ThrowStatus creates a status with stack, and panic.

func (*Context) UsageText added in v1.4.1

func (c *Context) UsageText() string

UsageText returns the command usage.

type ErrorHandling

type ErrorHandling = flag.ErrorHandling

ErrorHandling defines how FlagSet.Parse behaves if the parse fails.

const (
	ContinueOnError     ErrorHandling = flag.ContinueOnError // Return a descriptive error.
	ExitOnError         ErrorHandling = flag.ExitOnError     // Call os.Exit(2).
	PanicOnError        ErrorHandling = flag.PanicOnError    // Call panic with a descriptive error.
	ContinueOnUndefined ErrorHandling = 1 << 30              // Ignore provided but undefined flags
)

These constants cause FlagSet.Parse to behave as described if the parse fails.

type Filter added in v1.4.0

type Filter interface {
	Filter(c *Context, next ActionFunc)
}

Filter global options of app NOTE:

If need to return an error, use *Context.ThrowStatus or *Context.CheckStatus

type FilterCopier added in v1.4.0

type FilterCopier interface {
	DeepCopy() Filter
}

FilterCopier an interface that can create its own copy

type FilterFunc added in v1.4.0

type FilterFunc func(c *Context, next ActionFunc)

FilterFunc filter function NOTE:

If need to return an error, use *Context.ThrowStatus or *Context.CheckStatus

func (FilterFunc) Filter added in v1.4.0

func (fn FilterFunc) Filter(c *Context, next ActionFunc)

Filter implements Filter interface.

type Flag

type Flag = flag.Flag

A Flag represents the state of a flag.

func Lookup added in v1.1.2

func Lookup(name string) *Flag

Lookup returns the Flag structure of the named command-line flag, returning nil if none exists.

type FlagSet

type FlagSet struct {
	*flag.FlagSet
	// contains filtered or unexported fields
}

A FlagSet represents a set of defined flags. The zero value of a FlagSet has no name and has ContinueOnError error handling.

func NewFlagSet

func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet

NewFlagSet returns a new, empty flag set with the specified name and error handling property. If the name is not empty, it will be printed in the default usage message and in error messages.

func (*FlagSet) ErrorHandling added in v1.1.3

func (f *FlagSet) ErrorHandling() ErrorHandling

ErrorHandling returns the error handling behavior of the flag set.

func (*FlagSet) Init added in v1.1.0

func (f *FlagSet) Init(name string, errorHandling ErrorHandling)

Init sets the name and error handling property for a flag set. By default, the zero FlagSet uses an empty name and the ContinueOnError error handling policy.

func (*FlagSet) Lookup added in v1.4.0

func (f *FlagSet) Lookup(name string) *Flag

Lookup returns the Flag structure of the named flag, returning nil if none exists.

func (*FlagSet) NFormalNonFlag added in v1.4.0

func (f *FlagSet) NFormalNonFlag() int

NFormalNonFlag returns the number of non-flag required in the definition.

func (*FlagSet) NextArgs added in v1.4.0

func (f *FlagSet) NextArgs() []string

NextArgs returns arguments of the next subcommand.

func (*FlagSet) NonBool added in v1.4.0

func (f *FlagSet) NonBool(index int, value bool, usage string) *bool

NonBool defines a bool non-flag with specified index, default value, and usage string. The return value is the address of a bool variable that stores the value of the non-flag.

func (*FlagSet) NonBoolVar added in v1.4.0

func (f *FlagSet) NonBoolVar(p *bool, index int, value bool, usage string)

NonBoolVar defines a bool non-flag with specified index, default value, and usage string. The argument p points to a bool variable in which to store the value of the non-flag.

func (*FlagSet) NonDuration added in v1.4.0

func (f *FlagSet) NonDuration(index int, value time.Duration, usage string) *time.Duration

NonDuration defines a time.Duration non-flag with specified index, default value, and usage string. The return value is the address of a time.Duration variable that stores the value of the non-flag. The non-flag accepts a value acceptable to time.ParseDuration.

func (*FlagSet) NonDurationVar added in v1.4.0

func (f *FlagSet) NonDurationVar(p *time.Duration, index int, value time.Duration, usage string)

NonDurationVar defines a time.Duration non-flag with specified index, default value, and usage string. The argument p points to a time.Duration variable in which to store the value of the non-flag. The non-flag accepts a value acceptable to time.ParseDuration.

func (*FlagSet) NonFloat64 added in v1.4.0

func (f *FlagSet) NonFloat64(index int, value float64, usage string) *float64

NonFloat64 defines a float64 non-flag with specified index, default value, and usage string. The return value is the address of a float64 variable that stores the value of the non-flag.

func (*FlagSet) NonFloat64Var added in v1.4.0

func (f *FlagSet) NonFloat64Var(p *float64, index int, value float64, usage string)

NonFloat64Var defines a float64 non-flag with specified index, default value, and usage string. The argument p points to a float64 variable in which to store the value of the non-flag.

func (*FlagSet) NonInt added in v1.4.0

func (f *FlagSet) NonInt(index int, value int, usage string) *int

NonInt defines an int non-flag with specified index, default value, and usage string. The return value is the address of an int variable that stores the value of the non-flag.

func (*FlagSet) NonInt64 added in v1.4.0

func (f *FlagSet) NonInt64(index int, value int64, usage string) *int64

NonInt64 defines an int64 non-flag with specified index, default value, and usage string. The return value is the address of an int64 variable that stores the value of the non-flag.

func (*FlagSet) NonInt64Var added in v1.4.0

func (f *FlagSet) NonInt64Var(p *int64, index int, value int64, usage string)

NonInt64Var defines an int64 non-flag with specified index, default value, and usage string. The argument p points to an int64 variable in which to store the value of the non-flag.

func (*FlagSet) NonIntVar added in v1.4.0

func (f *FlagSet) NonIntVar(p *int, index int, value int, usage string)

NonIntVar defines an int non-flag with specified index, default value, and usage string. The argument p points to an int variable in which to store the value of the non-flag.

func (*FlagSet) NonString added in v1.4.0

func (f *FlagSet) NonString(index int, value string, usage string) *string

NonString defines a string non-flag with specified index, default value, and usage string. The return value is the address of a string variable that stores the value of the non-flag.

func (*FlagSet) NonStringVar added in v1.4.0

func (f *FlagSet) NonStringVar(p *string, index int, value string, usage string)

NonStringVar defines a string non-flag with specified index, default value, and usage string. The argument p points to a string variable in which to store the value of the non-flag.

func (*FlagSet) NonUint added in v1.4.0

func (f *FlagSet) NonUint(index int, value uint, usage string) *uint

NonUint defines a uint non-flag with specified index, default value, and usage string. The return value is the address of a uint variable that stores the value of the non-flag.

func (*FlagSet) NonUint64 added in v1.4.0

func (f *FlagSet) NonUint64(index int, value uint64, usage string) *uint64

NonUint64 defines a uint64 non-flag with specified index, default value, and usage string. The return value is the address of a uint64 variable that stores the value of the non-flag.

func (*FlagSet) NonUint64Var added in v1.4.0

func (f *FlagSet) NonUint64Var(p *uint64, index int, value uint64, usage string)

NonUint64Var defines a uint64 non-flag with specified index, default value, and usage string. The argument p points to a uint64 variable in which to store the value of the non-flag.

func (*FlagSet) NonUintVar added in v1.4.0

func (f *FlagSet) NonUintVar(p *uint, index int, value uint, usage string)

NonUintVar defines a uint non-flag with specified index, default value, and usage string. The argument p points to a uint variable in which to store the value of the non-flag.

func (*FlagSet) NonVar added in v1.4.0

func (f *FlagSet) NonVar(value Value, index int, usage string)

NonVar defines a non-flag with the specified index and usage string.

func (*FlagSet) NonVisit added in v1.4.0

func (f *FlagSet) NonVisit(fn func(*Flag))

NonVisit visits the non-flags in lexicographical order, calling fn for each. It visits only those non-flags that have been set.

func (*FlagSet) NonVisitAll added in v1.4.0

func (f *FlagSet) NonVisitAll(fn func(*Flag))

NonVisitAll visits the non-flags in lexicographical order, calling fn for each. It visits all flags, even those not set.

func (*FlagSet) Parse

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

Parse parses flag definitions from the argument list, which should not include the command name. Must be called after all flags in the FlagSet are defined and before flags are accessed by the program. The return value will be ErrHelp if -help or -h were set but not defined.

func (*FlagSet) PrintDefaults added in v1.1.1

func (f *FlagSet) PrintDefaults()

PrintDefaults prints, to standard error unless configured otherwise, the default values of all defined command-line flags in the set. See the documentation for the global function PrintDefaults for more information.

func (*FlagSet) Range added in v1.4.0

func (f *FlagSet) Range(fn func(*Flag))

Range visits the flags and non-flags in lexicographical order, calling fn for each. It visits only those flags and non-flags that have been set.

func (*FlagSet) RangeAll added in v1.4.0

func (f *FlagSet) RangeAll(fn func(*Flag))

RangeAll visits the flags and non-flags in lexicographical order, calling fn for each. It visits all flags and non-flags, even those not set.

func (*FlagSet) Set added in v1.4.0

func (f *FlagSet) Set(name, value string) error

Set sets the value of the named flag or the non-flag.

func (*FlagSet) StructVars added in v1.1.0

func (f *FlagSet) StructVars(p interface{}) error

StructVars defines flags based on struct tags and binds to fields. NOTE:

Not support nested fields

type Getter

type Getter = flag.Getter

Getter is an interface that allows the contents of a Value to be retrieved. It wraps the Value interface, rather than being part of it, because it appeared after Go 1 and its compatibility rules. All Value types provided by this package satisfy the Getter interface.

type Option added in v1.3.2

type Option struct {
	Command string
	Name    string
	Value   string
}

Option command option

func LookupOptions added in v1.3.2

func LookupOptions(arguments []string, name string) []*Option

LookupOptions lookups the options corresponding to the name directly from the arguments.

type Scope added in v1.4.4

type Scope int32

Scope command scope

const (
	// InitialScope the default scope
	InitialScope Scope = 0
)

type Status added in v1.3.0

type Status = status.Status

Status a handling status with code, msg, cause and stack.

type ValidateFunc added in v1.3.0

type ValidateFunc func(interface{}) error

ValidateFunc validator for struct flag

type Value

type Value = flag.Value

Value is the interface to the dynamic value stored in a flag. (The default value is represented as a string.)

If a Value has an IsBoolFlag() bool method returning true, the command-line parser makes -name equivalent to -name=true rather than using the next command-line argument.

Set is called once, in command line order, for each flag present. The flag package may call the String method with a zero-valued receiver, such as a nil pointer.

Jump to

Keyboard shortcuts

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