myflags

package module
v2.2.3 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2025 License: MIT Imports: 15 Imported by: 1

README

Go package PkgGoDev

myflags

myflags is a Golang module to make creating command line application easy, it built on top of cobra, provides following additional features:

  1. Instead of creating commands, sub-commands and flags manually, user could simply define all the commands/flags in a struct, myflags automatically creates command/flags based on the struct definition and parsed result get automatically assigned to the struct field that corresponding to the flag.
    • Some common cobra command attribute likes shorthand name, usage, auto-completion choices could be specified as struct field tags
  2. In addition to the types supported by cobra, myflags provides capability to extend support for new types as flag, user could even provide myflags support for existing types without creating alias type
    • this is achieved by implement RegisteredConverters interface
    • types sub module provides support for some existing golang types like time.Time
  3. support any slice/array as flag with element type that implements RegisteredConverters interface
  4. optional summaryhelp command to print usage for the entire command tree

note: current release is v2, the package path is "github.com/hujun-open/myflags/v2"

Quick Start

Using myflags is straight forward:

  1. define all commands/flags in a struct, each command is a sub-struct with tag action, the value of the tag specifies a struct method gets called when the corresponding command is entered in CLI.
    • a root command method could be optionally specified when creating filler with WithRootMethod
    • command could be nested, e.g. subcommand could have its subcommand, which is nested struct with action tag
  2. create a Filler, and call Fill method with the struct variable with default value.
  3. call one of cobra's command execute method like Filler.Execute

Following is an example: https://github.com/hujun-open/myflags/blob/a06b78dbf363c27240d07e59919d9eaf3b03da96/example/main.go#L1-L89

the created flags:

.\cptool summaryhelp
  = cptool [flags]
    -b, --backupaddrlist: backup server address list
        default:1.1.1.1,2.2.2.2
    -c, --configfile: working profile
        default:default.conf
    -f, --floatlist: list of numbers
        default:1.7,2.2,3.3
    --strlist: list of string
        default:a,bb,ccc
    --svraddr: server address to download the archive
        default:<nil>
    = cptool compress
      -l, --loop: number of compress iterations
        default:0x20
      --profile: compress profile
      --skip:
        default:false
      = cptool compress dry
      = cptool compress zipfile <FileName> <ArchiveName>
        <FileName>: input file name
          default:"defaultzip.file"
        <ArchiveName>: output archive name
          default:""
      = cptool compress zipfolder <FolderName> <ArchiveName> <CreationTime>
        <FolderName>: input folder name
          default:""
        <ArchiveName>: output archive name
          default:""
        <CreationTime>: creation time
          default:"2025 02 Jan 03:04"
    = cptool extract <InputFile> <OutputFolder>
      <InputFile>: input archive file
        default:""
      <OutputFolder>: output folder
        default:""
    = cptool completion
      = cptool completion bash
        --no-descriptions: disable completion descriptions
                default:false
      = cptool completion fish [flags]
        --no-descriptions: disable completion descriptions
                default:false
      = cptool completion powershell [flags]
        --no-descriptions: disable completion descriptions
                default:false
      = cptool completion zsh [flags]
        --no-descriptions: disable completion descriptions
                default:false
    = cptool docgen
      --output: output folder
        default:./
      = cptool docgen manpage
        --section: manpage section
                default:3
        --title: manpage title
      = cptool docgen markdown
    = cptool help [command]
    = cptool summaryhelp [flags]
      -h, --help: help for summaryhelp
        default:false

some parsing results:

./cptool --svraddr 1.1.1.1 --backupaddrlist 2.2.2.2,2001:dead::1 compress -l 3  zipfile  input1 out.zip
zipfile &{ConfigFile:default.conf SvrAddr:1.1.1.1 BackupAddrList:[2.2.2.2 2001:dead::1] FloatList:[1.7 2.2 3.3] StrList:[a bb ccc] Compress:{Loop:3 Profile: Skip:false NoFlag: DryRun:{} ZipFolder:{FolderName: ArchiveName: CreationTime:2025-01-02 03:04:05 +0000 UTC} ZipFile:{FileName:input1 ArchiveName:out.zip}} Extract:{InputFile: OutputFolder:}}

