Skip to content

Commit ea3e70c

Browse files
committed
Add command-line options
1 parent 93cb35b commit ea3e70c

File tree

4 files changed

+129
-1
lines changed

4 files changed

+129
-1
lines changed

command.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,28 @@ import (
55

66
"github.com/caddyserver/caddy/v2"
77
caddycmd "github.com/caddyserver/caddy/v2/cmd"
8+
"github.com/liujed/caddy-dns01proxy/flags"
9+
"github.com/liujed/goutil/optionals"
810
"github.com/spf13/cobra"
911
)
1012

13+
// Flag definitions.
14+
var (
15+
flgConfig = flags.Flag[string]{
16+
Name: "config",
17+
ShortName: optionals.Some('c'),
18+
UsageMsg: "read configuration from `FILE`",
19+
Required: true,
20+
FilenameExts: optionals.Some([]string{"json"}),
21+
}
22+
23+
flgDebug = flags.Flag[bool]{
24+
Name: "debug",
25+
ShortName: optionals.Some('v'),
26+
UsageMsg: "turn on verbose debug logs",
27+
}
28+
)
29+
1130
func init() {
1231
caddycmd.RegisterCommand(caddycmd.Command{
1332
Name: "dns01proxy",
@@ -27,6 +46,9 @@ Designed to work with:
2746
* Caddy's 'acmeproxy' DNS provider module, and
2847
* lego's 'httpreq' DNS provider.`,
2948
CobraFunc: func(cmd *cobra.Command) {
49+
flags.AddStringFlag(cmd, flgConfig)
50+
flags.AddBoolFlag(cmd, flgDebug)
51+
3052
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdRun)
3153

3254
cmd.AddCommand(&cobra.Command{

flags/flags.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package flags
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
7+
"github.com/liujed/goutil/optionals"
8+
"github.com/spf13/cobra"
9+
"github.com/spf13/pflag"
10+
)
11+
12+
// Defines a command-line Flag.
13+
type Flag[T any] struct {
14+
// Whether this flag is inherited by subcommands.
15+
Persistent bool
16+
17+
Name string
18+
ShortName optionals.Optional[rune]
19+
DefaultValue T
20+
UsageMsg string
21+
22+
Required bool
23+
Hidden bool
24+
DeprecationMsg optionals.Optional[string]
25+
26+
// If given, then command-line completions will be restricted to filenames
27+
// having any of the given extensions.
28+
FilenameExts optionals.Optional[[]string]
29+
30+
// Whether command-line completions should be restricted to directory names.
31+
DirNames bool
32+
}
33+
34+
// Adds the given boolean-valued flag to the given command.
35+
func AddBoolFlag(
36+
cmd *cobra.Command,
37+
f Flag[bool],
38+
) *bool {
39+
flags := f.getFlagSet(cmd)
40+
return addFlag(flags, flags.BoolP, f)
41+
}
42+
43+
// Adds the given string-valued flag to the given command.
44+
func AddStringFlag(
45+
cmd *cobra.Command,
46+
f Flag[string],
47+
) *string {
48+
flags := f.getFlagSet(cmd)
49+
return addFlag(flags, flags.StringP, f)
50+
}
51+
52+
// Adds the given string-slice-valued flag to the given command.
53+
func AddStringSliceFlag(
54+
cmd *cobra.Command,
55+
f Flag[[]string],
56+
) *[]string {
57+
flags := f.getFlagSet(cmd)
58+
return addFlag(flags, flags.StringSliceP, f)
59+
}
60+
61+
// Returns the FlagSet corresponding to this flag.
62+
func (f Flag[T]) getFlagSet(cmd *cobra.Command) *pflag.FlagSet {
63+
if f.Persistent {
64+
return cmd.PersistentFlags()
65+
}
66+
return cmd.Flags()
67+
}
68+
69+
// Adds the given flag to the given command.
70+
func addFlag[T any](
71+
flagSet *pflag.FlagSet,
72+
defineFlag func(name string, shorthand string, value T, usage string) *T,
73+
f Flag[T],
74+
) *T {
75+
if reflect.TypeFor[T]().Kind() == reflect.Slice {
76+
f.UsageMsg = fmt.Sprintf("%s. Can be specified multiple times", f.UsageMsg)
77+
}
78+
79+
shortName := ""
80+
if r, exists := f.ShortName.Get(); exists {
81+
shortName = string(r)
82+
}
83+
result := defineFlag(f.Name, shortName, f.DefaultValue, f.UsageMsg)
84+
85+
if f.Required {
86+
cobra.MarkFlagRequired(flagSet, f.Name)
87+
}
88+
if f.Hidden {
89+
flagSet.MarkHidden(f.Name)
90+
}
91+
if msg, deprecated := f.DeprecationMsg.Get(); deprecated {
92+
flagSet.MarkDeprecated(f.Name, msg)
93+
}
94+
95+
if exts, exists := f.FilenameExts.Get(); exists {
96+
cobra.MarkFlagFilename(flagSet, f.Name, exts...)
97+
}
98+
if f.DirNames {
99+
cobra.MarkFlagDirname(flagSet, f.Name)
100+
}
101+
102+
return result
103+
}

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ go 1.24.3
44

55
require (
66
github.com/caddyserver/caddy/v2 v2.10.0
7+
github.com/liujed/goutil v0.0.0
78
github.com/spf13/cobra v1.9.1
9+
github.com/spf13/pflag v1.0.6
810
)
911

1012
require (
@@ -33,7 +35,6 @@ require (
3335
github.com/quic-go/qpack v0.5.1 // indirect
3436
github.com/quic-go/quic-go v0.50.1 // indirect
3537
github.com/russross/blackfriday/v2 v2.1.0 // indirect
36-
github.com/spf13/pflag v1.0.6 // indirect
3738
github.com/zeebo/blake3 v0.2.4 // indirect
3839
go.uber.org/automaxprocs v1.6.0 // indirect
3940
go.uber.org/mock v0.5.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
8989
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
9090
github.com/libdns/libdns v1.0.0-beta.1 h1:KIf4wLfsrEpXpZ3vmc/poM8zCATXT2klbdPe6hyOBjQ=
9191
github.com/libdns/libdns v1.0.0-beta.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
92+
github.com/liujed/goutil v0.0.0 h1:2436TO9/CPSpL/M6Uih4Nt7B20NFQ0wwegoFnTgBC14=
93+
github.com/liujed/goutil v0.0.0/go.mod h1:dpiiIGi/qurLl5eG5TWq/eViVTAcWubEPPgbXA49w8A=
9294
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
9395
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
9496
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=

0 commit comments

Comments
 (0)