Skip to content
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

Merged
merged 2 commits into from
Dec 11, 2024

Conversation

yongruilin
Copy link
Contributor

@yongruilin yongruilin commented Dec 7, 2024

This PR adds an option AppendKeyFields to the ExtractItems 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

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Dec 7, 2024
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Dec 7, 2024
}
for _, keyField := range *pe.Key {
keyName := keyField.Name
keyFieldPath := append(path[:i+1:i+1], fieldpath.PathElement{FieldName: &keyName})

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.

Copy link
Contributor Author

@yongruilin yongruilin Dec 7, 2024

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 PathElements.

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?

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.

Copy link
Contributor

@jpbetz jpbetz Dec 9, 2024

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@jpbetz jpbetz left a 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
Comment on lines 35 to 49
// 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
)

Copy link
Contributor

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

Copy link
Contributor Author

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
Copy link
Contributor

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?

Copy link
Contributor Author

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})
Copy link
Contributor

@jpbetz jpbetz Dec 9, 2024

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.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
goto startExtrcation
goto startExtraction

Copy link

@leoluz leoluz Dec 10, 2024

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?

Copy link
Contributor Author

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?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍🏻

typed/typed.go Outdated Show resolved Hide resolved
typed/typed.go Outdated Show resolved Hide resolved
@yongruilin yongruilin force-pushed the extend-extractitems branch 2 times, most recently from 0ee796b to 65746d2 Compare December 10, 2024 17:25
typed/remove_test.go Outdated Show resolved Hide resolved
typed/typed.go Outdated
}
if options.appendKeyFields {
tvPathSet, err := tv.ToFieldSet()
if err != nil {
Copy link

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Updated.

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 {
Copy link
Contributor

@jpbetz jpbetz Dec 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Copy link
Contributor Author

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.
@jpbetz
Copy link
Contributor

jpbetz commented Dec 11, 2024

/lgtm
/approve
Thanks for adding this!

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Dec 11, 2024
@k8s-ci-robot
Copy link
Contributor

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 11, 2024
@k8s-ci-robot k8s-ci-robot merged commit 40c8ef9 into kubernetes-sigs:master Dec 11, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants