Skip to content

Commit 18a76be

Browse files
authored
Add option for required fields (#49)
1 parent 9206bcc commit 18a76be

File tree

4 files changed

+540
-44
lines changed

4 files changed

+540
-44
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import "github.com/itzg/go-flagsfiller"
2525
- Allows defaults to be given via struct tag `default`
2626
- Falls back to using instance field values as declared default
2727
- Declare flag usage via struct tag `usage`
28+
- Mark flags as required via struct tag `required` and validate with `Verify()` method (cannot be combined with `default` tag)
2829
- Can be combined with other modules, such as [google/subcommands](https://github.com/google/subcommands) for sub-command processing. Can also be integrated with [spf13/cobra](https://github.com/spf13/cobra) by using pflag's [AddGoFlagSet](https://godoc.org/github.com/spf13/pflag#FlagSet.AddGoFlagSet)
2930
- Beyond the standard types supported by flag.FlagSet also includes support for:
3031
- `[]string` where repetition of the argument appends to the slice and/or an argument value can contain a comma or newline-separated list of values. For example: `--arg one --arg two,three`
@@ -93,6 +94,36 @@ The following shows an example of the usage provided when passing `--help`:
9394
How long to wait (default 5s)
9495
```
9596

97+
## Required flags
98+
99+
Flags can be marked as required using the `required:"true"` struct tag. After parsing command-line arguments, call the `Verify()` method to ensure all required flags have been provided:
100+
101+
```go
102+
type Config struct {
103+
Host string `required:"true" usage:"The remote host"`
104+
Port int `default:"8080" usage:"The port"`
105+
Username string `required:"true" usage:"Username for authentication"`
106+
}
107+
108+
var config Config
109+
110+
filler := flagsfiller.New()
111+
err := filler.Fill(flag.CommandLine, &config)
112+
if err != nil {
113+
log.Fatal(err)
114+
}
115+
116+
flag.Parse()
117+
118+
// Verify all required fields are set
119+
err = filler.Verify()
120+
if err != nil {
121+
log.Fatal(err) // Will fail if Host or Username not provided
122+
}
123+
```
124+
125+
**Note:** A field cannot be both required and have a default value. Attempting to use both tags will result in an error during `Fill()`.
126+
96127
## Real world example
97128

98129
[saml-auth-proxy](https://github.com/itzg/saml-auth-proxy) shows an end-to-end usage of flagsfiller where the main function fills the flags, maps those to environment variables with [envy](https://github.com/jamiealquiza/envy), and parses the command line:

example_test.go

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ package flagsfiller_test
33
import (
44
"flag"
55
"fmt"
6-
"github.com/itzg/go-flagsfiller"
76
"log"
87
"time"
8+
9+
"github.com/itzg/go-flagsfiller"
910
)
1011

1112
func Example() {
1213
type Config struct {
1314
Host string `default:"localhost" usage:"The remote host"`
1415
Enabled bool `default:"true" usage:"Turn it on"`
1516
Automatic bool `default:"false" usage:"Make it automatic" aliases:"a"`
16-
Retries int `default:"1" usage:"Retry" aliases:"r,t"`
17+
Retries int `default:"1" usage:"Retry" aliases:"r,t"`
1718
Timeout time.Duration `default:"5s" usage:"How long to wait"`
1819
}
1920

@@ -36,3 +37,38 @@ func Example() {
3637
// Output:
3738
// {Host:external.svc Enabled:true Automatic:true Retries:2 Timeout:10m0s}
3839
}
40+
41+
func ExampleFlagSetFiller_Verify() {
42+
type Config struct {
43+
Host string `required:"true" usage:"The remote host"`
44+
Port int `default:"8080" usage:"The port"`
45+
Username string `required:"true" usage:"Username for authentication"`
46+
}
47+
48+
var config Config
49+
50+
flagset := flag.NewFlagSet("ExampleVerify", flag.ContinueOnError)
51+
52+
filler := flagsfiller.New()
53+
err := filler.Fill(flagset, &config)
54+
if err != nil {
55+
log.Fatal(err)
56+
}
57+
58+
// Parse with required fields provided
59+
err = flagset.Parse([]string{"--host", "example.com", "--username", "admin"})
60+
if err != nil {
61+
log.Fatal(err)
62+
}
63+
64+
// Verify all required fields are set
65+
err = filler.Verify()
66+
if err != nil {
67+
fmt.Printf("Error: %v\n", err)
68+
return
69+
}
70+
71+
fmt.Printf("Config validated: Host=%s, Port=%d, Username=%s\n", config.Host, config.Port, config.Username)
72+
// Output:
73+
// Config validated: Host=example.com, Port=8080, Username=admin
74+
}

0 commit comments

Comments
 (0)