Documentation
¶
Index ¶
- Constants
- type Command
- type Executor
- type Flag
- func (f *Flag) Defaults() string
- func (f *Flag) Env() string
- func (f *Flag) IsPersistent() bool
- func (f *Flag) IsRequired() bool
- func (f *Flag) Name() string
- func (f *Flag) Register(cmd *cobra.Command, envPrefix string)
- func (f *Flag) Set(val string) error
- func (f *Flag) Short() string
- func (f *Flag) String() string
- func (f *Flag) Type() string
Examples ¶
Constants ¶
View Source
const ( OPTION_REQUIRE = "require" // OPTION_REQUIRE marks flag as required OPTION_PERSIST = "persist" // OPTION_PERSIST marks flag persistent OPTION_DEFAULT = "default" // OPTION_DEFAULT marks flag default value, if flag has no option OPTION_SHORTHAND = "short" // OPTION_SHORTHAND marks flag short )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Command ¶
type Command interface {
// Use command usage message, as `cobra.Command.Use`
Use() string
// WithShort adds short description of this executor
WithShort(string) Command
// WithLong adds long descriptions
WithLong(string) Command
// WithExample adds example description
WithExample(string) Command
// Cmd returns generated *cobra.Command
Cmd() *cobra.Command
}
Command used to generate a cobra.Command
it defines the basic info for constructing cobra.Command, such as usage message, short description and execution method
func NewCommand ¶
type Executor ¶
Executor defines executor handling logic
Example ¶
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"math/big"
"os"
"github.com/spf13/cobra"
"github.com/xoctopus/confx/pkg/cmdx"
)
type Basics struct {
Required string `cmd:",require"`
Persistent *float32 `cmd:",persist"`
HasDefault string `cmd:",default='has-default'"`
Shorthand int `cmd:"short-hand,short=s"`
Skipped any `cmd:"-"`
unexported any
}
func (b *Basics) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"basic datatype flags"}, true
}
switch names[0] {
case "Required":
return []string{"string", "case [required]"}, true
case "Persistent":
return []string{"*float32", "case [persistent]"}, true
case "HasDefault":
return []string{"string", "case [has-no-option-default]"}, true
case "Shorthand":
return []string{"int", "case [has-shorthand to 's']"}, true
case "Skipped":
return []string{"any", "case [skip flag marked as '-']"}, true
}
return []string{}, false
}
type Composited struct {
StringArray []*string
IntegerArray []int64
BigInt *big.Int
}
func (c *Composited) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"composited datatype flags"}, true
}
switch names[0] {
case "StringArray":
return []string{"[]*string", "case [strings]"}, true
case "IntegerArray":
return []string{"[]int64", "case [integers]"}, true
case "BigInt":
return []string{"*big.Int", "case [TextMarshaler]"}, true
}
return []string{}, false
}
type Prefixed struct {
Required string `cmd:",require"`
Persistent *float32 `cmd:",persist"`
HasDefault string `cmd:",default='100 101 102'"`
}
func (c *Prefixed) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"prefixed flags"}, true
}
switch names[0] {
case "Required":
return []string{"string", "case [prefixed,require]"}, true
case "Persistent":
return []string{"*float32", "case [prefixed,persistent]"}, true
case "HasDefault":
return []string{"string", "case [prefixed,default]"}, true
}
return []string{}, false
}
type Inline struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}
func (v *Inline) UnmarshalText(text []byte) error {
tmp := struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}{}
if err := json.Unmarshal(text, &tmp); err != nil {
return err
}
v.Required = tmp.Required
v.HasDefault = tmp.HasDefault
v.Persistent = tmp.Persistent
return nil
}
func (v Inline) MarshalText() ([]byte, error) {
return json.Marshal(struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}{
Required: v.Required,
Persistent: v.Persistent,
HasDefault: v.HasDefault,
})
}
type TestExecutor struct {
Basics
*Composited
Prefixed `cmd:"prefixed"`
Inline
Global string
}
func (*TestExecutor) Exec(cmd *cobra.Command, args ...string) error {
cmd.Println("args:")
for _, arg := range args {
cmd.Printf(" %s\n", arg)
}
cmd.Println()
cmd.Println("flags")
names := []string{
"required",
"persistent",
"has-default",
"short-hand",
"string-array",
"integer-array",
"big-int",
"prefixed-required",
"prefixed-persistent",
"prefixed-has-default",
"inline",
"global",
"must-not-found",
}
for _, name := range names {
f := cmd.Flag(name)
if f == nil {
cmd.Printf(" %-21s flag is not registered\n", name+":")
continue
}
v := f.Value.String()
if v == "" {
v = f.NoOptDefVal
}
cmd.Printf(" %-21s %s\n", name+":", v)
}
return nil
}
func NewCommand(v cmdx.Executor, buf io.ReadWriter, args ...string) cmdx.Command {
c := cmdx.NewCommand("demo", v)
c.WithShort("this is a short description for executor `demo`")
c.WithLong("this is a long description for executor `demo`")
c.WithExample("this is an example for executor `demo`")
cmd := c.Cmd()
cmd.SetErr(buf)
cmd.SetOut(buf)
cmd.SetArgs(args)
return c
}
func main() {
_ = os.Setenv("DEMO__REQUIRED", "true")
buf := bytes.NewBuffer(nil)
cmd := NewCommand(
&TestExecutor{},
buf,
// TestBasics
"--required", "required",
"--persistent", "100.001",
// "--has-default", "",
"-s", "101",
// *TestComposited
"--string-array", "str1 str2 str3",
"--integer-array", "100 101 102",
"--big-int", "1111111111111111111111111111111111",
// TestPrefixed
"--prefixed-required", "prefixed required",
"--prefixed-persistent", "100.02",
"--prefixed-has-default", "overwrite default",
// TestInline
"--inline", `{"required": "required", "persistent": 100.002, "hasDefault": "default string"}`,
// Global
"--global", "global string",
// append arguments
"arg1",
"arg2",
)
cmd.Cmd().Printf("command: %s\n\n", cmd.Use())
_ = cmd.Cmd().Execute()
fmt.Print(buf.String())
}
Output: command: demo args: overwrite default arg1 arg2 flags required: required persistent: 100.001 has-default: has-default short-hand: 101 string-array: [str1 str2 str3] integer-array: [100 101 102] big-int: 1111111111111111111111111111111111 prefixed-required: prefixed required prefixed-persistent: 100.02 prefixed-has-default: 100 101 102 inline: {"required":"required","persistent":100.002,"hasDefault":"default string"} global: global string must-not-found: flag is not registered
Example (Help) ¶
package main
import (
"bytes"
"encoding/json"
"io"
"log"
"math/big"
"github.com/spf13/cobra"
"github.com/xoctopus/confx/pkg/cmdx"
)
type Basics struct {
Required string `cmd:",require"`
Persistent *float32 `cmd:",persist"`
HasDefault string `cmd:",default='has-default'"`
Shorthand int `cmd:"short-hand,short=s"`
Skipped any `cmd:"-"`
unexported any
}
func (b *Basics) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"basic datatype flags"}, true
}
switch names[0] {
case "Required":
return []string{"string", "case [required]"}, true
case "Persistent":
return []string{"*float32", "case [persistent]"}, true
case "HasDefault":
return []string{"string", "case [has-no-option-default]"}, true
case "Shorthand":
return []string{"int", "case [has-shorthand to 's']"}, true
case "Skipped":
return []string{"any", "case [skip flag marked as '-']"}, true
}
return []string{}, false
}
type Composited struct {
StringArray []*string
IntegerArray []int64
BigInt *big.Int
}
func (c *Composited) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"composited datatype flags"}, true
}
switch names[0] {
case "StringArray":
return []string{"[]*string", "case [strings]"}, true
case "IntegerArray":
return []string{"[]int64", "case [integers]"}, true
case "BigInt":
return []string{"*big.Int", "case [TextMarshaler]"}, true
}
return []string{}, false
}
type Prefixed struct {
Required string `cmd:",require"`
Persistent *float32 `cmd:",persist"`
HasDefault string `cmd:",default='100 101 102'"`
}
func (c *Prefixed) DocOf(names ...string) ([]string, bool) {
if len(names) == 0 {
return []string{"prefixed flags"}, true
}
switch names[0] {
case "Required":
return []string{"string", "case [prefixed,require]"}, true
case "Persistent":
return []string{"*float32", "case [prefixed,persistent]"}, true
case "HasDefault":
return []string{"string", "case [prefixed,default]"}, true
}
return []string{}, false
}
type Inline struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}
func (v *Inline) UnmarshalText(text []byte) error {
tmp := struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}{}
if err := json.Unmarshal(text, &tmp); err != nil {
return err
}
v.Required = tmp.Required
v.HasDefault = tmp.HasDefault
v.Persistent = tmp.Persistent
return nil
}
func (v Inline) MarshalText() ([]byte, error) {
return json.Marshal(struct {
Required string `json:"required"`
Persistent *float32 `json:"persistent"`
HasDefault string `json:"hasDefault"`
}{
Required: v.Required,
Persistent: v.Persistent,
HasDefault: v.HasDefault,
})
}
type TestExecutor struct {
Basics
*Composited
Prefixed `cmd:"prefixed"`
Inline
Global string
}
func (*TestExecutor) Exec(cmd *cobra.Command, args ...string) error {
cmd.Println("args:")
for _, arg := range args {
cmd.Printf(" %s\n", arg)
}
cmd.Println()
cmd.Println("flags")
names := []string{
"required",
"persistent",
"has-default",
"short-hand",
"string-array",
"integer-array",
"big-int",
"prefixed-required",
"prefixed-persistent",
"prefixed-has-default",
"inline",
"global",
"must-not-found",
}
for _, name := range names {
f := cmd.Flag(name)
if f == nil {
cmd.Printf(" %-21s flag is not registered\n", name+":")
continue
}
v := f.Value.String()
if v == "" {
v = f.NoOptDefVal
}
cmd.Printf(" %-21s %s\n", name+":", v)
}
return nil
}
func NewCommand(v cmdx.Executor, buf io.ReadWriter, args ...string) cmdx.Command {
c := cmdx.NewCommand("demo", v)
c.WithShort("this is a short description for executor `demo`")
c.WithLong("this is a long description for executor `demo`")
c.WithExample("this is an example for executor `demo`")
cmd := c.Cmd()
cmd.SetErr(buf)
cmd.SetOut(buf)
cmd.SetArgs(args)
return c
}
func main() {
buf := bytes.NewBuffer(nil)
cmd := NewCommand(&TestExecutor{}, buf, "--help")
_ = cmd.Cmd().Execute()
log.Print("\n" + buf.String())
}
type Flag ¶
type Flag struct {
// contains filtered or unexported fields
}
Flag implements pflag.Value
it can receive all basic types, such as `int`, `uint`. and types that implement encoding.Unmarshaller/Marshaller. it is also acceptable if they are elements of a one-dimensional slice.
func (*Flag) IsPersistent ¶
func (*Flag) IsRequired ¶
Click to show internal directories.
Click to hide internal directories.