-
Notifications
You must be signed in to change notification settings - Fork 66
add new generator and helpers to return values for boolean pointers #637
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
Conversation
generator/helpers/gen.go
Outdated
|
||
// Generator generates helper functions that are used to return values for boolean pointer fields. | ||
// | ||
// The helper function takes as a parameter, the `devfile:default:generate` annotated type and returns the value of the |
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.
should be?
// The helper function takes as a parameter, the `devfile:default:generate` annotated type and returns the value of the | |
// The helper function takes as a parameter, the `devfile:default:value` annotated type and returns the value of the |
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.
Thanks for picking up on this. It should be devfile:helper:generate
. I changed the marker name last minute to better reflect what the action should be
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.
I'm not sure a generator is the right approach in general here -- it's a lot of code (that could have bugs of its own) to replace writing out 6-7 functions explicitly.
func IsDefault(in *CommandGroup) bool {
return getBoolOrDefault(in.IsDefault, false)
}
// etc...
func getBoolOrDefault(input *bool, defaultVal bool) bool {
if input != nil {
return *input
}
return defaultVal
}
We could also consider attaching the functions to the specific types, in order to avoid populating the v1alpha2 namespace with helpers, e.g.
func (c *ExecCommand) HotReloadCapable() bool {
return getBoolOrDefault(c.HotReloadCapable, false)
}
generator/helpers/gen.go
Outdated
defaultVal := helper.defaultVal | ||
if fName != "MountSources" { | ||
buf.WriteString(helperFunction + ` | ||
return ` + defaultVal + ` }`) | ||
} else { | ||
buf.WriteString(helperFunction + `else { | ||
if DedicatedPod(in) { return false } | ||
return ` + defaultVal + ` }}`) | ||
} |
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.
I don't think it's appropriate to have field name-specific functionality in the generator -- it should do what it says for every instance of the marker.
Handling for mountSources
should probably be an explicit function instead of a generated one.
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.
I tried to set a conditional expression in the marker value for mountSources
but ran into problems so I resorted to plan B, which was to handle this in the code (yes, it's a bit hackish). I can create this function manually for now.
@amisevsk, I went with the generator approach because the k8s structs are the "single source of truth" and I wanted the default values to be extracted from this source. If we ever wanted to change the values in the future or introduce new boolean pointer fields, it can be done in one place and kept in sync.
I thought having the containing struct type as the receiver makes this a "getter". I originally had this in place but you were not in favour of using getters: #545 (comment) |
I am contradicting myself, and I do apologize for that -- sometimes seeing it written out in code makes me realize I wasn't thinking through it clearly 😄. I'm fine with either approach (and honestly am not sure what I was thinking in that comment). The benefit, in my eyes, of implementing it as a method would be autocomplete would suggest to direct field access (returning a I think your reasoning for using generators makes sense, my main concern is that the tag should be straightforward (if I put this here, generate a helper method of some sort to return my default value). I'm 👍 with using it for all fields save |
I'm in favour of using getters but we are bending the rules a bit because the fields should be private but we need to them to be public in order for deserialization to work properly. This will result in a name conflict between the field and method names (if we adopt the Go guidance to assign the capitalized field name as the method name) which unfortunately, leaves me with no choice but to prefix the methods with |
I hadn't thought about that -- good point. Sorry for all the needless delay in this case :( |
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.
LGTM, a couple of optional suggestions.
generator/getters/gen.go
Outdated
getterMethod := ` | ||
// Get` + fName + ` returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker` + ` | ||
func (in *` + cmd.Name + `) Get` + fName + `() bool { | ||
return getBoolOrDefault(in.` + fName + `,` + defaultVal + `)}` | ||
buf.WriteString(getterMethod) |
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.
We could consider using fmt.Sprintf
here, but it's optional.
getterMethod := ` | |
// Get` + fName + ` returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker` + ` | |
func (in *` + cmd.Name + `) Get` + fName + `() bool { | |
return getBoolOrDefault(in.` + fName + `,` + defaultVal + `)}` | |
buf.WriteString(getterMethod) | |
fmt.Sprintf(` | |
// Get %[1]s returns the value of the boolean property. If unset, it's the default value specified in the devfile:default:value marker | |
func (in *%[2]s) Get%[1]s() bool { | |
return getBoolOrDefault(in.%[1]s, %[3]s) | |
}`, fName, cmd.Name, defaultVal) | |
buf.WriteString(getterMethod) |
(looks like markdown formatting is broken by including a backtick in the sample in the sample :/ )
func (in *Endpoint) GetSecure() bool { | ||
return getBoolOrDefault(in.Secure, false) | ||
} | ||
func getBoolOrDefault(input *bool, defaultVal bool) bool { |
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 would be ideal to have a newline before this function, so that the generated file is unchanged by executing go fmt ./...
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: amisevsk, kim-tsao The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
No worries, it's good to hash out the details. Thanks for the thorough review as always! |
New changes are detected. LGTM label has been removed. |
What does this PR do?:
Adds new helper functions to return values for the various boolean pointer properties. The primary consumer will be the library parser which will use these helpers to set the default values on the flattened devfile obj so clients can avoid encountering nil values.
Which issue(s) this PR fixes:
#615
PR acceptance criteria:
Testing and documentation do not need to be complete in order for this PR to be approved. We just need to ensure tracking issues are opened.
Unit/Functional tests
Testing will be done as part of changes to the Library parser
QE Integration test
Documentation
Marker help has been added
Client Impact
Clients can retrieve the default boolean values with the helper functions or via the library parser once the changes are in place
How to test changes / Special notes to the reviewer: