Skip to content

Commit 6a0355d

Browse files
committed
refactor: export all CommandInfo and InputInfo fields
* necessary for any custom help generators to even be possible. * allows for a non-builder route.
1 parent 5a61312 commit 6a0355d

File tree

5 files changed

+280
-280
lines changed

5 files changed

+280
-280
lines changed

builder.go

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "strings"
55
var DefaultHelpInput = NewBoolOpt("help").
66
Short('h').
77
Help("Show this help message and exit.").
8-
HelpGen(DefaultHelpGenerator)
8+
WithHelpGen(DefaultHelpGenerator)
99

1010
var (
1111
errMixingPosArgsAndSubcmds = "commands cannot have both positional args and subcommands"
@@ -20,8 +20,8 @@ func (c *CommandInfo) prepareAndValidate() {
2020
// Add the default help option here as long as this
2121
// command doesn't already have a help option.
2222
var hasHelpOpt bool
23-
for i := range c.opts {
24-
if c.opts[i].helpGen != nil {
23+
for i := range c.Opts {
24+
if c.Opts[i].HelpGen != nil {
2525
hasHelpOpt = true
2626
break
2727
}
@@ -31,48 +31,48 @@ func (c *CommandInfo) prepareAndValidate() {
3131
}
3232

3333
// option assertions
34-
for i := 0; i < len(c.opts)-1; i++ {
35-
for z := i + 1; z < len(c.opts); z++ {
34+
for i := 0; i < len(c.Opts)-1; i++ {
35+
for z := i + 1; z < len(c.Opts); z++ {
3636
// assert there are no duplicate input ids
37-
if c.opts[i].id == c.opts[z].id {
38-
panic("command '" + strings.Join(c.path, " ") +
39-
"' contains duplicate option ids '" + c.opts[i].id + "'")
37+
if c.Opts[i].ID == c.Opts[z].ID {
38+
panic("command '" + strings.Join(c.Path, " ") +
39+
"' contains duplicate option ids '" + c.Opts[i].ID + "'")
4040
}
4141

4242
// assert there are no duplicate long or short option names
43-
if c.opts[i].nameShort != "" && c.opts[i].nameShort == c.opts[z].nameShort {
44-
panic("command '" + strings.Join(c.path, " ") +
45-
"' contains duplicate option short name '" + c.opts[i].nameShort + "'")
43+
if c.Opts[i].NameShort != "" && c.Opts[i].NameShort == c.Opts[z].NameShort {
44+
panic("command '" + strings.Join(c.Path, " ") +
45+
"' contains duplicate option short name '" + c.Opts[i].NameShort + "'")
4646
}
47-
if c.opts[i].nameLong != "" && c.opts[i].nameLong == c.opts[z].nameLong {
48-
panic("command '" + strings.Join(c.path, " ") +
49-
"' contains duplicate option long name '" + c.opts[i].nameLong + "'")
47+
if c.Opts[i].NameLong != "" && c.Opts[i].NameLong == c.Opts[z].NameLong {
48+
panic("command '" + strings.Join(c.Path, " ") +
49+
"' contains duplicate option long name '" + c.Opts[i].NameLong + "'")
5050
}
5151
}
5252
}
5353

5454
// assert there are no duplicate arg ids
55-
for i := 0; i < len(c.args)-1; i++ {
56-
for z := i + 1; z < len(c.args); z++ {
57-
if c.args[i].id == c.args[z].id {
58-
panic("command '" + strings.Join(c.path, " ") +
59-
"' contains duplicate argument ids '" + c.args[i].id + "'")
55+
for i := 0; i < len(c.Args)-1; i++ {
56+
for z := i + 1; z < len(c.Args); z++ {
57+
if c.Args[i].ID == c.Args[z].ID {
58+
panic("command '" + strings.Join(c.Path, " ") +
59+
"' contains duplicate argument ids '" + c.Args[i].ID + "'")
6060
}
6161
}
6262
}
6363

64-
// subcommand names must be unique across subcmds
65-
for i := 0; i < len(c.subcmds)-1; i++ {
66-
for z := i + 1; z < len(c.subcmds); z++ {
67-
if c.subcmds[i].name == c.subcmds[z].name {
68-
panic("command '" + strings.Join(c.path, " ") +
69-
"' contains duplicate subcommand name '" + c.subcmds[i].name + "'")
64+
// subcommand names must be unique across Subcmds
65+
for i := 0; i < len(c.Subcmds)-1; i++ {
66+
for z := i + 1; z < len(c.Subcmds); z++ {
67+
if c.Subcmds[i].Name == c.Subcmds[z].Name {
68+
panic("command '" + strings.Join(c.Path, " ") +
69+
"' contains duplicate subcommand name '" + c.Subcmds[i].Name + "'")
7070
}
7171
}
7272
}
7373

74-
for i := range c.subcmds {
75-
c.subcmds[i].prepareAndValidate()
74+
for i := range c.Subcmds {
75+
c.Subcmds[i].prepareAndValidate()
7676
}
7777
}
7878

@@ -89,67 +89,67 @@ func NewCmd(name string) CommandInfo {
8989
}
9090

9191
return CommandInfo{
92-
name: name,
93-
path: []string{name},
94-
opts: make([]InputInfo, 0, 5),
92+
Name: name,
93+
Path: []string{name},
94+
Opts: make([]InputInfo, 0, 5),
9595
}
9696
}
9797

9898
func (c CommandInfo) Help(blurb string) CommandInfo {
99-
c.helpBlurb = blurb
99+
c.HelpBlurb = blurb
100100
return c
101101
}
102102

103-
// HelpExtra adds an "overview" section to the Command's help message. This is typically
103+
// ExtraHelp adds an "overview" section to the Command's help message. This is typically
104104
// for longer-form content that wouldn't fit well within the 1-2 sentence "blurb."
105-
func (c CommandInfo) HelpExtra(extra string) CommandInfo {
106-
c.helpExtra = extra
105+
func (c CommandInfo) ExtraHelp(extra string) CommandInfo {
106+
c.HelpExtra = extra
107107
return c
108108
}
109109

110-
// HelpUsage overrides the default "usage" lines in the command's help message. These are
110+
// Usage overrides the default "usage" lines in the command's help message. These are
111111
// intended to show the user some different ways to invoke this command using whatever
112112
// combinations of options / arguments / subcommands.
113-
func (c CommandInfo) HelpUsage(lines ...string) CommandInfo {
114-
c.helpUsage = append(c.helpUsage, lines...)
113+
func (c CommandInfo) Usage(lines ...string) CommandInfo {
114+
c.HelpUsage = append(c.HelpUsage, lines...)
115115
return c
116116
}
117117

118118
func (c CommandInfo) Opt(o InputInfo) CommandInfo {
119119
// Assert `o` is not a positional arg by making sure it has at least one option name.
120-
if o.nameShort == "" && o.nameLong == "" {
120+
if o.NameShort == "" && o.NameLong == "" {
121121
panic(errEmptyOptNames)
122122
}
123-
c.opts = append(c.opts, o)
123+
c.Opts = append(c.Opts, o)
124124
return c
125125
}
126126

127127
func (c CommandInfo) Arg(a InputInfo) CommandInfo {
128-
if len(c.subcmds) > 0 {
128+
if len(c.Subcmds) > 0 {
129129
panic(errMixingPosArgsAndSubcmds)
130130
}
131131
// Assert the given input is not an option.
132132
if a.isOption() {
133133
panic(errOptAsPosArg)
134134
}
135135
// Ensure a required positional arg isn't coming after an optional one.
136-
if a.isRequired && len(c.args) > 0 && !c.args[len(c.args)-1].isRequired {
136+
if a.IsRequired && len(c.Args) > 0 && !c.Args[len(c.Args)-1].IsRequired {
137137
panic(errReqArgAfterOptional)
138138
}
139139

140-
c.args = append(c.args, a)
140+
c.Args = append(c.Args, a)
141141
return c
142142
}
143143

144144
func (c CommandInfo) Subcmd(sc CommandInfo) CommandInfo {
145-
if len(c.args) > 0 {
145+
if len(c.Args) > 0 {
146146
panic(errMixingPosArgsAndSubcmds)
147147
}
148148

149-
sc.path = append([]string(nil), c.path...)
150-
sc.path = append(sc.path, sc.name)
149+
sc.Path = append([]string(nil), c.Path...)
150+
sc.Path = append(sc.Path, sc.Name)
151151

152-
c.subcmds = append(c.subcmds, sc)
152+
c.Subcmds = append(c.Subcmds, sc)
153153
return c
154154
}
155155

@@ -163,9 +163,9 @@ func NewOpt(id string) InputInfo {
163163
panic(errEmptyInputID)
164164
}
165165
if len(id) == 1 {
166-
return InputInfo{id: id}.ShortOnly(id[0])
166+
return InputInfo{ID: id}.ShortOnly(id[0])
167167
}
168-
return InputInfo{id: id}.Long(id)
168+
return InputInfo{ID: id}.Long(id)
169169
}
170170

171171
// NewBoolOpt returns a new boolean option. If no value is provided to this option when
@@ -174,7 +174,7 @@ func NewOpt(id string) InputInfo {
174174
// be ignored.
175175
func NewBoolOpt(id string) InputInfo {
176176
o := NewOpt(id)
177-
o.isBoolOpt = true
177+
o.IsBoolOpt = true
178178
return o
179179
}
180180

@@ -199,76 +199,76 @@ func NewFloat64Opt(id string) InputInfo {
199199
}
200200

201201
// NewArg returns a new positional argument input. By default, the arg's display name will
202-
// be the provided id, but this can be overidden with [InputInfo.ValueName] method.
202+
// be the provided id, but this can be overidden with [InputInfo.WithValueName] method.
203203
func NewArg(id string) InputInfo {
204204
if id == "" {
205205
panic(errEmptyInputID)
206206
}
207-
return InputInfo{id: id, valueName: id}
207+
return InputInfo{ID: id, ValueName: id}
208208
}
209209

210210
// WithParser sets the InputInfo's parser to the given [ValueParser]. This will override any
211211
// parser that has been set up until this point. Providing nil as the parser will restore
212212
// the default behavior of just using the plain string value when this InputInfo is parsed.
213213
func (in InputInfo) WithParser(vp ValueParser) InputInfo {
214-
in.valueParser = vp
214+
in.ValueParser = vp
215215
return in
216216
}
217217

218218
// Short sets this option's short name to the given character. In order to create an
219219
// option that has a short name but no long name, see [InputInfo.ShortOnly].
220220
func (in InputInfo) Short(c byte) InputInfo {
221-
in.nameShort = string(c)
221+
in.NameShort = string(c)
222222
return in
223223
}
224224

225225
// ShortOnly sets this option's short name to the given character and removes any long
226226
// name it may have had at this point. In order to create an option that has both a short
227227
// and long name, see [InputInfo.Short]. Use [InputInfo.Long] to add a long name back.
228228
func (in InputInfo) ShortOnly(c byte) InputInfo {
229-
in.nameLong = ""
229+
in.NameLong = ""
230230
return in.Short(c)
231231
}
232232

233233
func (in InputInfo) Long(name string) InputInfo {
234-
in.nameLong = name
234+
in.NameLong = name
235235
return in
236236
}
237237

238238
func (in InputInfo) Help(blurb string) InputInfo {
239-
in.helpBlurb = blurb
239+
in.HelpBlurb = blurb
240240
return in
241241
}
242242

243243
func (in InputInfo) Env(e string) InputInfo {
244-
in.env = e
244+
in.EnvVar = e
245245
return in
246246
}
247247

248248
func (in InputInfo) Required() InputInfo {
249-
in.isRequired = true
249+
in.IsRequired = true
250250
return in
251251
}
252252

253-
// ValueName sets the display name of this InputInfo's argument value. For non-boolean
253+
// WithValueName sets the display name of this InputInfo's argument value. For non-boolean
254254
// options, it's the argument of the option. For positional arguments, it's the argument
255255
// name itself.
256-
func (in InputInfo) ValueName(name string) InputInfo {
257-
in.valueName = name
256+
func (in InputInfo) WithValueName(name string) InputInfo {
257+
in.ValueName = name
258258
return in
259259
}
260260

261261
func (in InputInfo) Default(v string) InputInfo {
262-
in.rawDefaultValue = v
263-
in.hasDefaultValue = true
262+
in.StrDefault = v
263+
in.HasStrDefault = true
264264
return in
265265
}
266266

267-
func (in InputInfo) HelpGen(hg HelpGenerator) InputInfo {
268-
in.helpGen = hg
267+
func (in InputInfo) WithHelpGen(hg HelpGenerator) InputInfo {
268+
in.HelpGen = hg
269269
return in
270270
}
271271

272272
func (in *InputInfo) isOption() bool {
273-
return in.nameShort != "" || in.nameLong != ""
273+
return in.NameShort != "" || in.NameLong != ""
274274
}

0 commit comments

Comments
 (0)