1<p align="center">
2
3<img src="/logo.png" />
4<br />
5<a href="https://goreportcard.com/report/github.com/integrii/flaggy"><img src="https://goreportcard.com/badge/github.com/integrii/flaggy"></a>
6<a href="https://travis-ci.org/integrii/flaggy"><img src="https://travis-ci.org/integrii/flaggy.svg?branch=master"></a>
7<a href="http://godoc.org/github.com/integrii/flaggy"><img src="https://camo.githubusercontent.com/d48cccd1ce67ddf8ba7fc356ec1087f3f7aa6d12/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f6c696c65696f2f6c696c653f7374617475732e737667"></a>
8<a href="http://unlicense.org/"><img src="https://img.shields.io/badge/license-Unlicense-blue.svg"></a>
9<a href="https://cover.run/go?repo=github.com%2Fintegrii%2Fflaggy&tag=golang-1.10"><img src="https://cover.run/go/github.com/integrii/flaggy.svg?style=flat&tag=golang-1.10"></a>
10<a href="https://github.com/avelino/awesome-go"><img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg"></a>
11</p>
12
13Sensible and _fast_ command-line flag parsing with excellent support for **subcommands** and **positional values**. Flags can be at any position. Flaggy has no required project or package layout like [Cobra requires](https://github.com/spf13/cobra/issues/641), and **no external dependencies**!
14
15Check out the [godoc](http://godoc.org/github.com/integrii/flaggy), [examples directory](https://github.com/integrii/flaggy/tree/master/examples), and [examples in this readme](https://github.com/integrii/flaggy#super-simple-example) to get started quickly. You can also read the Flaggy introduction post with helpful examples [on my weblog](https://ericgreer.info/post/a-better-flags-package-for-go/).
16
17# Installation
18
19`go get -u github.com/integrii/flaggy`
20
21# Key Features
22
23- Very easy to use ([see examples below](https://github.com/integrii/flaggy#super-simple-example))
24- 35 different flag types supported
25- Any flag can be at any position
26- Pretty and readable help output by default
27- Positional subcommands
28- Positional parameters
29- Suggested subcommands when a subcommand is typo'd
30- Nested subcommands
31- Both global and subcommand specific flags
32- Both global and subcommand specific positional parameters
33- [Customizable help templates for both the global command and subcommands](https://github.com/integrii/flaggy/blob/master/examples/customTemplate/main.go)
34- Customizable appended/prepended help messages for both the global command and subcommands
35- Simple function that displays help followed by a custom message string
36- Flags and subcommands may have both a short and long name
37- Unlimited trailing arguments after a `--`
38- Flags can use a single dash or double dash (`--flag`, `-flag`, `-f`, `--f`)
39- Flags can have `=` assignment operators, or use a space (`--flag=value`, `--flag value`)
40- Flags support single quote globs with spaces (`--flag 'this is all one value'`)
41- Flags of slice types can be passed multiple times (`-f one -f two -f three`)
42- Optional but default version output with `--version`
43- Optional but default help output with `-h` or `--help`
44- Optional but default help output when any invalid or unknown parameter is passed
45- It's _fast_. All flag and subcommand parsing takes less than `1ms` in most programs.
46
47# Example Help Output
48
49```
50testCommand - Description goes here.  Get more information at http://flaggy.
51This is a prepend for help
52
53  Usage:
54    testCommand [subcommandA|subcommandB|subcommandC] [testPositionalA] [testPositionalB]
55
56  Positional Variables:
57    testPositionalA   Test positional A does some things with a positional value. (Required)
58    testPositionalB   Test positional B does some less than serious things with a positional value.
59
60  Subcommands:
61    subcommandA (a)   Subcommand A is a command that does stuff
62    subcommandB (b)   Subcommand B is a command that does other stuff
63    subcommandC (c)   Subcommand C is a command that does SERIOUS stuff
64
65  Flags:
66       --version        Displays the program version string.
67    -h --help           Displays help with available flag, subcommand, and positional value parameters.
68    -s --stringFlag     This is a test string flag that does some stringy string stuff.
69    -i --intFlg         This is a test int flag that does some interesting int stuff. (default: 5)
70    -b --boolFlag       This is a test bool flag that does some booly bool stuff. (default: true)
71    -d --durationFlag   This is a test duration flag that does some untimely stuff. (default: 1h23s)
72
73This is an append for help
74This is a help add-on message
75```
76
77# Super Simple Example
78
79`./yourApp -f test`
80
81```go
82// Declare variables and their defaults
83var stringFlag = "defaultValue"
84
85// Add a flag
86flaggy.String(&stringFlag, "f", "flag", "A test string flag")
87
88// Parse the flag
89flaggy.Parse()
90
91// Use the flag
92print(stringFlag)
93```
94
95
96# Example with Subcommand
97
98`./yourApp subcommandExample -f test`
99
100```go
101// Declare variables and their defaults
102var stringFlag = "defaultValue"
103
104// Create the subcommand
105subcommand := flaggy.NewSubcommand("subcommandExample")
106
107// Add a flag to the subcommand
108subcommand.String(&stringFlag, "f", "flag", "A test string flag")
109
110// Add the subcommand to the parser at position 1
111flaggy.AttachSubcommand(subcommand, 1)
112
113// Parse the subcommand and all flags
114flaggy.Parse()
115
116// Use the flag
117print(stringFlag)
118```
119
120# Example with Nested Subcommands, Various Flags and Trailing Arguments
121
122`./yourApp subcommandExample --flag=5 nestedSubcommand -t test -y -- trailingArg`
123
124```go
125// Declare variables and their defaults
126var stringFlagF = "defaultValueF"
127var intFlagT = 3
128var boolFlagB bool
129
130// Create the subcommands
131subcommandExample := flaggy.NewSubcommand("subcommandExample")
132nestedSubcommand := flaggy.NewSubcommand("nestedSubcommand")
133
134// Add a flag to both subcommands
135subcommandExample.String(&stringFlagF, "t", "testFlag", "A test string flag")
136nestedSubcommand.Int(&intFlagT, "f", "flag", "A test int flag")
137
138// add a global bool flag for fun
139flaggy.Bool(&boolFlagB, "y", "yes", "A sample boolean flag")
140
141// attach the nested subcommand to the parent subcommand at position 1
142subcommandExample.AttachSubcommand(nestedSubcommand, 1)
143// attach the base subcommand to the parser at position 1
144flaggy.AttachSubcommand(subcommandExample, 1)
145
146// Parse everything, then use the flags and trailing arguments
147flaggy.Parse()
148print(stringFlagF)
149print(intFlagT)
150print(boolFlagB)
151print(flaggy.TrailingArguments[0])
152```
153
154# Supported Flag Types
155
156Flaggy has specific flag types for all basic types included in go as well as a slice of any of those types.  This includes all of the following types:
157
158- string and []string
159- bool and []bool
160- all int types and all []int types
161- all float types and all []float types
162- all uint types and all []uint types
163
164Other more specific types can also be used as flag types.  They will be automatically parsed using the standard parsing functions included with those types in those packages.  This includes:
165
166- net.IP
167- []net.IP
168- net.HardwareAddr
169- []net.HardwareAddr
170- net.IPMask
171- []net.IPMask
172- time.Duration
173- []time.Duration
174
175# An Example Program
176
177Best practice when using flaggy includes setting your program's name, description, and version (at build time) as shown in this example program.
178
179```go
180package main
181
182import "github.com/integrii/flaggy"
183
184// Make a variable for the version which will be set at build time.
185var version = "unknown"
186
187// Keep subcommands as globals so you can easily check if they were used later on.
188var mySubcommand *flaggy.Subcommand
189
190// Setup the variables you want your incoming flags to set.
191var testVar string
192
193// If you would like an environment variable as the default for a value, just populate the flag
194// with the value of the environment by default.  If the flag corresponding to this value is not
195// used, then it will not be changed.
196var myVar = os.Getenv("MY_VAR")
197
198
199func init() {
200  // Set your program's name and description.  These appear in help output.
201  flaggy.SetName("Test Program")
202  flaggy.SetDescription("A little example program")
203
204  // You can disable various things by changing bools on the default parser
205  // (or your own parser if you have created one).
206  flaggy.DefaultParser.ShowHelpOnUnexpected = false
207
208  // You can set a help prepend or append on the default parser.
209  flaggy.DefaultParser.AdditionalHelpPrepend = "http://github.com/integrii/flaggy"
210
211  // Add a flag to the main program (this will be available in all subcommands as well).
212  flaggy.String(&testVar, "tv", "testVariable", "A variable just for testing things!")
213
214  // Create any subcommands and set their parameters.
215  mySubcommand = flaggy.NewSubcommand("mySubcommand")
216  mySubcommand.Description = "My great subcommand!"
217
218  // Add a flag to the subcommand.
219  mySubcommand.String(&myVar, "mv", "myVariable", "A variable just for me!")
220
221  // Set the version and parse all inputs into variables.
222  flaggy.SetVersion(version)
223  flaggy.Parse()
224}
225
226func main(){
227    if mySubcommand.Used {
228      ...
229    }
230}
231```
232
233Then, you can use the following build command to set the `version` variable in the above program at build time.
234
235```bash
236# build your app and set the version string
237$ go build -ldflags='-X main.version=1.0.3-a3db3'
238$ ./yourApp version
239Version: 1.0.3-a3db3
240$ ./yourApp --help
241Test Program - A little example program
242http://github.com/integrii/flaggy
243```
244
245# Contributions
246
247Please feel free to open an issue if you find any bugs or see any features that make sense. Pull requests will be reviewed and accepted if they make sense, but it is always wise to submit a proposal issue before any major changes.
248