-
Notifications
You must be signed in to change notification settings - Fork 63
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
feat: Adds ExtractItems option to include key fields #275
feat: Adds ExtractItems option to include key fields #275
Conversation
0f81c16
to
8e5a6e6
Compare
} | ||
for _, keyField := range *pe.Key { | ||
keyName := keyField.Name | ||
keyFieldPath := append(path[:i+1:i+1], fieldpath.PathElement{FieldName: &keyName}) |
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 may have to make a copy of path, at least I've run into some issues when not doing so in my workaround.
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.
The copy
doesn't make the difference here as the fields in the PathElement
are pointers and they would still be copied to the new path, so that the new path still points to the same fields in the PathElement
s.
I think what matters is creating a new string keyName := keyField.Name
in the for-loop, so that the appended PathElement.FieldName
won't be overwritten on the same address.
Or, could you share the issues you encounter when not doing copy?
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.
Ah, maybe you are right. I have argoproj/gitops-engine@e881697, but I indeed didn't create a new string, so that might have been an issue.
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 fine with setting capacity here to prevent any overwriting of underlying slice values. I also wouldn't mind an extra comment for future readers stating what happens here since this is use of the language that not all readers may pick up on easily.
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've added the comment.
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.
Two suggestions then LGTM
typed/typed.go
Outdated
// ExtractItemsOptions is the list of all the options available when extracting items. | ||
type ExtractItemsOptions int | ||
|
||
const ( | ||
// AppendKeyFields means that when extracting items, the key field would also be included. | ||
AppendKeyFields ExtractItemsOptions = iota | ||
) | ||
|
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.
Are we confident all future options will be flags? Alternative form that would handle arbitrary option params: https://github.com/kubernetes/kube-openapi/pull/519/files#diff-72f8260914152fe9557b05d756ec94854184645e991ff755855628428d6d7a18R410-R421
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.
SG, updated using this format.
typed/typed.go
Outdated
case AppendKeyFields: | ||
tvPathSet, err := tv.ToFieldSet() | ||
if err != nil { | ||
continue |
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.
Can we include a comment explaining why continue is safe and correct here?
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.
Added the comment.
} | ||
for _, keyField := range *pe.Key { | ||
keyName := keyField.Name | ||
keyFieldPath := append(path[:i+1:i+1], fieldpath.PathElement{FieldName: &keyName}) |
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 fine with setting capacity here to prevent any overwriting of underlying slice values. I also wouldn't mind an extra comment for future readers stating what happens here since this is use of the language that not all readers may pick up on easily.
8e5a6e6
to
d4fcd3b
Compare
typed/typed.go
Outdated
// It is safe to continue and skip appending the key fields, because | ||
// if there is error to convert to fieldPath.Set, there is | ||
// no way to find the key fields values by following the schema. | ||
goto startExtrcation |
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.
goto startExtrcation | |
goto startExtraction |
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.
IMO, it would be preferable to return the error and avoid the goto
instead of failing silently. I understand that it would change the signature and break consumers. Maybe a new function?
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 is a good practice to expose the error. But I'm not a fan to add a new interface here. We should address the non-error return interface(RemoveItems
,ExtractItems
) in another PR. wdyt?
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. 👍🏻
0ee796b
to
65746d2
Compare
65746d2
to
a6f15ab
Compare
typed/typed.go
Outdated
} | ||
if options.appendKeyFields { | ||
tvPathSet, err := tv.ToFieldSet() | ||
if err != nil { |
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.
What if we do if err == nil { <Add the logic to set the keyname here> }
?
This way I think we could get rid of the goto
.
Wdyt?
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.
Sounds good. Updated.
a6f15ab
to
1d91b45
Compare
typed/typed.go
Outdated
@@ -187,7 +201,37 @@ func (tv TypedValue) RemoveItems(items *fieldpath.Set) *TypedValue { | |||
} | |||
|
|||
// ExtractItems returns a value with only the provided list or map items extracted from the value. | |||
func (tv TypedValue) ExtractItems(items *fieldpath.Set) *TypedValue { | |||
func (tv TypedValue) ExtractItems(items *fieldpath.Set, opts ...extractItemsOption) *TypedValue { |
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.
func (tv TypedValue) ExtractItems(items *fieldpath.Set, opts ...extractItemsOption) *TypedValue { | |
func (tv TypedValue) ExtractItems(items *fieldpath.Set, opts ...ExtractItemsOption) *TypedValue { |
Requiring a non-exported type as an argument of an exported function is surprising.
EDIT: I don't think this is strictly required to be usable from a separate package, but I can't think of any reason not to export the option function type (it's not possible to modify the option type since it is unexported). But let me know if there is something I'm not thinking of.
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.
My original thought was that putting it non-exported can force user to only use the exported Withxxx()
function to construct the options. But it indeed looks strange to put it in the exported function.
Updated.
Adds an option to `ExtractItems` to include key fields in the output.
1d91b45
to
a88b919
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jpbetz, yongruilin The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
This PR adds an option
AppendKeyFields
to theExtractItems
function.When doing extracting with a fieldpath set which doesn't include the key fields, with this option, the result would include the key field values. So that the extraction result would follow the schema without hitting key field missing errors.
Ref: #273