1package main
2
3import (
4	"fmt"
5	"os"
6
7	"gopkg.in/alecthomas/kingpin.v2"
8)
9
10func listHosts() []string {
11	// Provide a dynamic list of hosts from a hosts file or otherwise
12	// for bash completion. In this example we simply return static slice.
13
14	// You could use this functionality to reach into a hosts file to provide
15	// completion for a list of known hosts.
16	return []string{"sshhost.example", "webhost.example", "ftphost.example"}
17}
18
19type NetcatCommand struct {
20	hostName string
21	port     int
22	format   string
23}
24
25func (n *NetcatCommand) run(c *kingpin.ParseContext) error {
26	fmt.Printf("Would have run netcat to hostname %v, port %d, and output format %v\n", n.hostName, n.port, n.format)
27	return nil
28}
29
30func configureNetcatCommand(app *kingpin.Application) {
31	c := &NetcatCommand{}
32	nc := app.Command("nc", "Connect to a Host").Action(c.run)
33	nc.Flag("nop-flag", "Example of a flag with no options").Bool()
34
35	// You can provide hint options using a function to generate them
36	nc.Flag("host", "Provide a hostname to nc").
37		Required().
38		HintAction(listHosts).
39		StringVar(&c.hostName)
40
41	// You can provide hint options statically
42	nc.Flag("port", "Provide a port to connect to").
43		Required().
44		HintOptions("80", "443", "8080").
45		IntVar(&c.port)
46
47	// Enum/EnumVar options will be turned into completion options automatically
48	nc.Flag("format", "Define the output format").
49		Default("raw").
50		EnumVar(&c.format, "raw", "json")
51
52	// You can combine HintOptions with HintAction too
53	nc.Flag("host-with-multi", "Define a hostname").
54		HintAction(listHosts).
55		HintOptions("myhost.com").
56		String()
57
58	// And combine with themselves
59	nc.Flag("host-with-multi-options", "Define a hostname").
60		HintOptions("myhost.com").
61		HintOptions("myhost2.com").
62		String()
63
64	// If you specify HintOptions/HintActions for Enum/EnumVar, the options
65	// provided for Enum/EnumVar will be overridden.
66	nc.Flag("format-with-override-1", "Define a format").
67		HintAction(listHosts).
68		Enum("option1", "option2")
69
70	nc.Flag("format-with-override-2", "Define a format").
71		HintOptions("myhost.com", "myhost2.com").
72		Enum("option1", "option2")
73}
74
75func addSubCommand(app *kingpin.Application, name string, description string) {
76	c := app.Command(name, description).Action(func(c *kingpin.ParseContext) error {
77		fmt.Printf("Would have run command %s.\n", name)
78		return nil
79	})
80	c.Flag("nop-flag", "Example of a flag with no options").Bool()
81}
82
83func main() {
84	app := kingpin.New("completion", "My application with bash completion.")
85	app.Flag("flag-1", "").String()
86	app.Flag("flag-2", "").HintOptions("opt1", "opt2").String()
87
88	configureNetcatCommand(app)
89
90	// Add some additional top level commands
91	addSubCommand(app, "ls", "Additional top level command to show command completion")
92	addSubCommand(app, "ping", "Additional top level command to show command completion")
93	addSubCommand(app, "nmap", "Additional top level command to show command completion")
94
95	kingpin.MustParse(app.Parse(os.Args[1:]))
96}
97