Skip to content

Wiki: easygen cli code-gen example by code #35

@suntong

Description

@suntong

The easygen provides a rich set of options to auto-generating Go code for command line parameter handling. Here are them in real code.

For built-in flag package

Sample Go flag package based code

Sample Go code:

package easygenapi
import (
"flag"
"fmt"
"os"
)
////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions
const progname = "easygen" // os.Args[0]
// The Options struct defines the structure to hold the commandline values
type Options struct {
HTML bool // treat the template file as html instead of text
TemplateStr string // template string (in text)
TemplateFile string // .tmpl (comma-separated) template file `name(s)` (default: same as .yaml file)
ExtYaml string // `extension` of yaml file
ExtTmpl string // `extension` of template file
StrFrom string // replace from, the from string used for the replace function
StrTo string // replace to, the to string used for the replace function
Debug int // debugging `level`
}
////////////////////////////////////////////////////////////////////////////
// Global variables definitions
// Opts holds the actual values from the command line parameters
var Opts Options
////////////////////////////////////////////////////////////////////////////
// Commandline definitions
func initVars() {
// set default values for command line parameters
flag.BoolVar(&Opts.HTML, "html", false,
"treat the template file as html instead of text")
flag.StringVar(&Opts.TemplateStr, "ts", "",
"template string (in text)")
flag.StringVar(&Opts.TemplateFile, "f", "",
".tmpl (comma-separated) template file `name(s)` (default: same as .yaml file)")
flag.StringVar(&Opts.TemplateFile, "tf", "",
".tmpl (comma-separated) template file `name(s)` (default: same as .yaml file)")
flag.StringVar(&Opts.ExtYaml, "ey", ".yaml",
"`extension` of yaml file")
flag.StringVar(&Opts.ExtTmpl, "et", ".tmpl",
"`extension` of template file")
flag.StringVar(&Opts.StrFrom, "rf", "",
"replace from, the from string used for the replace function")
flag.StringVar(&Opts.StrTo, "rt", "",
"replace to, the to string used for the replace function")
flag.IntVar(&Opts.Debug, "d", 0,
"debugging `level`")
flag.IntVar(&Opts.Debug, "debug", 0,
"debugging `level`")
}
func initVals() {
exists := false
// Now override those default values from environment variables
if _, exists = os.LookupEnv("EASYGEN_HTML"); Opts.HTML|| exists {
Opts.HTML = true
}
if len(Opts.TemplateStr) == 0 ||
len(os.Getenv("EASYGEN_TS")) != 0 {
Opts.TemplateStr = os.Getenv("EASYGEN_TS")
}
if len(Opts.TemplateFile) == 0 ||
len(os.Getenv("EASYGEN_F")) != 0 {
Opts.TemplateFile = os.Getenv("EASYGEN_F")
}
if len(Opts.TemplateFile) == 0 ||
len(os.Getenv("EASYGEN_TF")) != 0 {
Opts.TemplateFile = os.Getenv("EASYGEN_TF")
}
if len(Opts.ExtYaml) == 0 ||
len(os.Getenv("EASYGEN_EY")) != 0 {
Opts.ExtYaml = os.Getenv("EASYGEN_EY")
}
if len(Opts.ExtTmpl) == 0 ||
len(os.Getenv("EASYGEN_ET")) != 0 {
Opts.ExtTmpl = os.Getenv("EASYGEN_ET")
}
if len(Opts.StrFrom) == 0 ||
len(os.Getenv("EASYGEN_RF")) != 0 {
Opts.StrFrom = os.Getenv("EASYGEN_RF")
}
if len(Opts.StrTo) == 0 ||
len(os.Getenv("EASYGEN_RT")) != 0 {
Opts.StrTo = os.Getenv("EASYGEN_RT")
}
}
// Usage function shows help on commandline usage
func Usage() {
fmt.Fprintf(os.Stderr,
"\nUsage:\n %s [flags] YamlFileName [YamlFileName...]\n\nFlags:\n\n",
progname)
flag.PrintDefaults()
fmt.Fprintf(os.Stderr,
"\nYamlFileName(s): The name for the .yaml data and .tmpl template file\n\tOnly the name part, without extension. Can include the path as well.\n")
os.Exit(0)
}

Which is generated from this YAML file:

# program name, name for the executable
ProgramName: easygen
# package name
# - For standalone program that does not belong to any package, e.g.,
# https://github.com/suntong/easygen/blob/7791e4f0e5605543d27da1671a21376cdb9dcf2a/easygen/easygen.go
# just ignore the first line, the `package` output, and copy the rest
# - If you don't mind using a separated file to handle commandline paramters,
# then name the package as "main". see the spin-out "TF-minus1.go" file under
# https://github.com/suntong/easygen/tree/d1ab0b5fe80ddac57fe9ef51f6ccb3ab998cd5ee
# - If you are using it in a pacakge, look no further than
# https://github.com/suntong/easygen/blob/master/easygenapi/config.go
# which was a direct dump: easygen test/commandlineFlag | gofmt > easygenapi/config.go
#
PackageName: easygenapi
# Name of the structure to hold the values for/from commandline
StructName: Options
# The actual variable that hold the commandline paramter values
StructVar: Opts
Options:
- Name: HTML
Type: bool
Flag: html
Value: false
Usage: treat the template file as html instead of text
- Name: TemplateStr
Type: string
Flag: ts
Value: '""'
Usage: "template string (in text)"
- Name: TemplateFile
Type: string
Flag: f,tf
Value: '""'
Usage: ".tmpl (comma-separated) template file `name(s)` (default: same as .yaml file)"
- Name: ExtYaml
Type: string
Flag: ey
Value: '".yaml"'
Usage: "`extension` of yaml file"
- Name: ExtTmpl
Type: string
Flag: et
Value: '".tmpl"'
Usage: "`extension` of template file"
- Name: StrFrom
Type: string
Flag: rf
Value: '""'
Usage: "replace from, the from string used for the replace function"
- Name: StrTo
Type: string
Flag: rt
Value: '""'
Usage: "replace to, the to string used for the replace function"
- Name: Debug
Type: int
Flag: d,debug
Value: 0
Usage: "debugging `level`"
# Whether to use the USAGE_SUMMARY in Usage help
UsageSummary: ""
UsageLead: "\\nUsage:\\n %s [flags] YamlFileName [YamlFileName...]\\n\\nFlags:\\n\\n"
UsageEnd: "\\nYamlFileName(s): The name for the .yaml data and .tmpl template file\\n\\tOnly the name part, without extension. Can include the path as well.\\n"

For easygen itself using the built-in flag package

// !!! !!!
// WARNING: Code automatically generated. Editing discouraged.
// !!! !!!
package main
import (
"flag"
"fmt"
"os"
"github.com/go-easygen/easygen"
)
////////////////////////////////////////////////////////////////////////////
// Constant and data type/structure definitions
//const progname = "easygen" // os.Args[0]
////////////////////////////////////////////////////////////////////////////
// Global variables definitions
////////////////////////////////////////////////////////////////////////////
// Commandline definitions
func init() {
// set default values for command line parameters
flag.StringVar(&easygen.Opts.TemplateStr, "ts", "",
"template string (in text)")
flag.StringVar(&easygen.Opts.ExtYaml, "ey", ".yaml",
"`extension` of yaml file")
flag.StringVar(&easygen.Opts.ExtJson, "ej", ".json",
"`extension` of json file")
flag.StringVar(&easygen.Opts.ExtTmpl, "et", ".tmpl",
"`extension` of template file")
flag.IntVar(&easygen.Opts.Debug, "debug", 0,
"debugging `level`")
// Now override those default values from environment variables
if len(easygen.Opts.TemplateStr) == 0 ||
len(os.Getenv("EASYGEN_TS")) != 0 {
easygen.Opts.TemplateStr = os.Getenv("EASYGEN_TS")
}
if len(easygen.Opts.ExtYaml) == 0 ||
len(os.Getenv("EASYGEN_EY")) != 0 {
easygen.Opts.ExtYaml = os.Getenv("EASYGEN_EY")
}
if len(easygen.Opts.ExtJson) == 0 ||
len(os.Getenv("EASYGEN_EJ")) != 0 {
easygen.Opts.ExtJson = os.Getenv("EASYGEN_EJ")
}
if len(easygen.Opts.ExtTmpl) == 0 ||
len(os.Getenv("EASYGEN_ET")) != 0 {
easygen.Opts.ExtTmpl = os.Getenv("EASYGEN_ET")
}
}
// Usage function shows help on commandline usage
func Usage() {
fmt.Fprintf(os.Stderr,
"%s version %s\n\nUsage:\n %s [flags] template_name [data_filename [data_filename...]]\n\nFlags:\n\n",
progname, version, progname)
flag.PrintDefaults()
fmt.Fprintf(os.Stderr,
`
template_name: The name for the template file.
- Can have the extension (specified by -et) or without it.
- Can include the path as well.
- Can be a comma-separated list giving many template files, in which case
at least one data_filename must be given.
data_filename(s): The name for the .yaml or .json data.
- If omitted derive from the template_name.
- Can have the extension or without it. If withot extension,
will try the .yaml file first then .json
- Can include the path as well.
- If there is a single data_filename, and it is "-",
then read the data (.yaml or .json format) from stdin.
Flag defaults can be overridden by corresponding environment variable, e.g.:
EASYGEN_EY=.yml EASYGEN_ET=.tpl easygen ...
`)
os.Exit(0)
}

