Skip to content

Commit cf9bcea

Browse files
authored
Merge pull request #1961 from dearchap/issue_1960
Feat:(issue_1960) make defaults validation optional
2 parents 5386081 + c5664f1 commit cf9bcea

File tree

5 files changed

+82
-67
lines changed

5 files changed

+82
-67
lines changed

command_test.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3766,7 +3766,7 @@ func TestCommandReadArgsFromStdIn(t *testing.T) {
37663766
{
37673767
name: "empty2",
37683768
input: `
3769-
3769+
37703770
`,
37713771
args: []string{"foo"},
37723772
expectedInt: 0,
@@ -3784,7 +3784,7 @@ func TestCommandReadArgsFromStdIn(t *testing.T) {
37843784
{
37853785
name: "intflag-from-input2",
37863786
input: `
3787-
--if
3787+
--if
37883788
37893789
100`,
37903790
args: []string{"foo"},
@@ -3803,14 +3803,14 @@ func TestCommandReadArgsFromStdIn(t *testing.T) {
38033803
--ssf hello
38043804
--ssf
38053805
3806-
"hello
3806+
"hello
38073807
123
38083808
44"
38093809
`,
38103810
args: []string{"foo"},
38113811
expectedInt: 100,
38123812
expectedFloat: 100.1,
3813-
expectedSlice: []string{"hello", "hello\t\n 123\n44"},
3813+
expectedSlice: []string{"hello", "hello\n 123\n44"},
38143814
},
38153815
{
38163816
name: "end-args",
@@ -3976,7 +3976,8 @@ func TestJSONExportCommand(t *testing.T) {
39763976
"config": {
39773977
"TrimSpace": false
39783978
},
3979-
"onlyOnce": false
3979+
"onlyOnce": false,
3980+
"validateDefaults" : false
39803981
},
39813982
{
39823983
"name": "sub-command-flag",
@@ -3995,7 +3996,8 @@ func TestJSONExportCommand(t *testing.T) {
39953996
"config": {
39963997
"Count": null
39973998
},
3998-
"onlyOnce": false
3999+
"onlyOnce": false,
4000+
"validateDefaults" : false
39994001
}
40004002
],
40014003
"hideHelp": false,
@@ -4036,7 +4038,8 @@ func TestJSONExportCommand(t *testing.T) {
40364038
"config": {
40374039
"TrimSpace": false
40384040
},
4039-
"onlyOnce": false
4041+
"onlyOnce": false,
4042+
"validateDefaults" : false
40404043
},
40414044
{
40424045
"name": "another-flag",
@@ -4055,7 +4058,8 @@ func TestJSONExportCommand(t *testing.T) {
40554058
"config": {
40564059
"Count": null
40574060
},
4058-
"onlyOnce": false
4061+
"onlyOnce": false,
4062+
"validateDefaults" : false
40594063
}
40604064
],
40614065
"hideHelp": false,
@@ -4213,7 +4217,8 @@ func TestJSONExportCommand(t *testing.T) {
42134217
"config": {
42144218
"Count": null
42154219
},
4216-
"onlyOnce": false
4220+
"onlyOnce": false,
4221+
"validateDefaults" : false
42174222
}
42184223
],
42194224
"hideHelp": false,
@@ -4254,7 +4259,8 @@ func TestJSONExportCommand(t *testing.T) {
42544259
"config": {
42554260
"TrimSpace": false
42564261
},
4257-
"onlyOnce": false
4262+
"onlyOnce": false,
4263+
"validateDefaults" : false
42584264
},
42594265
{
42604266
"name": "another-flag",
@@ -4273,7 +4279,8 @@ func TestJSONExportCommand(t *testing.T) {
42734279
"config": {
42744280
"Count": null
42754281
},
4276-
"onlyOnce": false
4282+
"onlyOnce": false,
4283+
"validateDefaults" : false
42774284
}
42784285
],
42794286
"hideHelp": false,
@@ -4313,7 +4320,8 @@ func TestJSONExportCommand(t *testing.T) {
43134320
"config": {
43144321
"TrimSpace": false
43154322
},
4316-
"onlyOnce": false
4323+
"onlyOnce": false,
4324+
"validateDefaults" : false
43174325
},
43184326
{
43194327
"name": "flag",
@@ -4333,7 +4341,8 @@ func TestJSONExportCommand(t *testing.T) {
43334341
"config": {
43344342
"TrimSpace": false
43354343
},
4336-
"onlyOnce": false
4344+
"onlyOnce": false,
4345+
"validateDefaults" : false
43374346
},
43384347
{
43394348
"name": "another-flag",
@@ -4352,7 +4361,8 @@ func TestJSONExportCommand(t *testing.T) {
43524361
"config": {
43534362
"Count": null
43544363
},
4355-
"onlyOnce": false
4364+
"onlyOnce": false,
4365+
"validateDefaults" : false
43564366
},
43574367
{
43584368
"name": "hidden-flag",
@@ -4369,7 +4379,8 @@ func TestJSONExportCommand(t *testing.T) {
43694379
"config": {
43704380
"Count": null
43714381
},
4372-
"onlyOnce": false
4382+
"onlyOnce": false,
4383+
"validateDefaults" : false
43734384
}
43744385
],
43754386
"hideHelp": false,

flag_impl.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,24 @@ type NoConfig struct{}
6969
// C specifies the configuration required(if any for that flag type)
7070
// VC specifies the value creator which creates the flag.Value emulation
7171
type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
72-
Name string `json:"name"` // name of the flag
73-
Category string `json:"category"` // category of the flag, if any
74-
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
75-
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
76-
Usage string `json:"usage"` // usage string for help output
77-
Sources ValueSourceChain `json:"-"` // sources to load flag value from
78-
Required bool `json:"required"` // whether the flag is required or not
79-
Hidden bool `json:"hidden"` // whether to hide the flag in help output
80-
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
81-
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
82-
Destination *T `json:"-"` // destination pointer for value when set
83-
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
84-
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
85-
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
86-
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
87-
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
88-
Validator func(T) error `json:"-"` // custom function to validate this flag value
72+
Name string `json:"name"` // name of the flag
73+
Category string `json:"category"` // category of the flag, if any
74+
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
75+
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
76+
Usage string `json:"usage"` // usage string for help output
77+
Sources ValueSourceChain `json:"-"` // sources to load flag value from
78+
Required bool `json:"required"` // whether the flag is required or not
79+
Hidden bool `json:"hidden"` // whether to hide the flag in help output
80+
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
81+
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
82+
Destination *T `json:"-"` // destination pointer for value when set
83+
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
84+
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
85+
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
86+
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
87+
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
88+
Validator func(T) error `json:"-"` // custom function to validate this flag value
89+
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
8990

9091
// unexported fields for internal use
9192
count int // number of times the flag has been set
@@ -145,7 +146,7 @@ func (f *FlagBase[T, C, V]) Apply(set *flag.FlagSet) error {
145146
}
146147

147148
// Validate the given default or values set from external sources as well
148-
if f.Validator != nil {
149+
if f.Validator != nil && f.ValidateDefaults {
149150
if v, ok := f.value.Get().(T); !ok {
150151
return &typeError[T]{
151152
other: f.value.Get(),

flag_validation_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func TestFlagDefaultValidation(t *testing.T) {
2020
}
2121
return fmt.Errorf("Value %d not in range [3,10] or [20,24]", i)
2222
},
23+
ValidateDefaults: true,
2324
},
2425
},
2526
}

godoc-current.txt

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -647,23 +647,24 @@ var VersionFlag Flag = &BoolFlag{
647647
VersionFlag prints the version for the application
648648

649649
type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
650-
Name string `json:"name"` // name of the flag
651-
Category string `json:"category"` // category of the flag, if any
652-
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
653-
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
654-
Usage string `json:"usage"` // usage string for help output
655-
Sources ValueSourceChain `json:"-"` // sources to load flag value from
656-
Required bool `json:"required"` // whether the flag is required or not
657-
Hidden bool `json:"hidden"` // whether to hide the flag in help output
658-
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
659-
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
660-
Destination *T `json:"-"` // destination pointer for value when set
661-
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
662-
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
663-
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
664-
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
665-
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
666-
Validator func(T) error `json:"-"` // custom function to validate this flag value
650+
Name string `json:"name"` // name of the flag
651+
Category string `json:"category"` // category of the flag, if any
652+
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
653+
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
654+
Usage string `json:"usage"` // usage string for help output
655+
Sources ValueSourceChain `json:"-"` // sources to load flag value from
656+
Required bool `json:"required"` // whether the flag is required or not
657+
Hidden bool `json:"hidden"` // whether to hide the flag in help output
658+
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
659+
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
660+
Destination *T `json:"-"` // destination pointer for value when set
661+
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
662+
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
663+
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
664+
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
665+
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
666+
Validator func(T) error `json:"-"` // custom function to validate this flag value
667+
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
667668

668669
// Has unexported fields.
669670
}

testdata/godoc-v3.x.txt

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -647,23 +647,24 @@ var VersionFlag Flag = &BoolFlag{
647647
VersionFlag prints the version for the application
648648

649649
type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
650-
Name string `json:"name"` // name of the flag
651-
Category string `json:"category"` // category of the flag, if any
652-
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
653-
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
654-
Usage string `json:"usage"` // usage string for help output
655-
Sources ValueSourceChain `json:"-"` // sources to load flag value from
656-
Required bool `json:"required"` // whether the flag is required or not
657-
Hidden bool `json:"hidden"` // whether to hide the flag in help output
658-
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
659-
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
660-
Destination *T `json:"-"` // destination pointer for value when set
661-
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
662-
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
663-
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
664-
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
665-
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
666-
Validator func(T) error `json:"-"` // custom function to validate this flag value
650+
Name string `json:"name"` // name of the flag
651+
Category string `json:"category"` // category of the flag, if any
652+
DefaultText string `json:"defaultText"` // default text of the flag for usage purposes
653+
HideDefault bool `json:"hideDefault"` // whether to hide the default value in output
654+
Usage string `json:"usage"` // usage string for help output
655+
Sources ValueSourceChain `json:"-"` // sources to load flag value from
656+
Required bool `json:"required"` // whether the flag is required or not
657+
Hidden bool `json:"hidden"` // whether to hide the flag in help output
658+
Persistent bool `json:"persistent"` // whether the flag needs to be applied to subcommands as well
659+
Value T `json:"defaultValue"` // default value for this flag if not set by from any source
660+
Destination *T `json:"-"` // destination pointer for value when set
661+
Aliases []string `json:"aliases"` // Aliases that are allowed for this flag
662+
TakesFile bool `json:"takesFileArg"` // whether this flag takes a file argument, mainly for shell completion purposes
663+
Action func(context.Context, *Command, T) error `json:"-"` // Action callback to be called when flag is set
664+
Config C `json:"config"` // Additional/Custom configuration associated with this flag type
665+
OnlyOnce bool `json:"onlyOnce"` // whether this flag can be duplicated on the command line
666+
Validator func(T) error `json:"-"` // custom function to validate this flag value
667+
ValidateDefaults bool `json:"validateDefaults"` // whether to validate defaults or not
667668

668669
// Has unexported fields.
669670
}

0 commit comments

Comments
 (0)