diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index e1c62e4d940..0fab9f32da8 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -200,10 +200,6 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin } count++ - if err := info.Refresh(patchedObj, true); err != nil { - return err - } - oldData, err := json.Marshal(info.Object) if err != nil { return err @@ -216,6 +212,11 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin dataChangedMsg = "patched" } + // After computing whether we changed data, refresh the resource info with the resulting object + if err := info.Refresh(patchedObj, true); err != nil { + return err + } + if len(options.OutputFormat) > 0 && options.OutputFormat != "name" { return cmdutil.PrintResourceInfoForCommand(cmd, info, f, out) } diff --git a/pkg/kubectl/cmd/patch_test.go b/pkg/kubectl/cmd/patch_test.go index 22f0a39912d..5908afbe0d2 100644 --- a/pkg/kubectl/cmd/patch_test.go +++ b/pkg/kubectl/cmd/patch_test.go @@ -93,6 +93,60 @@ func TestPatchObjectFromFile(t *testing.T) { } } +func TestPatchNoop(t *testing.T) { + _, svc, _ := testData() + getObject := &svc.Items[0] + patchObject := &svc.Items[0] + + f, tf, codec, _ := cmdtesting.NewAPIFactory() + tf.UnstructuredClient = &fake.RESTClient{ + APIRegistry: api.Registry, + NegotiatedSerializer: unstructuredSerializer, + Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { + switch p, m := req.URL.Path, req.Method; { + case p == "/namespaces/test/services/frontend" && m == "PATCH": + return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, patchObject)}, nil + case p == "/namespaces/test/services/frontend" && m == "GET": + return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, getObject)}, nil + default: + t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) + return nil, nil + } + }), + } + tf.Namespace = "test" + + // No-op + { + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdPatch(f, buf) + cmd.Flags().Set("namespace", "test") + cmd.Flags().Set("patch", `{}`) + cmd.Run(cmd, []string{"services", "frontend"}) + if buf.String() != "service \"baz\" not patched\n" { + t.Errorf("unexpected output: %s", buf.String()) + } + } + + // Patched + { + copied, _ := api.Scheme.DeepCopy(patchObject) + patchObject = copied.(*api.Service) + if patchObject.Annotations == nil { + patchObject.Annotations = map[string]string{} + } + patchObject.Annotations["foo"] = "bar" + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdPatch(f, buf) + cmd.Flags().Set("namespace", "test") + cmd.Flags().Set("patch", `{"metadata":{"annotations":{"foo":"bar"}}}`) + cmd.Run(cmd, []string{"services", "frontend"}) + if buf.String() != "service \"baz\" patched\n" { + t.Errorf("unexpected output: %s", buf.String()) + } + } +} + func TestPatchObjectFromFileOutput(t *testing.T) { _, svc, _ := testData()