-
Notifications
You must be signed in to change notification settings - Fork 38.7k
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
Refactor Strategic Merge Patch #43880
Conversation
/unassign @dchen1107 |
@janetkuo Are you familiar with this code and able to review? |
Review status: 0 of 3 files reviewed at latest revision, 2 unresolved discussions. staging/src/k8s.io/apimachinery/pkg/util/mergepatch/errors.go, line 30 at r1 (raw file):
Make these functions with arguments. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 57 at r1 (raw file):
Comment what these are Comments from Reviewable |
Review status: 0 of 3 files reviewed at latest revision, 20 unresolved discussions. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 161 at r1 (raw file):
Pass in the casted value for modifiedValue staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 198 at r1 (raw file):
Add comments for arguments staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 200 at r1 (raw file):
Cast this before passing in staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 211 at r1 (raw file):
Add a comment that the directive tells us to replace the entire object instead of diffing it staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 221 at r1 (raw file):
Add comment // Maps were not identical, use provided patch value staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 229 at r1 (raw file):
drop "Typed" piece of var names staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 231 at r1 (raw file):
pass in casted value staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 244 at r1 (raw file):
// Merge the 2 slices using mergePatchKey staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 265 at r1 (raw file):
Pass in the full options.
staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 266 at r1 (raw file):
if ignoreChangesAndAdditions { staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 276 at r1 (raw file):
Add comment for original and modified // original maybe either the live cluster object or the last applied configuration staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 277 at r1 (raw file):
if ignoreDeletions { staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 280 at r1 (raw file):
if _, found := modified[key]; !found { staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 339 at r1 (raw file):
support either < or > staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 364 at r1 (raw file):
` ` staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 371 at r1 (raw file):
Boolean logic unclear (put parens) staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 407 at r1 (raw file):
originalElement, originalElementMergeKeyValue staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 438 at r1 (raw file):
help func ` func ItemRemovedFromModifiedSlice(original, modified string) { return originalString < modifiedString } func ItemMatchesOriginalAndModifiedSlice(original, modified string) { return originalString == modifiedString } func CreateDeleteDirective(mergeKey: originalValue, directiveMarker: deleteDirective) { } Comments from Reviewable |
Review status: 0 of 3 files reviewed at latest revision, 21 unresolved discussions. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 604 at r1 (raw file):
should continue is vague. Call this Comments from Reviewable |
21475e0
to
3e27df4
Compare
Review status: 0 of 3 files reviewed at latest revision, 21 unresolved discussions. staging/src/k8s.io/apimachinery/pkg/util/mergepatch/errors.go, line 30 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 57 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 161 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 198 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 200 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 211 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 221 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 229 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 231 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 244 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 265 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 266 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 276 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 277 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 280 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 339 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 364 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 371 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 407 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 438 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. staging/src/k8s.io/apimachinery/pkg/util/strategicpatch/patch.go, line 604 at r1 (raw file): Previously, pwittrock (Phillip Wittrock) wrote…
Done. Comments from Reviewable |
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 number of if
conditions and interface{}
used here is quite scary. I wonder if both problems could be vastly improved by using an interface with a merge function and separate the logic in different types.
} | ||
|
||
func ErrBadArgType(expected, actual string) error { | ||
return fmt.Errorf("expected a %s, but received a %s", expected, actual) |
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 wonder if it would simplify the code to take expected, actual interface{}
and the print the type with %T
(instead of using reflect.TypeOf(obj).Kind().String()
).
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.
%T
gives a type that is too concrete for us. Return a very concrete type may confuse the users sometimes.
But we can use reflect
control which level of type we want to return to the users.
x := []byte("foo")
fmt.Printf("%T\n", x)
fmt.Printf(reflect.TypeOf(x).String())
fmt.Printf(reflect.TypeOf(x).Kind().String())
[]uint8
[]uint8
slice
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.
Yeah, thanks for pointing this out. TIL what typeOf(obj).Kind()
does :-)
return original, nil | ||
// mergeMapHandler handles how to merge `patchV` whose key is `key` with `original` respecting | ||
// fieldPatchStrategy, fieldPatchMergeKey, isDeleteList and mergeOptions. | ||
func mergeSliceHandler(original map[string]interface{}, key string, patchV interface{}, fieldType reflect.Type, |
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.
Same comment as above
} | ||
// mergeMapHandler handles how to merge `patchV` whose key is `key` with `original` respecting | ||
// fieldPatchStrategy and mergeOptions. | ||
func mergeMapHandler(original map[string]interface{}, key string, patchV interface{}, fieldType reflect.Type, |
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 have a bad feeling about this function:
- It takes a lot of parameters
- Given a specific condition, it does only one simple thing (ignoring many of the parameters, not a good sign). And this is also done in the function below (exactly the same)
- Given the opposite condition, many of the types must be casted to different types
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.
Given a specific condition, it does only one simple thing (ignoring many of the parameters, not a good sign). And this is also done in the function below (exactly the same)
This problem still exists. But I don't have a better way to that. Any suggestions?
func mergeSliceHandler(original map[string]interface{}, key string, patchV interface{}, fieldType reflect.Type, | ||
fieldPatchStrategy, fieldPatchMergeKey string, isDeleteList bool, mergeOptions MergeOptions) error { | ||
if fieldPatchStrategy == mergeDirective { | ||
elemType := fieldType.Elem() |
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.
fieldType
is only used to get elemType
. Should we pass elemType
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.
I want to keep the signature of mergeSliceHandler
and mergeSliceHandler
similar. So I prefer to use fieldType
func mergeMapHandler(original map[string]interface{}, key string, patchV interface{}, fieldType reflect.Type, | ||
fieldPatchStrategy string, mergeOptions MergeOptions) error { | ||
if fieldPatchStrategy != replaceDirective { | ||
typedOriginal := original[key].(map[string]interface{}) |
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.
You're assuming that original[key]
can be casted to map[string]interface{}
(no error checking) because it's been done by the calling function, but that's not obvious when you read this function. I think that could be simplified.
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 type assertion safety check.
It's already much better to read, thanks! |
LGTM for me |
/approve |
/comment |
/lgtm |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: caesarxuchao, pwittrock, ymqytw
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
Automatic merge from submit-queue (batch tested with PRs 44097, 42772, 43880, 44031, 44066) |
Refactor Strategic Merge Patch