cflag

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2023 License: Apache-2.0 Imports: 19 Imported by: 0

README

cflag

cflag - Wraps and extends go flag.FlagSet to build simple command line applications

  • Supports auto-rendering of pretty help messages
  • Allows adding short options to flag options, and multiples
  • Allows binding named arguments
  • Allows setting arguments or options as required
  • Allows setting validators for arguments or options

中文说明

Install

go get github.com/zhangyiming748/pretty/cflag

Go docs

Usage

Examples, code please see _example/cmd.go

package main

import (
	"github.com/zhangyiming748/pretty/cflag"
	"github.com/zhangyiming748/pretty/cliutil"
)

var opts = struct {
    age  int
    name string
    str1 string
    lOpt string
    bol  bool
}{}

// go run ./_example/cmd.go
// go run ./cflag/_example/cmd.go -h
// go run ./cflag/_example/cmd.go --name inhere --lo val ab cd
func main() {
	c := cflag.New(func(c *cflag.CFlags) {
		c.Desc = "this is a demo command"
		c.Version = "0.5.1"
	})
	c.IntVar(&opts.age, "age", 0, "this is a int option;;a")
	c.StringVar(&opts.name, "name", "", "this is a string option and required;true")
	c.StringVar(&opts.str1, "str1", "def-val", "this is a string option with default value;;s")
	c.StringVar(&opts.lOpt, "long-opt", "", "this is a string option with shorts;;lo")

	c.AddArg("arg1", "this is arg1", true, nil)
	c.AddArg("arg2", "this is arg2", true, nil)

	c.Func = func(c *cflag.CFlags) error {
		cliutil.Magentaln("hello, this is command:", c.Name())
		cliutil.Infoln("option.age =", opts.age)
		cliutil.Infoln("option.name =", opts.name)
		cliutil.Infoln("option.str1 =", opts.str1)
		cliutil.Infoln("option.lOpt =", opts.lOpt)
		cliutil.Infoln("arg1 =", c.Arg("arg1").String())
		cliutil.Infoln("arg2 =", c.Arg("arg2").String())
		cliutil.Infoln("remain args =", c.RemainArgs())

		return nil
	}

	// c.MustParse(os.Args[1:])
	c.MustParse(nil)
}
Bind and get arguments

Bind arguments:

	c.AddArg("arg1", "this is arg1", true, nil)
	c.AddArg("arg2", "this is arg2", true, nil)

Get arguments by name:

	cliutil.Infoln("arg1 =", c.Arg("arg1").String())
	cliutil.Infoln("arg2 =", c.Arg("arg2").String())
Set required and short options

Options can be set as required, and short option names can be set.

TIPs: Implements required and shorts by extending usage with options parsed

Format:

  • format1: desc;required
  • format2: desc;required;shorts
  • required: a bool string. mark option is required
    • True: true,on,yes
    • False: false,off,no,''
  • shorts: shortcut names for option, allow multi values, split by comma ,

Examples:

    // set option 'name' is required
	c.StringVar(&opts.name, "name", "", "this is a string option and required;true")
    // set option 'str1' shorts: s
	c.StringVar(&opts.str1, "str1", "def-val", "this is a string option with default value;;s")
Show help
go run ./cflag/_example/cmd.go -h

Output:

cmd-help

Run command
go run ./cflag/_example/cmd.go --name inhere -a 12 --lo val ab cd
go run ./cflag/_example/cmd.go --name inhere -a 12 --lo val ab cd de fg

Output:

cmd-run

required Check
go run ./cflag/_example/cmd.go -a 22
go run ./cflag/_example/cmd.go --name inhere

Output:

cmd-required.png

Cli application

Use cflag to quickly build a multi-command application.

package main

import (
	"github.com/zhangyiming748/pretty/cflag"
	"github.com/zhangyiming748/pretty/dump"
)

var c1Opts = struct {
	age  int
	name string
}{}

var c2Opts = struct {
	str1 string
	lOpt string
	bol  bool
}{}

// go run ./_example/app.go
// go run ./cflag/_example/app.go -h
// go run ./cflag/_example/app.go demo -h
func main() {
	app := cflag.NewApp()
	app.Desc = "this is my cli application"
	app.Version = "1.0.2"

	// go run ./cflag/_example/app.go demo --name inhere --age 333 val0 val1
	c1 := cflag.NewCmd("demo", "this is a demo command")
	c1.OnAdd = func(c *cflag.Cmd) {
		c.IntVar(&c1Opts.age, "age", 0, "this is a int option;;a")
		c.StringVar(&c1Opts.name, "name", "", "this is a string option and required;true")

		c.AddArg("arg1", "this is arg1", true, nil)
		c.AddArg("arg2", "this is arg2", false, nil)
	}
	c1.Func = func(c *cflag.Cmd) error {
		pretty.P(c1Opts, c.Args())
		return nil
	}

	// Multiple commands can be added
	app.Add(c1)

	app.Run()
}
Show commands
go run ./cflag/_example/app.go -h

app-help

Run command
go run ./cflag/_example/app.go demo --name inhere --age 333 val0 val1

app-run

Documentation

Overview

Package cflag Wraps and extends go `flag.FlagSet` to build simple command line applications

- Support auto render a pretty help panel

- Allow to add shortcuts for flag option

- Allow binding named arguments

- Allow set required for argument or option

- Allow set validator for argument or option

Example
package main

import (
	"github.com/zhangyiming748/pretty/cflag"
	"github.com/zhangyiming748/pretty/cliutil"
)

func main() {
	opts := struct {
		age  int
		name string
		str1 string
		bol  bool
	}{}

	c := cflag.New(func(c *cflag.CFlags) {
		c.Desc = "this is a demo command"
		c.Version = "0.5.1"
	})
	c.IntVar(&opts.age, "age", 0, "this is a int option;;a")
	c.StringVar(&opts.name, "name", "", "this is a string option and required;true")
	c.StringVar(&opts.str1, "str1", "def-val", "this is a string option with default value;;s")

	c.AddArg("arg1", "this is arg1", true, nil)
	c.AddArg("arg2", "this is arg2", true, nil)
	c.AddArg("arg3", "this is arg3 with default", false, "def-val")

	c.Func = func(c *cflag.CFlags) error {
		// do something ...

		cliutil.Infoln("hello, this is", c.Name())
		cliutil.Infoln("option.age =", opts.age)
		cliutil.Infoln("option.name =", opts.name)
		cliutil.Infoln("option.str1 =", opts.str1)
		cliutil.Infoln("arg1 =", c.Arg("arg1").String())
		cliutil.Infoln("arg2 =", c.Arg("arg2").String())
		cliutil.Infoln("arg3 =", c.Arg("arg3").String())

		return nil
	}

	// c.MustParse(os.Args[1:])
	c.MustParse(nil)
}
Output:

Index

Examples

Constants

View Source
const ParseStopMark = "--"

ParseStopMark string

Variables

View Source
var Debug = envutil.GetBool("CFLAG_DEBUG")

Debug mode

Functions

func AddPrefix

func AddPrefix(name string) string

AddPrefix for render flag options help

func AddPrefixes

func AddPrefixes(name string, shorts []string) string

AddPrefixes for render flag options help, name will first add.

func AddPrefixes2

func AddPrefixes2(name string, shorts []string, nameAtEnd bool) string

AddPrefixes2 for render flag options help, can custom name add position.

func FilterNames

func FilterNames(names []string) []string

FilterNames for option names, will clear there are: "-+= "

func IsFlagHelpErr

func IsFlagHelpErr(err error) bool

IsFlagHelpErr check

func IsZeroValue

func IsZeroValue(opt *flag.Flag, value string) (bool, bool)

IsZeroValue determines whether the string represents the zero value for a flag.

from flag.isZeroValue() and more return the second arg for check is string.

func ReplaceShorts

func ReplaceShorts(args []string, shortsMap map[string]string) []string

ReplaceShorts replace shorts to full option. will stop on ParseStopMark

For example:

eg: '-f' -> '--file'.
eg: '-n=tom' -> '--name=tom'.

func SetDebug

func SetDebug(open bool)

SetDebug mode

func SplitShortcut

func SplitShortcut(shortcut string) []string