.\cptool compress zipfolder folder1 out.zip "2030 01 Jun 13:01" -l 99
zipfolder &{ConfigFile:default.conf SvrAddr:<nil> BackupAddrList:[1.1.1.1 2.2.2.2] FloatList:[1.7 2.2 3.3] StrList:[a bb ccc] Compress:{Loop:99 Profile: Skip:false NoFlag: DryRun:{} ZipFolder:{FolderName:folder1 ArchiveName:out.zip CreationTime:2030-06-01 13:01:00 +0000 UTC} ZipFile:{FileName:defaultzip.file ArchiveName:}} Extract:{InputFile: OutputFolder:}}

Struct Field Tags

Following struct field tags are supported:

  • noun: mark the field as postional argument, the value is the index; e.g. 1 means first argument, 2 is 2nd argument ..etc
  • skipflag: skip the field for flagging
  • alias: use the specified alias as the name of the parameter
  • short: use the specified string as the shorthand parameter name
  • usage: the usage string of the parameter
  • action: this field is an action, the value is the method name to run
  • required: this field is a mandatory required flag
  • choices: a comma separated list of value choices for the field, used for shell completion
  • complete: the value is the method name for shell completion

Supported Types

Base:

  • all int/uint types
  • float32/float64
  • string
  • bool

following are provided by github.com/hujun-open/myflags/v2/types:

  • all int/uint types: support base tag for the base
  • net.HardwareAddr
  • net.IPNet
  • net.IP
  • time.Time
  • time.Duration

Others:

  • All types implement both of following interface:
    • encoding.TextMarshaler
    • encoding.TextUnmarshaler
  • All type register via myflags.Register function

Note: flag is only created for exported struct field.

Slice / Array

In addition to above types, following types are also supported:

  • pointer to the type above
  • slice/array of type above
  • slice/array of pointer to the type above

Use "," as separator of items in the input string

note: if the item type is struct, then it must be either registered type or implements encoding.TextMarshaler/encoding.TextUnmarshaler

Nested / Embeded struct

myflags also supports following type of struct:

  • nested struct, like:
type Outer struct {
    Nested struct {
        Name string
    }
}
  • embeded struct, like:
type SubS struct {
    SubName string
}
type Outer struct {
    SubS
}

Flag Naming

By default, the name of created flag is the lowercase of struct field name, in case the field is part of sub-struct, and parent struct is NOT an action, then the name of created flag is "<parent_field_name>-<field_name>";

Optionally a renaming function could be supplied when creating the Filler, myflags uses the renaming function returned string as the flag name.

Positional Argument

Positional arguments are the struct field with "noun" tag, the value of the tag is the postional index, start from 1. positional argument only get parsed with a command, which means in case of root command positional argument only get parsed when filler is created with WithRootMethod.

Shell Completion

A shell completion script generation command completion could be included via WithShellCompletionCMD(). which is the default cobra shell completion command.

there are two options on how to complete a flag or postional argument

  • use choice tag to specify a list of comma sperated values
  • use complete tag to specify a completion metho with type of cobra.CompletionFunc

both tags can't be used at the same time for a given flag or argument.

Extension

New type could be supported via myflags.Register, which takes a variable implements myflags.RegisteredConverters interface. the myflags.Register must be called before myflags.Fill, typically it should be called in init().

Check types.go, types_int.go for examples.

Builtin Commands

Myflags support following builtin commands:

  • help: same as cobra help command, always included
  • completion: generate completion script for varies shell, same as cobra, always included
  • docgen: doc generation command, currently support markdown and manpage, use cobra's doc generation lib, include via WithDocGenCMD()
  • summaryhelp: print usage for whole command tree, include via WithSummaryHelp()

Bool

myflags support bool flag with following format:

  • --flag (meaning true)
  • --flag=<true|false>

--flag <true|false> is not supported

Documentation

Index

Constants

View Source
const (
	//SkipTag is the struct field tag used to skip flag generation
	SkipTag = "skipflag"
	//AliasTag is the struct field tag used to specify the flag name iso field name
	AliasTag = "alias"
	//ShorthandTag is the struct field tag used to specify shorthand name for the flag
	ShorthandTag = "short"
	//UsageTag is the struct field tag used to specify the usage of the field
	UsageTag = "usage"
	//ActTag is the struct field tag used to specify the field (of type struct) is an action, the value is the name of the method to run
	//method name is looked up in the field struct first, then in the root struct
	ActTag = "action"
	//RequiredTag indicate the flag is mandatory required
	RequiredTag = "required"
	//ValidValuesTag is a list of valid values for the field, separated by comma, used for completion
	ValidValuesTag = "choices"
	//NounTag marks a field as noun for a command, there is only one field will be treated as noun per (sub-)struct
	NounTag = "noun"
	//CompleteTag specify a method as cobra.CompleteFunc
	CompleteTag = "complete"
)
View Source
const (
	//default flag.ErrorHandling
	DefaultErrHandle = flag.ExitOnError
)
View Source
const DocgenCMDName = "docgen"

DocgenCMDName is the optional command to generate docs

View Source
const SummaryHelpCMDName = "summaryhelp"

SummaryHelpCMDName is the name of command print summary help

Variables

This section is empty.

Functions

func DefaultRenamer

func DefaultRenamer(parent, name string, isAct bool) string

DefaultRenamer is the default renaming function, it is parent + "-" + name when isAct is true; otherwise return lower case of name

func IsOwnAction

func IsOwnAction(cmd *cobra.Command, completionCMDName, helpCMDName string, skipRootCMD bool) bool

IsOwnAction check if the cobra.Command.ExecuteC() returned command cmd is intended for cobra's own action, like help, completion command or --version flag with root command completionCMDName and helpCMDName specifies corresponding completion and help command name, "completion" and "help" are used if they are empty string. it also return true if cmd is the root command and skipRootCMD is true,

func PrettyStruct

func PrettyStruct(in any, prefix string) string

PrettyStruct returns a pretty formatted string representation of in

func Register

func Register[T any](c RegisteredConverters)

Register a new type with corresponding converters

func SummaryFillerUsageStr added in v2.1.0

func SummaryFillerUsageStr(filler *Filler, prefix string) string

SummaryFillerUsageStr returns a usage string that include usage of flags, child commands and their children

func SummaryUsageStr

func SummaryUsageStr(cmd *cobra.Command, prefix string) string

SummaryUsageStr returns a usage string that include usage of flags, child commands and their children

Types

type Filler

type Filler struct {
	*cobra.Command
	// contains filtered or unexported fields
}

Filler auto-generates one or multiple flag.FlagSet based on an input struct

func NewFiller

func NewFiller(name, usage string, options ...FillerOption) *Filler

NewFiller creates a new Filler, name is the name for the command, usage is the overall usage introduction. optionally, a list of FillerOptions could be specified. Note: the name must be same as the name of application executable, otherwise shell completion won't work.

func (*Filler) ExecuteCMDPath added in v2.0.2

func (filler *Filler) ExecuteCMDPath() (*cobra.Command, []string, error)

ExecutePath run filler.ExecuteC() and return the executed command and full command path as slice of string, first level sub-command name invoked is the first item in the slice.

func (*Filler) Fill

func (filler *Filler) Fill(in any) error

Fill filler with struct in

func (*Filler) FindFiller added in v2.2.2

func (filler *Filler) FindFiller(args []string) *Filler

FindFiller return corresponding filler that handles given args

func (*Filler) GetChildCommand

func (filler *Filler) GetChildCommand(childpath string) *cobra.Command

GetChildCommand return a child command specified by child path, which is a string of list of command names separated by "/", start with "/" which represents calling filler's command e.g. /act1/act12/act121; return nil if not found or childpath is not valid

func (*Filler) GetChildFiller added in v2.2.2

func (filler *Filler) GetChildFiller(childpath string) *Filler

GetChildFiller return a child Filler specified by child path, which is a string of list of command names separated by "/", start with "/" which represents calling filler's command e.g. /act1/act12/act121; return nil if not found or childpath is not valid

func (*Filler) GetFlagset

func (filler *Filler) GetFlagset() *flag.FlagSet

GetFlagset returns the flagset used by the filler

func (*Filler) GetNounCompleteFunc added in v2.2.2

func (filler *Filler) GetNounCompleteFunc(index uint) cobra.CompletionFunc

GetNounCompleteFunc returns complete function for the noun specified by the index, which start from 1; return nil if not found

func (*Filler) GetNounStructField added in v2.2.2

func (filler *Filler) GetNounStructField(index uint) *reflect.StructField

GetNounStructField returns struct field for the noun specified by the index, which start from 1; return nil if not found

func (*Filler) SetPreRun added in v2.1.0

func (filler *Filler) SetPreRun(f func(cmd *cobra.Command, args []string))

SetPreRun set f as filler.Commmand.PreRun method; don't set filler.Command.PreRun directly

func (*Filler) SetPreRunE added in v2.1.0

func (filler *Filler) SetPreRunE(f func(cmd *cobra.Command, args []string) error)

SetPreRun set f as filler.Commmand.PreRunE method; don't set filler.Command.PreRunE directly

func (*Filler) SummaryHelpCMD

func (filler *Filler) SummaryHelpCMD() *cobra.Command

SummaryHelpCMD returns a command `summaryhelp` that print summary help that include usage of flags, child commands and their children

type FillerOption

type FillerOption func(filler *Filler)

FillerOption is an option when creating new Filler

func WithDocGenCMD

func WithDocGenCMD() FillerOption

include doc generation command

func WithFlagErrHandling

func WithFlagErrHandling(h flag.ErrorHandling) FillerOption

WithFlagErrHandling returns a FillerOption thats specifies the flag.ErrorHandling

func WithRenamer

func WithRenamer(r RenameFunc) FillerOption

WithRenamer returns a FillerOption that specifies the rename function

func WithRootArgCompletionMethod added in v2.2.0

func WithRootArgCompletionMethod(f cobra.CompletionFunc) FillerOption

WithRootArgCompletionMethod set f as ValidArgsFunction of the root command

func WithRootMethod

func WithRootMethod(f RunMethod) FillerOption

WithRootMethod set f as the Run method of the root command

func WithShellCompletionCMD added in v2.2.0

func WithShellCompletionCMD() FillerOption

func WithSummaryHelp

func WithSummaryHelp() FillerOption

WithSummaryHelp adds a command `summaryhelp` that print summary help that include usage of flags, child commands and their children

type FromStrFunc

type FromStrFunc func(s string, tags reflect.StructTag) (any, error)

FromStrFunc is a function convert string s into a specific type T, the tag is the struct field tag, as addtional input. see time.go for implementation examples

type RegisteredConverters

type RegisteredConverters interface {
	ToStr(any, reflect.StructTag) string
	FromStr(string, reflect.StructTag) (any, error)
}

type RenameFunc

type RenameFunc func(parent, name string, isAct bool) string

RenameFunc is the function to rename the flag for a struct field, name is the field name, while parent is the parent struct field name, isAct is true when parent is an action

type RunMethod

type RunMethod func(cmd *cobra.Command, args []string)

RunMethod is the type of function could be used as cobra.Command.Run

var DefRunMethod RunMethod = func(cmd *cobra.Command, args []string) {}

DefRunMethod is function that does nothing, it is assigned if value of ActTag is empty string

type ToStrFunc

type ToStrFunc func(in any, tags reflect.StructTag) string

ToStrFunc is a function convert in to string, the tag is the struct field tag, as addtional input. see time.go for implementation examples

Directories

Path Synopsis
Package types provide myflags support for following golang types:
Package types provide myflags support for following golang types:

Jump to

Keyboard shortcuts

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