1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
package main
import (
"context"
"flag"
"fmt"
"os"
"github.com/peterbourgon/ff/v3/ffcli"
)
// textctl is a simple applications in which all commands are built up in func
// main. It demonstrates how to declare minimal commands, how to wire them
// together into a command tree, and one way to allow subcommands access to
// flags set in parent commands.
func main() {
var (
rootFlagSet = flag.NewFlagSet("textctl", flag.ExitOnError)
verbose = rootFlagSet.Bool("v", false, "increase log verbosity")
repeatFlagSet = flag.NewFlagSet("textctl repeat", flag.ExitOnError)
n = repeatFlagSet.Int("n", 3, "how many times to repeat")
)
repeat := &ffcli.Command{
Name: "repeat",
ShortUsage: "textctl repeat [-n times] <arg>",
ShortHelp: "Repeatedly print the argument to stdout.",
FlagSet: repeatFlagSet,
Exec: func(_ context.Context, args []string) error {
if n := len(args); n != 1 {
return fmt.Errorf("repeat requires exactly 1 argument, but you provided %d", n)
}
if *verbose {
fmt.Fprintf(os.Stderr, "repeat: will generate %dB of output\n", (*n)*len(args[0]))
}
for i := 0; i < *n; i++ {
fmt.Fprintf(os.Stdout, "%s\n", args[0])
}
return nil
},
}
count := &ffcli.Command{
Name: "count",
ShortUsage: "count [<arg> ...]",
ShortHelp: "Count the number of bytes in the arguments.",
Exec: func(_ context.Context, args []string) error {
if *verbose {
fmt.Fprintf(os.Stderr, "count: argument count %d\n", len(args))
}
var n int
for _, arg := range args {
n += len(arg)
}
fmt.Fprintf(os.Stdout, "%d\n", n)
return nil
},
}
root := &ffcli.Command{
ShortUsage: "textctl [flags] <subcommand>",
FlagSet: rootFlagSet,
Subcommands: []*ffcli.Command{repeat, count},
Exec: func(context.Context, []string) error {
return flag.ErrHelp
},
}
if err := root.ParseAndRun(context.Background(), os.Args[1:]); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
|