SplitShortcut string to []string

func WithDesc

func WithDesc(desc string) func(c *CFlags)

WithDesc for command

func WithVersion

func WithVersion(version string) func(c *CFlags)

WithVersion for command

func WrapColorForCode

func WrapColorForCode(s string) string

WrapColorForCode WrapColorForCode. convert "hello `keywords`" to "hello <mga>keywords</>"

Types

type App

type App struct {
	Name string
	Desc string
	// NameWidth max width for command name
	NameWidth  int
	HelpWriter io.Writer
	// Version for app
	Version string

	// AfterHelpBuild hook
	AfterHelpBuild func(buf *strutil.Buffer)
	// contains filtered or unexported fields
}

App struct

func NewApp

func NewApp(fns ...func(app *App)) *App

NewApp instance

Example
app := cflag.NewApp()
app.Desc = "this is my cli application"
app.Version = "1.0.2"

var c1Opts = struct {
	age  int
	name string
}{}

c1 := cflag.NewCmd("demo", "this is a demo command")
c1.OnAdd = func(c *cflag.Cmd) {
	c.IntVar(&c1Opts.age, "age", 0, "this is a int option;;a")
	c.StringVar(&c1Opts.name, "name", "", "this is a string option and required;true")

	c.AddArg("arg1", "this is arg1", true, nil)
	c.AddArg("arg2", "this is arg2", false, nil)
}

c1.Func = func(c *cflag.Cmd) error {
	pretty.P(c1Opts, c.Args())
	return nil
}

var c2Opts = struct {
	str1 string
	lOpt string
	bol  bool
}{}

c2 := cflag.NewCmd("other", "this is another demo command")
{
	c2.StringVar(&c2Opts.str1, "str1", "def-val", "this is a string option with default value;;s")
	c2.StringVar(&c2Opts.lOpt, "long-opt", "", "this is a string option with shorts;;lo")

	c2.Func = func(c *cflag.Cmd) error {
		pretty.P(c2Opts)
		return nil
	}
}

app.Add(c1, c2)
app.Run()
Output:

func (*App) Add

func (a *App) Add(cmds ...*Cmd)

Add command(s) to app

func (*App) Run

func (a *App) Run()

Run app by os.Args

func (*App) RunWithArgs

func (a *App) RunWithArgs(args []string) error

RunWithArgs run app by input args

type Booleans

type Booleans []bool

Booleans The bool flag list, implemented flag.Value interface

func (*Booleans) Set

func (s *Booleans) Set(value string) error

Set new value

func (*Booleans) String

func (s *Booleans) String() string

String to string

type CFlags

type CFlags struct {
	*flag.FlagSet

	// Desc command description
	Desc string
	// Version command version number
	Version string
	// Example command usage examples
	Example string
	// LongHelp custom help
	LongHelp string
	// Func handler for the command
	Func func(c *CFlags) error
	// contains filtered or unexported fields
}

CFlags wrap and extends the go flag.FlagSet

eg:

// Can be set required and shorts on desc:
// format1: desc;required
cmd.IntVar(&age, "age", 0, "your age;true")
// format2: desc;required;shorts
cmd.IntVar(&age, "age", 0, "your age;true;a")

func New

func New(fns ...func(c *CFlags)) *CFlags

New create new instance.

Usage:

cmd := cflag.New(func(c *cflag.CFlags) {
	c.Version = "0.1.2"
	c.Desc = "this is my cli tool"
})

// binding opts and args

cmd.Parse(nil)

func NewEmpty

func NewEmpty(fns ...func(c *CFlags)) *CFlags

NewEmpty instance.

func (*CFlags) AddArg

func (c *CFlags) AddArg(name, desc string, required bool, value any)

AddArg binding for command

func (*CFlags) AddShortcuts

func (c *CFlags) AddShortcuts(name string, shorts ...string)

AddShortcuts for option flag

func (*CFlags) AddValidator

func (c *CFlags) AddValidator(name string, fn OptCheckFn)

AddValidator for a flag option

func (*CFlags) Arg

func (c *CFlags) Arg(name string) *FlagArg

Arg get by bind name

func (*CFlags) BinFile

func (c *CFlags) BinFile() string

BinFile path for command

func (*CFlags) BindArg

func (c *CFlags) BindArg(arg *FlagArg)

BindArg for command

func (*CFlags) ConfigOpt

func (c *CFlags) ConfigOpt(name string, fn func(opt *FlagOpt))

ConfigOpt for a flag option

func (*CFlags) MustParse

func (c *CFlags) MustParse(args []string)

MustParse parse flags and run command, will auto handle error

func (*CFlags) MustRun

func (c *CFlags) MustRun(args []string)

MustRun parse flags and run command. alias of MustParse()

func (*CFlags) Name

func (c *CFlags) Name() string

Name for command

func (*CFlags) Parse

func (c *CFlags) Parse(args []string) error

Parse flags and run command

If args is nil, will parse os.Args

func (*CFlags) QuickRun

func (c *CFlags) QuickRun()

QuickRun parse OS flags and run command, will auto handle error

func (*CFlags) RemainArgs

func (c *CFlags) RemainArgs() []string

RemainArgs get

func (*CFlags) ShowHelp

func (c *CFlags) ShowHelp()

ShowHelp for command

func (*CFlags) WithConfigFn

func (c *CFlags) WithConfigFn(fns ...func(c *CFlags)) *CFlags

WithConfigFn for command

type Cmd

type Cmd struct {
	*CFlags
	Name  string
	Func  func(c *Cmd) error
	OnAdd func(c *Cmd)
}

Cmd struct

func NewCmd

func NewCmd(name, desc string) *Cmd

NewCmd instance

func (*Cmd) Config

func (c *Cmd) Config(fn func(c *Cmd)) *Cmd

Config the cmd

type EnumString

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

EnumString The string flag list, implemented flag.Value interface

func (*EnumString) Set

func (s *EnumString) Set(value string) error

Set new value, will check value is right

func (*EnumString) SetEnum

func (s *EnumString) SetEnum(enum []string)

SetEnum values

func (*EnumString) String

func (s *EnumString) String() string

String to string

type FlagArg

type FlagArg struct {
	// Value for the flag argument
	*structs.Value

	// Name of the argument
	Name string
	// Desc arg description
	Desc string
	// Index of the argument
	Index int
	// Required argument
	Required bool
	// Validator for check value
	Validator func(val string) error
	// contains filtered or unexported fields
}

FlagArg struct

func NewArg

func NewArg(name, desc string, required bool) *FlagArg

NewArg create instance

func (*FlagArg) HelpDesc

func (a *FlagArg) HelpDesc() string

HelpDesc string

type FlagOpt

type FlagOpt struct {
	// Shortcuts short names. eg: ["o", "a"]
	Shortcuts []string
	// Required option
	Required bool
	// Validator for check option value
	Validator OptCheckFn
}

FlagOpt struct

func (*FlagOpt) HelpName

func (o *FlagOpt) HelpName(name string) string

HelpName string

type Ints

type Ints []int

Ints The int flag list, implemented flag.Value interface

func (*Ints) Set

func (s *Ints) Set(value string) error

Set new value

func (*Ints) String

func (s *Ints) String() string

String to string

type OptCheckFn

type OptCheckFn func(val any) error

OptCheckFn define

type String

type String string

String a special string

Usage:

// case 1:
var names gcli.String
c.VarOpt(&names, "names", "", "multi name by comma split")

--names "tom,john,joy"
names.Split(",") -> []string{"tom","john","joy"}

// case 2:
var ids gcli.String
c.VarOpt(&ids, "ids", "", "multi id by comma split")

--names "23,34,56"
names.Ints(",") -> []int{23,34,56}

func (*String) Ints

func (s *String) Ints(sep string) []int

Ints value to []int

func (*String) Set

func (s *String) Set(val string) error

Set value

func (*String) Split

func (s *String) Split(sep string) []string

Split value to []string

func (*String) String

func (s *String) String() string

String to string

type Strings

type Strings []string

Strings The string flag list, implemented flag.Value interface

func (*Strings) Set

func (s *Strings) Set(value string) error

Set new value

func (*Strings) String

func (s *Strings) String() string

String to string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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