Which is generated from this YAML file:

# program name, name for the executable
ProgramName: easygen
# package name
# - For standalone program that does not belong to any package, e.g.,
# https://github.com/suntong/easygen/blob/7791e4f0e5605543d27da1671a21376cdb9dcf2a/easygen/easygen.go
# just ignore the first line, the `package` output, and copy the rest
# - If you don't mind using a separated file to handle commandline paramters,
# then name the package as "main". see the spin-out "TF-minus1.go" file under
# https://github.com/suntong/easygen/tree/d1ab0b5fe80ddac57fe9ef51f6ccb3ab998cd5ee
# - If you are using it in a pacakge, look no further than
# https://github.com/suntong/easygen/blob/master/easygenapi/config.go
# which was a direct dump: easygen test/commandlineFlag | gofmt > easygenapi/config.go
#
PackageName: easygen
# Name of the structure to hold the values for/from commandline
StructName: Options
# The actual variable that hold the commandline paramter values
StructVar: Opts
Options:
- Name: TemplateStr
Type: string
Flag: ts
Value: '""'
Usage: "template string (in text)"
- Name: ExtYaml
Type: string
Flag: ey
Value: '".yaml"'
Usage: "`extension` of yaml file"
- Name: ExtJson
Type: string
Flag: ej
Value: '".json"'
Usage: "`extension` of json file"
- Name: ExtTmpl
Type: string
Flag: et
Value: '".tmpl"'
Usage: "`extension` of template file"
- Name: Debug
Type: int
Flag: debug
Value: 0
Usage: "debugging `level`"
# Whether to use the USAGE_SUMMARY in Usage help
UsageSummary: ""
UsageLead: "\\nUsage:\\n %s [flags] template_name [data_filename [data_filename...]]\\n\\nFlags:\\n\\n"
UsageEnd: |
template_name: The name for the template file.
- Can have the extension (specified by -et) or without it.
- Can include the path as well.
- Can be a comma-separated list giving many template files, in which case
at least one data_filename must be given.
data_filename(s): The name for the .yaml or .json data.
- If omitted derive from the template_name.
- Can have the extension or without it. If withot extension,
will try the .yaml file first then .json
- Can include the path as well.
- If there is a single data_filename, and it is "-",
then read the data (.yaml or .json format) from stdin.
Flag defaults can be overridden by corresponding environment variable, e.g.:
EASYGEN_EY=.yml EASYGEN_ET=.tpl easygen ...

For ffcvt using the built-in flag package

This is by far the longest command line parameter handling code I've ever built --
https://github.com/suntong/ffcvt/blob/master/config.go
and it is built by easygen automatically as well.

For the viper package

Sample Go code:

flags.Bool("debug", false, "Turn on debugging.")
viper.BindPFlag("debug", flags.Lookup("debug"))
flags.String("addr", "localhost:5002", "Address of the service.")
viper.BindPFlag("addr", flags.Lookup("addr"))
flags.String("smtp-addr", "localhost:25", "Address of the SMTP server.")
viper.BindPFlag("smtp-addr", flags.Lookup("smtp-addr"))
flags.String("smtp-user", "", "User for the SMTP server.")
viper.BindPFlag("smtp-user", flags.Lookup("smtp-user"))
flags.String("smtp-password", "", "Password for the SMTP server.")
viper.BindPFlag("smtp-password", flags.Lookup("smtp-password"))
flags.String("email-from", "[email protected]", "The from email address.")
viper.BindPFlag("email-from", flags.Lookup("email-from"))

