-
Notifications
You must be signed in to change notification settings - Fork 939
feat: add cli first class validation #8374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9572e90
1681c99
262ecf9
b1094fc
5c571dd
6d2079d
30fee84
b84238e
c1486ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,40 @@ type NoOptDefValuer interface { | |
NoOptDefValue() string | ||
} | ||
|
||
// Validator is a wrapper around a pflag.Value that allows for validation | ||
// of the value after or before it has been set. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like that this implements There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe there's a function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I was trying, but unfortunately The only way I could think of making it work is have some post-processing step for the option? It felt easier to make it a flag on the Options and just touch it at the flag parsing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's a common enough validation requirement that making it apart of the Option field is justified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. The downside is that if |
||
type Validator[T pflag.Value] struct { | ||
Value T | ||
// validate is called after the value is set. | ||
validate func(T) error | ||
} | ||
|
||
func Validate[T pflag.Value](opt T, validate func(value T) error) *Validator[T] { | ||
return &Validator[T]{Value: opt, validate: validate} | ||
} | ||
|
||
func (i *Validator[T]) String() string { | ||
return i.Value.String() | ||
} | ||
|
||
func (i *Validator[T]) Set(input string) error { | ||
err := i.Value.Set(input) | ||
if err != nil { | ||
return err | ||
} | ||
if i.validate != nil { | ||
err = i.validate(i.Value) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (i *Validator[T]) Type() string { | ||
return i.Value.Type() | ||
} | ||
|
||
// values.go contains a standard set of value types that can be used as | ||
// Option Values. | ||
|
||
|
@@ -329,10 +363,12 @@ type Struct[T any] struct { | |
Value T | ||
} | ||
|
||
//nolint:revive | ||
func (s *Struct[T]) Set(v string) error { | ||
return yaml.Unmarshal([]byte(v), &s.Value) | ||
} | ||
|
||
//nolint:revive | ||
func (s *Struct[T]) String() string { | ||
byt, err := yaml.Marshal(s.Value) | ||
if err != nil { | ||
|
@@ -361,6 +397,7 @@ func (s *Struct[T]) UnmarshalYAML(n *yaml.Node) error { | |
return n.Decode(&s.Value) | ||
} | ||
|
||
//nolint:revive | ||
func (s *Struct[T]) Type() string { | ||
return fmt.Sprintf("struct[%T]", s.Value) | ||
} | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not make Required a composable Validation rule instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot be a validation rule because the validation rule is only called on
Set()
. If the user never provides a value, and no default is set, thenSet()
is never called.So it has to happen in the flag parsing logic.