361 lines
9.3 KiB
Markdown
361 lines
9.3 KiB
Markdown
|
### Version Flag
|
|||
|
|
|||
|
The default version flag (`-v/--version`) is defined as `cli.VersionFlag`, which
|
|||
|
is checked by the cli internals in order to print the `App.Version` via
|
|||
|
`cli.VersionPrinter` and break execution.
|
|||
|
|
|||
|
#### Customization
|
|||
|
|
|||
|
The default flag may be customized to something other than `-v/--version` by
|
|||
|
setting `cli.VersionFlag`, e.g.:
|
|||
|
|
|||
|
<!-- {
|
|||
|
"args": ["--print-version"],
|
|||
|
"output": "partay version 19\\.99\\.0"
|
|||
|
} -->
|
|||
|
``` go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"log"
|
|||
|
"os"
|
|||
|
|
|||
|
"github.com/urfave/cli"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
cli.VersionFlag = cli.BoolFlag{
|
|||
|
Name: "print-version, V",
|
|||
|
Usage: "print only the version",
|
|||
|
}
|
|||
|
|
|||
|
app := cli.NewApp()
|
|||
|
app.Name = "partay"
|
|||
|
app.Version = "19.99.0"
|
|||
|
err := app.Run(os.Args)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Alternatively, the version printer at `cli.VersionPrinter` may be overridden, e.g.:
|
|||
|
|
|||
|
<!-- {
|
|||
|
"args": ["--version"],
|
|||
|
"output": "version=19\\.99\\.0 revision=fafafaf"
|
|||
|
} -->
|
|||
|
``` go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"log"
|
|||
|
"os"
|
|||
|
|
|||
|
"github.com/urfave/cli"
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
Revision = "fafafaf"
|
|||
|
)
|
|||
|
|
|||
|
func main() {
|
|||
|
cli.VersionPrinter = func(c *cli.Context) {
|
|||
|
fmt.Printf("version=%s revision=%s\n", c.App.Version, Revision)
|
|||
|
}
|
|||
|
|
|||
|
app := cli.NewApp()
|
|||
|
app.Name = "partay"
|
|||
|
app.Version = "19.99.0"
|
|||
|
err := app.Run(os.Args)
|
|||
|
if err != nil {
|
|||
|
log.Fatal(err)
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
#### Full API Example
|
|||
|
|
|||
|
**Notice**: This is a contrived (functioning) example meant strictly for API
|
|||
|
demonstration purposes. Use of one's imagination is encouraged.
|
|||
|
|
|||
|
<!-- {
|
|||
|
"output": "made it!\nPhew!"
|
|||
|
} -->
|
|||
|
``` go
|
|||
|
package main
|
|||
|
|
|||
|
import (
|
|||
|
"errors"
|
|||
|
"flag"
|
|||
|
"fmt"
|
|||
|
"io"
|
|||
|
"io/ioutil"
|
|||
|
"os"
|
|||
|
"time"
|
|||
|
|
|||
|
"github.com/urfave/cli"
|
|||
|
)
|
|||
|
|
|||
|
func init() {
|
|||
|
cli.AppHelpTemplate += "\nCUSTOMIZED: you bet ur muffins\n"
|
|||
|
cli.CommandHelpTemplate += "\nYMMV\n"
|
|||
|
cli.SubcommandHelpTemplate += "\nor something\n"
|
|||
|
|
|||
|
cli.HelpFlag = cli.BoolFlag{Name: "halp"}
|
|||
|
cli.BashCompletionFlag = cli.BoolFlag{Name: "compgen", Hidden: true}
|
|||
|
cli.VersionFlag = cli.BoolFlag{Name: "print-version, V"}
|
|||
|
|
|||
|
cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) {
|
|||
|
fmt.Fprintf(w, "best of luck to you\n")
|
|||
|
}
|
|||
|
cli.VersionPrinter = func(c *cli.Context) {
|
|||
|
fmt.Fprintf(c.App.Writer, "version=%s\n", c.App.Version)
|
|||
|
}
|
|||
|
cli.OsExiter = func(c int) {
|
|||
|
fmt.Fprintf(cli.ErrWriter, "refusing to exit %d\n", c)
|
|||
|
}
|
|||
|
cli.ErrWriter = ioutil.Discard
|
|||
|
cli.FlagStringer = func(fl cli.Flag) string {
|
|||
|
return fmt.Sprintf("\t\t%s", fl.GetName())
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
type hexWriter struct{}
|
|||
|
|
|||
|
func (w *hexWriter) Write(p []byte) (int, error) {
|
|||
|
for _, b := range p {
|
|||
|
fmt.Printf("%x", b)
|
|||
|
}
|
|||
|
fmt.Printf("\n")
|
|||
|
|
|||
|
return len(p), nil
|
|||
|
}
|
|||
|
|
|||
|
type genericType struct{
|
|||
|
s string
|
|||
|
}
|
|||
|
|
|||
|
func (g *genericType) Set(value string) error {
|
|||
|
g.s = value
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
func (g *genericType) String() string {
|
|||
|
return g.s
|
|||
|
}
|
|||
|
|
|||
|
func main() {
|
|||
|
app := cli.NewApp()
|
|||
|
app.Name = "kənˈtrīv"
|
|||
|
app.Version = "19.99.0"
|
|||
|
app.Compiled = time.Now()
|
|||
|
app.Authors = []cli.Author{
|
|||
|
cli.Author{
|
|||
|
Name: "Example Human",
|
|||
|
Email: "human@example.com",
|
|||
|
},
|
|||
|
}
|
|||
|
app.Copyright = "(c) 1999 Serious Enterprise"
|
|||
|
app.HelpName = "contrive"
|
|||
|
app.Usage = "demonstrate available API"
|
|||
|
app.UsageText = "contrive - demonstrating the available API"
|
|||
|
app.ArgsUsage = "[args and such]"
|
|||
|
app.Commands = []cli.Command{
|
|||
|
cli.Command{
|
|||
|
Name: "doo",
|
|||
|
Aliases: []string{"do"},
|
|||
|
Category: "motion",
|
|||
|
Usage: "do the doo",
|
|||
|
UsageText: "doo - does the dooing",
|
|||
|
Description: "no really, there is a lot of dooing to be done",
|
|||
|
ArgsUsage: "[arrgh]",
|
|||
|
Flags: []cli.Flag{
|
|||
|
cli.BoolFlag{Name: "forever, forevvarr"},
|
|||
|
},
|
|||
|
Subcommands: cli.Commands{
|
|||
|
cli.Command{
|
|||
|
Name: "wop",
|
|||
|
Action: wopAction,
|
|||
|
},
|
|||
|
},
|
|||
|
SkipFlagParsing: false,
|
|||
|
HideHelp: false,
|
|||
|
Hidden: false,
|
|||
|
HelpName: "doo!",
|
|||
|
BashComplete: func(c *cli.Context) {
|
|||
|
fmt.Fprintf(c.App.Writer, "--better\n")
|
|||
|
},
|
|||
|
Before: func(c *cli.Context) error {
|
|||
|
fmt.Fprintf(c.App.Writer, "brace for impact\n")
|
|||
|
return nil
|
|||
|
},
|
|||
|
After: func(c *cli.Context) error {
|
|||
|
fmt.Fprintf(c.App.Writer, "did we lose anyone?\n")
|
|||
|
return nil
|
|||
|
},
|
|||
|
Action: func(c *cli.Context) error {
|
|||
|
c.Command.FullName()
|
|||
|
c.Command.HasName("wop")
|
|||
|
c.Command.Names()
|
|||
|
c.Command.VisibleFlags()
|
|||
|
fmt.Fprintf(c.App.Writer, "dodododododoodododddooooododododooo\n")
|
|||
|
if c.Bool("forever") {
|
|||
|
c.Command.Run(c)
|
|||
|
}
|
|||
|
return nil
|
|||
|
},
|
|||
|
OnUsageError: func(c *cli.Context, err error, isSubcommand bool) error {
|
|||
|
fmt.Fprintf(c.App.Writer, "for shame\n")
|
|||
|
return err
|
|||
|
},
|
|||
|
},
|
|||
|
}
|
|||
|
app.Flags = []cli.Flag{
|
|||
|
cli.BoolFlag{Name: "fancy"},
|
|||
|
cli.BoolTFlag{Name: "fancier"},
|
|||
|
cli.DurationFlag{Name: "howlong, H", Value: time.Second * 3},
|
|||
|
cli.Float64Flag{Name: "howmuch"},
|
|||
|
cli.GenericFlag{Name: "wat", Value: &genericType{}},
|
|||
|
cli.Int64Flag{Name: "longdistance"},
|
|||
|
cli.Int64SliceFlag{Name: "intervals"},
|
|||
|
cli.IntFlag{Name: "distance"},
|
|||
|
cli.IntSliceFlag{Name: "times"},
|
|||
|
cli.StringFlag{Name: "dance-move, d"},
|
|||
|
cli.StringSliceFlag{Name: "names, N"},
|
|||
|
cli.UintFlag{Name: "age"},
|
|||
|
cli.Uint64Flag{Name: "bigage"},
|
|||
|
}
|
|||
|
app.EnableBashCompletion = true
|
|||
|
app.UseShortOptionHandling = true
|
|||
|
app.HideHelp = false
|
|||
|
app.HideVersion = false
|
|||
|
app.BashComplete = func(c *cli.Context) {
|
|||
|
fmt.Fprintf(c.App.Writer, "lipstick\nkiss\nme\nlipstick\nringo\n")
|
|||
|
}
|
|||
|
app.Before = func(c *cli.Context) error {
|
|||
|
fmt.Fprintf(c.App.Writer, "HEEEERE GOES\n")
|
|||
|
return nil
|
|||
|
}
|
|||
|
app.After = func(c *cli.Context) error {
|
|||
|
fmt.Fprintf(c.App.Writer, "Phew!\n")
|
|||
|
return nil
|
|||
|
}
|
|||
|
app.CommandNotFound = func(c *cli.Context, command string) {
|
|||
|
fmt.Fprintf(c.App.Writer, "Thar be no %q here.\n", command)
|
|||
|
}
|
|||
|
app.OnUsageError = func(c *cli.Context, err error, isSubcommand bool) error {
|
|||
|
if isSubcommand {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
fmt.Fprintf(c.App.Writer, "WRONG: %#v\n", err)
|
|||
|
return nil
|
|||
|
}
|
|||
|
app.Action = func(c *cli.Context) error {
|
|||
|
cli.DefaultAppComplete(c)
|
|||
|
cli.HandleExitCoder(errors.New("not an exit coder, though"))
|
|||
|
cli.ShowAppHelp(c)
|
|||
|
cli.ShowCommandCompletions(c, "nope")
|
|||
|
cli.ShowCommandHelp(c, "also-nope")
|
|||
|
cli.ShowCompletions(c)
|
|||
|
cli.ShowSubcommandHelp(c)
|
|||
|
cli.ShowVersion(c)
|
|||
|
|
|||
|
categories := c.App.Categories()
|
|||
|
categories.AddCommand("sounds", cli.Command{
|
|||
|
Name: "bloop",
|
|||
|
})
|
|||
|
|
|||
|
for _, category := range c.App.Categories() {
|
|||
|
fmt.Fprintf(c.App.Writer, "%s\n", category.Name)
|
|||
|
fmt.Fprintf(c.App.Writer, "%#v\n", category.Commands)
|
|||
|
fmt.Fprintf(c.App.Writer, "%#v\n", category.VisibleCommands())
|
|||
|
}
|
|||
|
|
|||
|
fmt.Printf("%#v\n", c.App.Command("doo"))
|
|||
|
if c.Bool("infinite") {
|
|||
|
c.App.Run([]string{"app", "doo", "wop"})
|
|||
|
}
|
|||
|
|
|||
|
if c.Bool("forevar") {
|
|||
|
c.App.RunAsSubcommand(c)
|
|||
|
}
|
|||
|
c.App.Setup()
|
|||
|
fmt.Printf("%#v\n", c.App.VisibleCategories())
|
|||
|
fmt.Printf("%#v\n", c.App.VisibleCommands())
|
|||
|
fmt.Printf("%#v\n", c.App.VisibleFlags())
|
|||
|
|
|||
|
fmt.Printf("%#v\n", c.Args().First())
|
|||
|
if len(c.Args()) > 0 {
|
|||
|
fmt.Printf("%#v\n", c.Args()[1])
|
|||
|
}
|
|||
|
fmt.Printf("%#v\n", c.Args().Present())
|
|||
|
fmt.Printf("%#v\n", c.Args().Tail())
|
|||
|
|
|||
|
set := flag.NewFlagSet("contrive", 0)
|
|||
|
nc := cli.NewContext(c.App, set, c)
|
|||
|
|
|||
|
fmt.Printf("%#v\n", nc.Args())
|
|||
|
fmt.Printf("%#v\n", nc.Bool("nope"))
|
|||
|
fmt.Printf("%#v\n", nc.BoolT("nerp"))
|
|||
|
fmt.Printf("%#v\n", nc.Duration("howlong"))
|
|||
|
fmt.Printf("%#v\n", nc.Float64("hay"))
|
|||
|
fmt.Printf("%#v\n", nc.Generic("bloop"))
|
|||
|
fmt.Printf("%#v\n", nc.Int64("bonk"))
|
|||
|
fmt.Printf("%#v\n", nc.Int64Slice("burnks"))
|
|||
|
fmt.Printf("%#v\n", nc.Int("bips"))
|
|||
|
fmt.Printf("%#v\n", nc.IntSlice("blups"))
|
|||
|
fmt.Printf("%#v\n", nc.String("snurt"))
|
|||
|
fmt.Printf("%#v\n", nc.StringSlice("snurkles"))
|
|||
|
fmt.Printf("%#v\n", nc.Uint("flub"))
|
|||
|
fmt.Printf("%#v\n", nc.Uint64("florb"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalBool("global-nope"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalBoolT("global-nerp"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalDuration("global-howlong"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalFloat64("global-hay"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalGeneric("global-bloop"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalInt("global-bips"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalIntSlice("global-blups"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalString("global-snurt"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalStringSlice("global-snurkles"))
|
|||
|
|
|||
|
fmt.Printf("%#v\n", nc.FlagNames())
|
|||
|
fmt.Printf("%#v\n", nc.GlobalFlagNames())
|
|||
|
fmt.Printf("%#v\n", nc.GlobalIsSet("wat"))
|
|||
|
fmt.Printf("%#v\n", nc.GlobalSet("wat", "nope"))
|
|||
|
fmt.Printf("%#v\n", nc.NArg())
|
|||
|
fmt.Printf("%#v\n", nc.NumFlags())
|
|||
|
fmt.Printf("%#v\n", nc.Parent())
|
|||
|
|
|||
|
nc.Set("wat", "also-nope")
|
|||
|
|
|||
|
ec := cli.NewExitError("ohwell", 86)
|
|||
|
fmt.Fprintf(c.App.Writer, "%d", ec.ExitCode())
|
|||
|
fmt.Printf("made it!\n")
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
if os.Getenv("HEXY") != "" {
|
|||
|
app.Writer = &hexWriter{}
|
|||
|
app.ErrWriter = &hexWriter{}
|
|||
|
}
|
|||
|
|
|||
|
app.Metadata = map[string]interface{}{
|
|||
|
"layers": "many",
|
|||
|
"explicable": false,
|
|||
|
"whatever-values": 19.99,
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// ignore error so we don't exit non-zero and break gfmrun README example tests
|
|||
|
_ = app.Run(os.Args)
|
|||
|
}
|
|||
|
|
|||
|
func wopAction(c *cli.Context) error {
|
|||
|
fmt.Fprintf(c.App.Writer, ":wave: over here, eh\n")
|
|||
|
return nil
|
|||
|
}
|
|||
|
```
|