Which is generated from this YAML file:

Options:
- Name: debug
Type: Bool
Value: false
Usage: Turn on debugging.
- Name: addr
Type: String
Value: '"localhost:5002"'
Usage: Address of the service.
- Name: smtp-addr
Type: String
Value: '"localhost:25"'
Usage: Address of the SMTP server.
- Name: smtp-user
Type: String
Value: '""'
Usage: User for the SMTP server.
- Name: smtp-password
Type: String
Value: '""'
Usage: Password for the SMTP server.
- Name: email-from
Type: String
Value: '"[email protected]"'
Usage: The from email address.

For the cli package

Sample cli package based code 1

Sample Go code:

// -*- go -*-
////////////////////////////////////////////////////////////////////////////
// Program: gogo
// Purpose: Golang package manager
////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/mkideal/cli"
)
var app = &cli.Register(&cli.Command{
Name: "gogo",
Desc: "Golang package manager",
Text: " gogo is a new golang package manager\n very very good",
Argv: func() interface{} { return new(gogoT) },
Fn: gogo,
NumArg: cli.ExactN(1),
})
type gogoT struct {
cli.Helper
Version bool `cli:"v,version" usage:"display version"`
List bool `cli:"l,list" usage:"list all sub commands or not"`
}
func gogo(ctx *cli.Context) error {
argv := ctx.Argv().(*gogoT)
ctx.String("%s: %v", ctx.Path(), jsonIndent(argv))
ctx.String("[gogo]: %v\n", ctx.Args())
return nil
}
////////////////////////////////////////////////////////////////////////////
// Program: build
// Purpose: Build golang application
////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/mkideal/cli"
)
var buildCmd = app.Register(&cli.Command{
Name: "build",
Desc: "Build golang application",
Text: "Usage:\n gogo build [Options] Arch(i386|amd64)",
Argv: func() interface{} { return new(buildT) },
Fn: build,
NumArg: cli.ExactN(1),
CanSubRoute: true,
})
type buildT struct {
cli.Helper
Dir string `cli:"dir" usage:"source code root dir" dft:"./"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
}
func build(ctx *cli.Context) error {
argv := ctx.Argv().(*buildT)
ctx.String("%s: %v", ctx.Path(), jsonIndent(argv))
ctx.String("[build]: %v\n", ctx.Args())
return nil
}
////////////////////////////////////////////////////////////////////////////
// Program: install
// Purpose: Install golang application
////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/mkideal/cli"
)
var installCmd = app.Register(&cli.Command{
Name: "install",
Desc: "Install golang application",
Text: "Usage:\n gogo install [Options] package [package...]",
Argv: func() interface{} { return new(installT) },
Fn: install,
NumArg: cli.AtLeast(1),
CanSubRoute: true,
})
type installT struct {
cli.Helper
Dir string `cli:"dir" usage:"source code root dir" dft:"./"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
}
func install(ctx *cli.Context) error {
argv := ctx.Argv().(*installT)
ctx.String("%s: %v", ctx.Path(), jsonIndent(argv))
ctx.String("[install]: %v\n", ctx.Args())
return nil
}
////////////////////////////////////////////////////////////////////////////
// Program: publish
// Purpose: Publish golang application
////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/mkideal/cli"
)
var publishCmd = app.Register(&cli.Command{
Name: "publish",
Desc: "Publish golang application",
Argv: func() interface{} { return new(publishT) },
Fn: publish,
})
type publishT struct {
cli.Helper
Dir string `cli:"dir" usage:"source code root dir" dft:"./"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
List bool `cli:"l,list" usage:"list all sub commands"`
}
func publish(ctx *cli.Context) error {
argv := ctx.Argv().(*publishT)
ctx.String("%s: %v", ctx.Path(), jsonIndent(argv))
ctx.String("[publish]: %v\n", ctx.Args())
return nil
}

Which is generated from this YAML file:

# program name, name for the executable
ProgramName: gogo
# package name
# - For standalone program that does not belong to any package, e.g.,
# https://github.com/suntong/easygen/blob/7791e4f0e5605543d27da1671a21376cdb9dcf2a/easygen/easygen.go
# just ignore the first line, the `package` output, and copy the rest
# - If you don't mind using a separated file to handle commandline paramters,
# then name the package as "main". see the spin-out "TF-minus1.go" file under
# https://github.com/suntong/easygen/tree/d1ab0b5fe80ddac57fe9ef51f6ccb3ab998cd5ee
# - If you are using it in a pacakge, look no further than
# https://github.com/suntong/easygen/blob/master/easygenapi/config.go
# which was a direct dump: easygen test/commandlineFlag | gofmt > easygenapi/config.go
#
PackageName: main
Name: gogo
Var: app
Desc: "Golang package manager"
Text: ' gogo is a new golang package manager\n very very good'
NumArg: cli.ExactN(1)
Options:
- Name: Version
Type: bool
Flag: v,version
Usage: display version
- Name: List
Type: bool
Flag: l,list
Usage: list all sub commands or not
Command:
- Name: build
Desc: "Build golang application"
Text: 'Usage:\n gogo build [Options] Arch(i386|amd64)'
NumArg: cli.ExactN(1)
Options:
- Name: Dir
Type: string
Flag: dir
Value: '"./"'
Usage: source code root dir
- Name: Suffix
Type: string
Flag: suffix
Value: '".go,.c,.s"'
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: install
Desc: "Install golang application"
Text: 'Usage:\n gogo install [Options] package [package...]'
NumArg: cli.AtLeast(1)
Options:
- Name: Dir
Type: string
Flag: dir
Value: '"./"'
Usage: source code root dir
- Name: Suffix
Type: string
Flag: suffix
Value: '".go,.c,.s"'
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: publish
Desc: "Publish golang application"
Options:
- Name: Dir
Type: string
Flag: dir
Value: '"./"'
Usage: source code root dir
- Name: Suffix
Type: string
Flag: suffix
Value: '".go,.c,.s"'
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: List
Type: bool
Flag: l,list
Usage: "list all sub commands"

Sample cli package based code 2

Sample Go code 2:

// -*- go -*-
////////////////////////////////////////////////////////////////////////////
// Program: redo
// Purpose: global option redo
////////////////////////////////////////////////////////////////////////////
package main
import (
"github.com/mkideal/cli"
)
////////////////////////////////////////////////////////////////////////////
// redo
type rootT struct {
cli.Helper
Self *rootT `cli:"c,config" usage:"config file" json:"-" parser:"jsonfile" dft:"redo.json"`
Host string `cli:"H,host" usage:"host address" dft:"$HOST"`
Port int `cli:"p,port" usage:"listening port" dft:"80"`
}
var root = &cli.Command{
Name: "redo",
Desc: "global option redo",
Text: " redo global option via automatic code-gen",
Global: true,
Argv: func() interface{} { t := new(rootT); t.Self = t; return t },
Fn: redo,
NumArg: cli.ExactN(1),
}
// func main() {
// cli.SetUsageStyle(cli.ManualStyle) // up-down, for left-right, use NormalStyle
// //NOTE: You can set any writer implements io.Writer
// // default writer is os.Stdout
// if err := cli.Root(root,
// cli.Tree(buildDef),
// cli.Tree(installDef),
// cli.Tree(publishDef)).Run(os.Args[1:]); err != nil {
// fmt.Fprintln(os.Stderr, err)
// }
// fmt.Println("")
// }
// func redo(ctx *cli.Context) error {
// ctx.JSON(ctx.RootArgv())
// ctx.JSON(ctx.Argv())
// fmt.Println()
// return nil
// }
////////////////////////////////////////////////////////////////////////////
// build
// func buildCLI(ctx *cli.Context) error {
// rootArgv := ctx.RootArgv().(*rootT)
// argv := ctx.Argv().(*buildT)
// fmt.Printf("[build]:\n %+v\n %+v\n %v\n", rootArgv, argv, ctx.Args())
// return nil
// }
type buildT struct {
Dir string `cli:"dir" usage:"source code root dir" dft:"./"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
}
var buildDef = &cli.Command{
Name: "build",
Desc: "Build the network application",
Text: "Usage:\n redo build [Options] Arch(i386|amd64)",
Argv: func() interface{} { return new(buildT) },
Fn: buildCLI,
NumArg: cli.ExactN(1),
CanSubRoute: true,
}
////////////////////////////////////////////////////////////////////////////
// install
// func installCLI(ctx *cli.Context) error {
// rootArgv := ctx.RootArgv().(*rootT)
// argv := ctx.Argv().(*installT)
// fmt.Printf("[install]:\n %+v\n %+v\n %v\n", rootArgv, argv, ctx.Args())
// return nil
// }
type installT struct {
Dir string `cli:"dir" usage:"source code root dir" dft:"./"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
}
var installDef = &cli.Command{
Name: "install",
Desc: "Install the network application",
Text: "Usage:\n redo install [Options] package [package...]",
Argv: func() interface{} { return new(installT) },
Fn: installCLI,
NumArg: cli.AtLeast(1),
CanSubRoute: true,
}
////////////////////////////////////////////////////////////////////////////
// publish
// func publishCLI(ctx *cli.Context) error {
// rootArgv := ctx.RootArgv().(*rootT)
// argv := ctx.Argv().(*publishT)
// fmt.Printf("[publish]:\n %+v\n %+v\n %v\n", rootArgv, argv, ctx.Args())
// return nil
// }
type publishT struct {
Dir string `cli:"*d,dir" usage:"publish dir"`
Suffix string `cli:"suffix" usage:"source file suffix" dft:".go,.c,.s"`
Out string `cli:"o,out" usage:"output filename"`
List bool `cli:"l,list" usage:"list all sub commands"`
}
var publishDef = &cli.Command{
Name: "publish",
Desc: "Publish the network application",
Argv: func() interface{} { return new(publishT) },
Fn: publishCLI,
NumOption: cli.AtLeast(1),
}

This is my current way of generating cli package based command line parameter handling code.

It is generated from this YAML file:

# program name, name for the executable
ProgramName: redo
# package name
# - For standalone program that does not belong to any package, e.g.,
# https://github.com/suntong/easygen/blob/7791e4f0e5605543d27da1671a21376cdb9dcf2a/easygen/easygen.go
# just ignore the first line, the `package` output, and copy the rest
# - If you don't mind using a separated file to handle commandline paramters,
# then name the package as "main". see the spin-out "TF-minus1.go" file under
# https://github.com/suntong/easygen/tree/d1ab0b5fe80ddac57fe9ef51f6ccb3ab998cd5ee
# - If you are using it in a pacakge, look no further than
# https://github.com/suntong/easygen/blob/master/easygenapi/config.go
# which was a direct dump: easygen test/commandlineFlag | gofmt > easygenapi/config.go
#
PackageName: main
Name: redo
Desc: "global option redo"
Text: ' redo global option via automatic code-gen'
Global: true
NumArg: cli.ExactN(1)
Self: true
Options:
- Name: Self
Type: '*rootT'
Flag: c,config
Usage: config file
Value: redo.json
- Name: Host
Type: string
Flag: H,host
Usage: host address
Value: "$HOST"
- Name: Port
Type: int
Flag: p,port
Usage: listening port
Value: 80
Command:
- Name: build
Desc: "Build the network application"
Text: 'Usage:\n redo build [Options] Arch(i386|amd64)'
NumArg: cli.ExactN(1)
Options:
- Name: Dir
Type: string
Flag: dir
Value: "./"
Usage: source code root dir
- Name: Suffix
Type: string
Flag: suffix
Value: ".go,.c,.s"
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: install
Desc: "Install the network application"
Text: 'Usage:\n redo install [Options] package [package...]'
NumArg: cli.AtLeast(1)
Options:
- Name: Dir
Type: string
Flag: dir
Value: "./"
Usage: source code root dir
- Name: Suffix
Type: string
Flag: suffix
Value: ".go,.c,.s"
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: publish
Desc: "Publish the network application"
NumOption: cli.AtLeast(1)
Options:
- Name: Dir
Type: string
Flag: '*d,dir'
Usage: publish dir
- Name: Suffix
Type: string
Flag: suffix
Value: ".go,.c,.s"
Usage: "source file suffix"
- Name: Out
Type: string
Flag: o,out
Usage: "output filename"
- Name: List
Type: bool
Flag: l,list
Usage: "list all sub commands"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions