-
Notifications
You must be signed in to change notification settings - Fork 11
/
urfave-cli-main.go
executable file
·182 lines (161 loc) · 4.91 KB
/
urfave-cli-main.go
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// [urfave-cli](https://github.com/urfave/cli) is a popular CLI package.
// In this example we will show how to use it to create flags, sub commands and
// act on them.
// godoc: [https://godoc.org/github.com/urfave/cli](https://godoc.org/github.com/urfave/cli)
package main
import (
"fmt"
"os"
// go get before using it
"github.com/urfave/cli"
)
var (
// Hold subcommands
cmds []cli.Command
// Hold flags
flags []cli.Flag
// Hold host
host string
// Hold port
port int
)
func init() {
// We will set flags, subcommands in init.
// Set flags
flags = []cli.Flag{
cli.StringFlag{
// Alternate flags are separated by commas.
// We can call -t, --t, -target, --host, etc.
Name: "t, target, host",
// Default value for flag (optional)
Value: "127.0.0.1",
// Default placeholder in -h usage string is set with ``:
// "-t HOST, --target HOST, --host HOST hacking HOST (default: "127.0.0.1")"
Usage: "hacking `HOST`",
// Variable to hold the value of flag
Destination: &host,
},
// IntFlag
cli.IntFlag{
Name: "p, port",
Value: 22,
Usage: "target `PORT`",
Destination: &port,
},
}
// Subcommands
cmds = []cli.Command{
{
// Name
Name: "hack",
// Aliases (similar to alternate flags) stored in a string slice
Aliases: []string{"haxorx", "pwn"},
// Usage text - using `` to create placeholders is not supported here
Usage: "hack target",
// Function to call when this sub command is activated
// Similar to app.Action, this function should be of type
// cli.ActionFunc == func (*cli.Context) error
Action: act,
// Subcommand category
Category: "Hacking",
},
{
Name: "crack",
Aliases: []string{"c"},
Usage: "crack target",
// It's possible to use the same function for different subcommands
// (they do not have to be in the same category) and then detect
// the command inside.
Action: act,
Category: "Hacking",
},
{
Name: "scan",
Aliases: []string{"s"},
Usage: "scan target",
// Different function for this subcommand.
Action: scan,
Category: "Recon",
},
}
}
func main() {
// Create a new app
app := cli.NewApp()
// Name of the program
app.Name = "AppName"
// Application usage
app.Usage = "application usage"
// Description
app.Description = "description two"
// Version - if not version "0.0.0" will be printed
app.Version = "1.2.3.4"
// We can hide version instead
app.HideVersion = true
// Author name
app.Author = "Author1"
// Author email
app.Email = "author1@example.com"
// For multiple authors we need to create a slice of cli.Author
// Author has two fields, Name and Email (both string)
// First Authors list will be printed and then Author
// AUTHORS:
// Author2 <author2@example.com>
// Author3 <author3@example.com>
// Author1 <author1@example.com>
app.Authors = []cli.Author{
{"Author2", "author2@example.com"},
{"Author3", "author3@example.com"},
}
// Set subcommands
app.Commands = cmds
// Set flags
app.Flags = flags
// This function will be called if no arguments are provided at runtime
// Expects type cli.ActionFunc == "func (*cli.Context) error"
app.Action = noArgs
// Run the app
app.Run(os.Args)
}
// noArgs will run if no arguments/flags are provided
func noArgs(c *cli.Context) error {
// Print app usage
cli.ShowAppHelp(c)
// It's possible to change the return status code and error here
// cli.NewExitError creates a a new error and the return status code for
// the application.
return cli.NewExitError("no commands provided", 2)
}
// act will detect the subcommand from c and print the appropriate message
// or subcommand help if applicable.
func act(c *cli.Context) error {
// Check for arguments after the subcommand
if c.Args().Present() {
// Get the next argument.Can also do c.Args().Get(0)
// c.NArgs() returns the number of arguments and can be used in a for
// along with .Get(i)
t := c.Args().First()
// c.Command.Name has command name and c.Command has a lot more [info](https://godoc.org/github.com/dkolbly/cli#Command)
// Knowing the subcommand we can call different functions here.
cmdName := c.Command.Name
fmt.Printf("%sing %s", cmdName, t)
return nil
}
// If there are no arguments, show help for that specific subcommands
// and then return with an error.
cli.ShowSubcommandHelp(c)
return cli.NewExitError("no arguments provided for subcommand", 3)
}
// scan will "scan" the target
func scan(c *cli.Context) error {
// Check for arguments after the subcommand
if c.Args().Present() {
// Get next argument (the target)
t := c.Args().First()
fmt.Println("scanning", t)
return nil
}
// Show scan subcommand help
cli.ShowSubcommandHelp(c)
return cli.NewExitError("no arguments provided for subcommand", 3)
}