cmdr

package module
v0.2.9 Latest Latest
Warning

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

Go to latest
Published: May 24, 2019 License: MIT Imports: 23 Imported by: 76

README

cmdr

Build Status Go Report Card GitHub tag (latest SemVer)

getopt/getopt_long like command-line UI golang library.

A getopt-like parser of command-line options, compatible with the getopt_long syntax, which is an extension of the syntax recommended by POSIX.

cmdr is a UNIX command-line UI library written by golang.

Features

  • Unix getopt(3) representation but without its programmatic interface.

  • Automatic help screen generation

  • Support for unlimited multiple sub-commands.

  • Support for command short and long name, and aliases names.

  • Support for both short and long options (-o and --opt). Support for multiple aliases

  • Automatically allows those formats (applied to long flags too):

    • -I file, -Ifile, and -I=files
    • -I 'file', -I'file', and -I='files'
    • -I "file", -I"file", and -I="files"
  • Support for -D+, -D- to enable/disable a bool flag.

  • Support for circuit-break by --.

  • Support for options being specified multiple times, with different values

  • Support for optional arguments.

  • Groupable commands and options/flags.

    Sortable group name with [0-9A-Za-z]+\..+ format, eg:

    1001.c++, 1100.golang, 1200.java, …;

    abcd.c++, b999.golang, zzzz.java, …;

  • Sortable commands and options/flags. Or sorted by alphabetic order.

  • Predefined commands and flags:

    • Help: -h, -?, --help, ...
    • Version & Build Info: --version/-V, --build-info/-#
    • Verbose & Debug: —verbose/-v, —debug/-D, —quiet/-q
    • Generate Commands:
      • generate shell: —bash/—zsh(todo)
      • generate manual: todo
      • generate doc: todo
  • Generators

    • Man Page generator: bin/demo generate manrefactor

    • Bash and Zsh (not yet, todo) completion.

      bin/wget-demo generate shell --bash
      
  • Predefined yaml config file locations:

    • /etc/<appname>/<appname>.yml and conf.d sub-directory.

    • /usr/local/etc/<appname>/<appname>.yml and conf.d sub-directory.

    • $HOME/<appname>/<appname>,yml and conf.d sub-directory.

    • Watch conf.d directory:

      • AddOnConfigLoadedListener(c)
      • RemoveOnConfigLoadedListener(c)
      • SetOnConfigLoadedListener(c, enabled)
    • As a feature, do NOT watch the changes on <appname>.yml.

    • To customize the searching locations yourself:

      • SetPredefinedLocations(locations)

        SetPredefinedLocations([]string{"./config", "~/.config/cmdr/", "$GOPATH/running-configs/cmdr"})
        
  • Overrides by environment variables.

    todo: prior:

  • cmdr.Get(key), cmdr.GetBool(key), cmdr.GetInt(key), cmdr.GetString(key), cmdr.GetStringSlice(key) for Option value extractions.

    • bool
    • int, int64, uint, uint64
    • string
    • string slice
    • todo: time, duration, int slice, ...
  • cmdr.Set(key, value), cmdr.SerNx(key, value)

  • Write Painter implementation to loop each commands and flags

  • Todo: manual generator, and markdown/docx/pdf generators.

  • More...

Examples

  1. short
    simple codes.
  2. demo
    normal demo with external config files.
  3. wget-demo
    partial-impl wget demo.

Documentation

Uses

LICENSE

MIT.

Documentation

Index

Constants

View Source
const (

	// UnsortedGroup for commands and flags
	UnsortedGroup = "zzzz.unsorted"
	// SysMgmtGroup for commands and flags
	SysMgmtGroup = "zzz9.Misc"
)
View Source
const (
	// AppName const
	AppName = "cmdr" // main app-name
	// Version const
	Version = "0.2.9" // version name
	// VersionInt const
	VersionInt = 0x000209 // using as
)
View Source
const (
	FgBlack        = 30
	FgRed          = 31
	FgGreen        = 32
	FgYellow       = 33
	FgBlue         = 34
	FgMagenta      = 35
	FgCyan         = 36
	FgLightGray    = 37
	FgDarkGray     = 90
	FgLightRed     = 91
	FgLightGreen   = 92
	FgLightYellow  = 93
	FgLightBlue    = 94
	FgLightMagenta = 95
	FgLightCyan    = 96
	FgWhite        = 97

	BgNormal       = 0
	BgBoldOrBright = 1
	BgDim          = 2
	BgItalic       = 3
	BgUnderline    = 4
	BgUlink        = 5
	BgHidden       = 8

	DarkColor = FgLightGray
)

Variables

View Source
var (
	// GormDefaultCopier used for gorm
	GormDefaultCopier = &CopierImpl{true, true, true}
	// StandardCopier is a normal copier
	StandardCopier = &CopierImpl{false, false, false}
)
View Source
var (
	// EnableVersionCommands supports injecting the default `--version` flags and commands
	EnableVersionCommands = true
	// EnableHelpCommands supports injecting the default `--help` flags and commands
	EnableHelpCommands = true
	// EnableVerboseCommands supports injecting the default `--verbose` flags and commands
	EnableVerboseCommands = true
	// EnableGenerateCommands supports injecting the default `generate` commands and subcommands
	EnableGenerateCommands = true

	// RxxtPrefix create a top-level namespace, which contains all normalized `Flag`s.
	RxxtPrefix = []string{"app"}

	// EnvPrefix attaches a prefix to key to retrieve the option value.
	EnvPrefix = []string{"CMDR"}

	CurrentDescColor         = FgDarkGray
	CurrentDefaultValueColor = FgDarkGray
	CurrentGroupTitleColor   = DarkColor

	// ErrShouldBeStopException tips `Exec()` cancelled the following actions after `PreAction()`
	ErrShouldBeStopException = errors.New("should be stop right now")
)

Functions

func AddOnConfigLoadedListener

func AddOnConfigLoadedListener(c ConfigReloaded)

AddOnConfigLoadedListener add an functor on config loaded and merged

func Clone added in v0.2.3

func Clone(fromValue, toValue interface{}) interface{}

Clone deep copy source to target

func DumpAsString

func DumpAsString() (str string)

DumpAsString for debugging.

func EnsureDir

func EnsureDir(dir string) (err error)

EnsureDir checks and creates the directory.

func Exec

func Exec(rootCmd *RootCommand) (err error)

Exec is main entry of `cmdr`.

func FileExists

func FileExists(name string) bool

FileExists returns the existence of an directory or file

func Get

func Get(key string) interface{}

Get returns the generic value of an `Option` key. Such as: ```golang cmdr.Get("app.logger.level") => 'DEBUG',... ```

func GetBool

func GetBool(key string) bool

GetBool returns the bool value of an `Option` key.

func GetBoolP added in v0.2.3

func GetBoolP(prefix, key string) bool

GetBoolP returns the bool value of an `Option` key.

func GetCurrentDir

func GetCurrentDir() string

GetCurrentDir returns the current working directory

func GetDebugMode added in v0.2.5

func GetDebugMode() bool

GetDebugMode returns the flag value of `--debug`/`-D`

func GetExcutableDir

func GetExcutableDir() string

GetExcutableDir returns the executable file directory

func GetInt

func GetInt(key string) int

GetInt returns the int value of an `Option` key.

func GetInt64 added in v0.2.3

func GetInt64(key string) int64

GetInt64 returns the int64 value of an `Option` key.

func GetInt64P added in v0.2.3

func GetInt64P(prefix, key string) int64

GetInt64P returns the int64 value of an `Option` key.

func GetIntP added in v0.2.3

func GetIntP(prefix, key string) int

GetIntP returns the int value of an `Option` key.

func GetPredefinedLocations added in v0.2.5

func GetPredefinedLocations() []string

GetPredefinedLocations return the searching locations for loading config files.

func GetQuietMode added in v0.2.5

func GetQuietMode() bool

GetDebugMode returns the flag value of `--quiet`/`-q`

func GetStrictMode added in v0.2.5

func GetStrictMode() bool

GetStrictMode enables error when opt value missed. such as: xxx a b --prefix” => error: prefix opt has no value specified. xxx a b --prefix'/' => ok.

ENV: use `CMDR_APP_STRICT_MODE=true` to enable strict-mode. NOTE: `CMDR_APP_` prefix could be set by user (via: `EnvPrefix` && `RxxtPrefix`).

the flag value of `--strict-mode`.

func GetString

func GetString(key string) string

GetString returns the string value of an `Option` key.

func GetStringP added in v0.2.3

func GetStringP(prefix, key string) string

GetStringP returns the string value of an `Option` key.

func GetStringSlice

func GetStringSlice(key string) []string

GetStringSlice returns the string slice value of an `Option` key.

func GetStringSliceP added in v0.2.3

func GetStringSliceP(prefix, key string) []string

GetStringSliceP returns the string slice value of an `Option` key.

func GetUint added in v0.2.3

func GetUint(key string) uint

GetUint returns the uint value of an `Option` key.

func GetUint64 added in v0.2.3

func GetUint64(key string) uint64

GetUint64 returns the uint64 value of an `Option` key.

func GetUint64P added in v0.2.3

func GetUint64P(prefix, key string) uint64

GetUint64P returns the uint64 value of an `Option` key.

func GetUintP added in v0.2.3

func GetUintP(prefix, key string) uint

GetUintP returns the uint value of an `Option` key.

func GetUsedConfigFile added in v0.2.3

func GetUsedConfigFile() string

GetUsedConfigFile returns the main config filename (generally it's `<appname>.yml`)

func GetUsedConfigSubDir added in v0.2.3

func GetUsedConfigSubDir() string

GetUsedConfigSubDir returns the sub-directory `conf.d` of config files

func GetVerboseMode added in v0.2.5

func GetVerboseMode() bool

GetDebugMode returns the flag value of `--verbose`/`-v`

func InternalExecFor added in v0.2.3

func InternalExecFor(rootCmd *RootCommand, args []string) (err error)

InternalExecFor is an internal helper, esp for debugging

func LoadConfigFile

func LoadConfigFile(file string) (err error)

LoadConfigFile Load a yaml config file and merge the settings into `rxxtOptions` and load files in the `conf.d` child directory too.

func RemoveOnConfigLoadedListener

func RemoveOnConfigLoadedListener(c ConfigReloaded)

RemoveOnConfigLoadedListener remove an functor on config loaded and merged

func Set added in v0.2.3

func Set(key string, val interface{})

Set set the value of an `Option` key. ```golang cmdr.Set("app.logger.level", "DEBUG") cmdr.Set("app.ms.tags.port", 8500) ... ```

func SetCustomShowBuildInfo added in v0.2.3

func SetCustomShowBuildInfo(fn func())

SetCustomShowBuildInfo supports your `ShowBuildInfo()` instead of internal `showBuildInfo()`

func SetCustomShowVersion added in v0.2.3

func SetCustomShowVersion(fn func())

SetCustomShowVersion supports your `ShowVersion()` instead of internal `showVersion()`

func SetInternalOutputStreams added in v0.2.3

func SetInternalOutputStreams(out, err *bufio.Writer)

SetInternalOutputStreams sets the internal output streams for debugging

func SetNx added in v0.2.3

func SetNx(key string, val interface{})

SetNx but without prefix auto-wrapped. `rxxtPrefix` is a string slice to define the prefix string array, default is ["app"]. So, cmdr.Set("debug", true) will put an real entry with (`app.debug`, true).

func SetOnConfigLoadedListener

func SetOnConfigLoadedListener(c ConfigReloaded, enabled bool)

SetOnConfigLoadedListener enable/disable an functor on config loaded and merged

func SetPredefinedLocations added in v0.2.5

func SetPredefinedLocations(locations []string)

SetPredefinedLocations to customize the searching locations for loading config files. It MUST be invoked before `cmdr.Exec`. Such as: ```go

SetPredefinedLocations([]string{"./config", "~/.config/cmdr/", "$GOPATH/running-configs/cmdr"})

```

func StripOrderPrefix added in v0.2.9

func StripOrderPrefix(s string) string

func WalkAllCommands added in v0.2.9

func WalkAllCommands(walk func(cmd *Command, index int) (err error)) (err error)

WalkAllCommands loop on all commands, started from root.

Types

type BaseOpt

type BaseOpt struct {
	Name string
	// single char. example for flag: "a" -> "-a"
	// Short rune.
	Short string
	// word string. example for flag: "addr" -> "--addr"
	Full string
	// more synonyms
	Aliases []string
	// group name
	Group string
	// to-do: Toggle Group
	ToggleGroup string

	Flags []*Flag

	Description             string
	LongDescription         string
	Examples                string
	Hidden                  bool
	DefaultValuePlaceholder string

	// cmd 是 flag 被识别时已经得到的子命令
	// return: ErrShouldBeStopException will break the following flow and exit right now
	Action func(cmd *Command, args []string) (err error)
	// contains filtered or unexported fields
}

BaseOpt is base of `Command`, `Flag`

func (*BaseOpt) GetDescZsh

func (s *BaseOpt) GetDescZsh() (desc string)

GetDescZsh temp

func (*BaseOpt) GetLongTitleNamesArray added in v0.2.3

func (s *BaseOpt) GetLongTitleNamesArray() []string

GetLongTitleNamesArray temp

func (*BaseOpt) GetShortTitleNamesArray added in v0.2.3

func (s *BaseOpt) GetShortTitleNamesArray() []string

GetShortTitleNamesArray temp

func (*BaseOpt) GetTitleFlagNames

func (s *BaseOpt) GetTitleFlagNames() string

GetTitleFlagNames temp

func (*BaseOpt) GetTitleFlagNamesBy

func (s *BaseOpt) GetTitleFlagNamesBy(delimChar string) string

GetTitleFlagNamesBy temp

func (*BaseOpt) GetTitleFlagNamesByMax

func (s *BaseOpt) GetTitleFlagNamesByMax(delimChar string, maxCount int) string

GetTitleFlagNamesByMax temp

func (*BaseOpt) GetTitleName

func (s *BaseOpt) GetTitleName() string

GetTitleName temp

func (*BaseOpt) GetTitleNames

func (s *BaseOpt) GetTitleNames() string

GetTitleNames temp

func (*BaseOpt) GetTitleNamesArray

func (s *BaseOpt) GetTitleNamesArray() []string

GetTitleNamesArray temp

func (*BaseOpt) GetTitleNamesBy

func (s *BaseOpt) GetTitleNamesBy(delimChar string) string

GetTitleNamesBy temp

func (*BaseOpt) GetTitleZshFlagName

func (s *BaseOpt) GetTitleZshFlagName() (str string)

GetTitleZshFlagName temp

func (*BaseOpt) GetTitleZshFlagNames

func (s *BaseOpt) GetTitleZshFlagNames(delimChar string) (str string)

GetTitleZshFlagNames temp

func (*BaseOpt) GetTitleZshFlagNamesArray

func (s *BaseOpt) GetTitleZshFlagNamesArray() (ary []string)

GetTitleZshFlagNamesArray temp

func (*BaseOpt) HasParent added in v0.2.9

func (c *BaseOpt) HasParent() bool

HasParent detects whether owner is available or not

type Command

type Command struct {
	BaseOpt
	SubCommands []*Command
	// return: ErrShouldBeStopException will break the following flow and exit right now
	PreAction func(cmd *Command, args []string) (err error)
	// PostAction will be run after Action() invoked.
	PostAction func(cmd *Command, args []string)
	// be shown at tail of command usages line. Such as for TailPlaceHolder="<host-fqdn> <ipv4/6>":
	// austr dns add <host-fqdn> <ipv4/6> [Options] [Parent/Global Options]
	TailPlaceHolder string
	// contains filtered or unexported fields
}

Command holds the structure of commands and subcommands

func (*Command) GetExpandableNames

func (c *Command) GetExpandableNames() string

GetExpandableNames returns the names comma splitted string.

func (*Command) GetExpandableNamesArray

func (c *Command) GetExpandableNamesArray() []string

GetExpandableNamesArray returns the names array of command, includes short name and long name.

func (*Command) GetName

func (c *Command) GetName() string

GetName returns the name of a `Command`.

func (*Command) GetParentName

func (c *Command) GetParentName() string

GetParentName returns the owner command name

func (*Command) GetQuotedGroupName

func (c *Command) GetQuotedGroupName() string

GetQuotedGroupName returns the group name quoted string.

func (*Command) GetRoot

func (c *Command) GetRoot() *RootCommand

GetRoot returns the `RootCommand`

func (*Command) GetSubCommandNamesBy

func (c *Command) GetSubCommandNamesBy(delimChar string) string

GetSubCommandNamesBy returns the joint string of subcommands

func (*Command) IsRoot added in v0.2.9

func (c *Command) IsRoot() bool

IsRoot returns true if this command is a RootCommand

func (*Command) PrintHelp

func (c *Command) PrintHelp(justFlags bool)

PrintHelp prints help screen

func (*Command) PrintVersion

func (c *Command) PrintVersion()

PrintVersion prints versions information

type ConfigReloaded

type ConfigReloaded interface {
	OnConfigReloaded()
}

ConfigReloaded for config reloaded

type Copier added in v0.2.3

type Copier interface {
	Copy(toValue interface{}, fromValue interface{}, ignoreNames ...string) (err error)
}

Copier interface

type CopierImpl added in v0.2.3

type CopierImpl struct {
	KeepIfFromIsNil  bool // 源字段值为nil指针时,目标字段的值保持不变
	ZeroIfEqualsFrom bool // 源和目标字段值相同时,目标字段被清除为未初始化的零值
	KeepIfFromIsZero bool // 源字段值为未初始化的零值时,目标字段的值保持不变 // 此条尚未实现
}

CopierImpl impl

func (*CopierImpl) Copy added in v0.2.3

func (s *CopierImpl) Copy(toValue interface{}, fromValue interface{}, ignoreNames ...string) (err error)

Copy copy things

type Flag

type Flag struct {
	BaseOpt

	// default value for flag
	DefaultValue interface{}
	ValidArgs    []string
	Required     bool
}

Flag means a flag, a option, or a opt.

type Options

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

Options is a holder of all options

func NewOptions

func NewOptions() *Options

NewOptions returns an `Options` structure pointer

func NewOptionsWith

func NewOptionsWith(entries map[string]interface{}) *Options

NewOptionsWith returns an `Options` structure pointer

func (*Options) DumpAsString

func (s *Options) DumpAsString() (str string)

DumpAsString for debugging.

func (*Options) Get

func (s *Options) Get(key string) interface{}

Get an `Option` by key string, eg: ```golang cmdr.Get("app.logger.level") => 'DEBUG',... ```

func (*Options) GetBool

func (s *Options) GetBool(key string) (ret bool)

GetBool returns the bool value of an `Option` key.

func (*Options) GetInt

func (s *Options) GetInt(key string) (ir int64)

GetInt returns the int64 value of an `Option` key.

func (*Options) GetString

func (s *Options) GetString(key string) (ret string)

GetString returns the string value of an `Option` key.

func (*Options) GetStringSlice

func (s *Options) GetStringSlice(key string) (ir []string)

GetStringSlice returns the string slice value of an `Option` key.

func (*Options) GetUint added in v0.2.3

func (s *Options) GetUint(key string) (ir uint64)

GetUint returns the uint64 value of an `Option` key.

func (*Options) LoadConfigFile

func (s *Options) LoadConfigFile(file string) (err error)

LoadConfigFile Load a yaml config file and merge the settings into `rxxtOptions` and load files in the `conf.d` child directory too.

func (*Options) Reset

func (s *Options) Reset()

Reset the exists `Options`, so that you could follow a `LoadConfigFile()` with it.

func (*Options) Set

func (s *Options) Set(key string, val interface{})

Set set the value of an `Option` key.

func (*Options) SetNx

func (s *Options) SetNx(key string, val interface{})

SetNx but without prefix auto-wrapped. `rxxtPrefix` is a string slice to define the prefix string array, default is ["app"]. So, cmdr.Set("debug", true) will put an real entry with (`app.debug`, true).

type Painter added in v0.2.9

type Painter interface {
	Printf(fmtStr string, args ...interface{})

	FpPrintHeader(command *Command)
	FpPrintHelpTailLine(command *Command)

	FpUsagesTitle(command *Command, title string)
	FpUsagesLine(command *Command, fmt, appName, cmdList, cmdsTitle, tailPlaceHolder string)
	FpDescTitle(command *Command, title string)
	FpDescLine(command *Command)
	FpExamplesTitle(command *Command, title string)
	FpExamplesLine(command *Command)

	FpCommandsTitle(command *Command)
	FpCommandsGroupTitle(group string)
	FpCommandsLine(command *Command)
	FpFlagsTitle(command *Command, flag *Flag, title string)
	FpFlagsGroupTitle(group string)
	FpFlagsLine(command *Command, flag *Flag, defValStr string)

	Flush()
}

type RootCommand

type RootCommand struct {
	Command

	AppName    string
	Version    string
	VersionInt uint32

	Copyright string
	Author    string
	Header    string // using `Header` for header and ignore built with `Copyright` and `Author`, and no usage lines too.
	// contains filtered or unexported fields
}

RootCommand holds some application information

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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