From 613ada4cd7500237a69de1f2233c028c0b579ce7 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Mon, 9 Jan 2017 14:21:24 -0500 Subject: [PATCH] Fix kubectl get -f -o Fix kubectl get -f -o so it prints all the objects in the file, instead of just the first one. Also add a test for this feature. --- hack/make-rules/test-cmd-util.sh | 14 ++++ pkg/kubectl/cmd/annotate.go | 6 +- pkg/kubectl/cmd/convert.go | 6 +- pkg/kubectl/cmd/get.go | 12 +-- pkg/kubectl/cmd/label.go | 2 +- pkg/kubectl/resource/builder.go | 46 +++++----- pkg/kubectl/resource/builder_test.go | 120 +++++++++++++-------------- pkg/kubectl/resource/result.go | 14 ++-- 8 files changed, 117 insertions(+), 103 deletions(-) diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh index 65faf73cde2..a21228c84e0 100644 --- a/hack/make-rules/test-cmd-util.sh +++ b/hack/make-rules/test-cmd-util.sh @@ -1072,6 +1072,20 @@ run_kubectl_get_tests() { # cleanup kubectl delete pods valid-pod "${kube_flags[@]}" + + ### Test 'kubectl get -f -o ' prints all the items in the file's list + # Pre-condition: no POD exists + kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" '' + # Command + kubectl create -f test/fixtures/doc-yaml/user-guide/multi-pod.yaml "${kube_flags[@]}" + # Post-condition: PODs redis-master and redis-proxy exist + + # Check that all items in the list are printed + output_message=$(kubectl get -f test/fixtures/doc-yaml/user-guide/multi-pod.yaml -o jsonpath="{..metadata.name}" "${kube_flags[@]}") + kube::test::if_has_string "${output_message}" "redis-master redis-proxy" + + # cleanup + kubectl delete pods redis-master redis-proxy "${kube_flags[@]}" } run_kubectl_request_timeout_tests() { diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index 989794f11c5..8acf548d4e0 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -197,14 +197,14 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro return err } - var singularResource bool - r.IntoSingular(&singularResource) + var singleItemImpliedResource bool + r.IntoSingleItemImplied(&singleItemImpliedResource) // only apply resource version locking on a single resource. // we must perform this check after o.builder.Do() as // []o.resources can not not accurately return the proper number // of resources when they are not passed in "resource/name" format. - if !singularResource && len(o.resourceVersion) > 0 { + if !singleItemImpliedResource && len(o.resourceVersion) > 0 { return fmt.Errorf("--resource-version may only be used with a single resource") } diff --git a/pkg/kubectl/cmd/convert.go b/pkg/kubectl/cmd/convert.go index 46055cbfba2..63817c0a133 100644 --- a/pkg/kubectl/cmd/convert.go +++ b/pkg/kubectl/cmd/convert.go @@ -162,8 +162,8 @@ func (o *ConvertOptions) RunConvert() error { return err } - singular := false - infos, err := r.IntoSingular(&singular).Infos() + singleItemImplied := false + infos, err := r.IntoSingleItemImplied(&singleItemImplied).Infos() if err != nil { return err } @@ -172,7 +172,7 @@ func (o *ConvertOptions) RunConvert() error { return fmt.Errorf("no objects passed to convert") } - objects, err := resource.AsVersionedObject(infos, !singular, o.outputVersion, o.encoder) + objects, err := resource.AsVersionedObject(infos, !singleItemImplied, o.outputVersion, o.encoder) if err != nil { return err } diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index ae302d187f9..afb7213c4cd 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -307,10 +307,10 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ // 2. if there is a single item and that item is a list, leave it as its specific list // 3. if there is a single item and it is not a a list, leave it as a single item var errs []error - singular := false - infos, err := r.IntoSingular(&singular).Infos() + singleItemImplied := false + infos, err := r.IntoSingleItemImplied(&singleItemImplied).Infos() if err != nil { - if singular { + if singleItemImplied { return err } errs = append(errs, err) @@ -325,9 +325,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ } var obj runtime.Object - if singular { - obj = infos[0].Object - } else { + if !singleItemImplied || len(infos) > 1 { // we have more than one item, so coerce all items into a list list := &unstructured.UnstructuredList{ Object: map[string]interface{}{ @@ -340,6 +338,8 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ list.Items = append(list.Items, info.Object.(*unstructured.Unstructured)) } obj = list + } else { + obj = infos[0].Object } isList := meta.IsListType(obj) diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index ee137b73dc4..3ddfe7f6e98 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -187,7 +187,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { Latest() } one := false - r := b.Do().IntoSingular(&one) + r := b.Do().IntoSingleItemImplied(&one) if err := r.Err(); err != nil { return err } diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 48992b51621..161c8d10d80 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -72,7 +72,7 @@ type Builder struct { singleResourceType bool continueOnError bool - singular bool + singleItemImplied bool export bool @@ -139,7 +139,7 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename b.URL(defaultHttpGetAttempts, url) default: if !recursive { - b.singular = true + b.singleItemImplied = true } b.Path(recursive, s) } @@ -600,21 +600,21 @@ func (b *Builder) visitBySelector() *Result { } func (b *Builder) visitByResource() *Result { - // if b.singular is false, this could be by default, so double-check length - // of resourceTuples to determine if in fact it is singular or not - isSingular := b.singular - if !isSingular { - isSingular = len(b.resourceTuples) == 1 + // if b.singleItemImplied is false, this could be by default, so double-check length + // of resourceTuples to determine if in fact it is singleItemImplied or not + isSingleItemImplied := b.singleItemImplied + if !isSingleItemImplied { + isSingleItemImplied = len(b.resourceTuples) == 1 } if len(b.resources) != 0 { - return &Result{singular: isSingular, err: fmt.Errorf("you may not specify individual resources and bulk resources in the same call")} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("you may not specify individual resources and bulk resources in the same call")} } // retrieve one client for each resource mappings, err := b.resourceTupleMappings() if err != nil { - return &Result{singular: isSingular, err: err} + return &Result{singleItemImplied: isSingleItemImplied, err: err} } clients := make(map[string]RESTClient) for _, mapping := range mappings { @@ -633,12 +633,12 @@ func (b *Builder) visitByResource() *Result { for _, tuple := range b.resourceTuples { mapping, ok := mappings[tuple.Resource] if !ok { - return &Result{singular: isSingular, err: fmt.Errorf("resource %q is not recognized: %v", tuple.Resource, mappings)} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("resource %q is not recognized: %v", tuple.Resource, mappings)} } s := fmt.Sprintf("%s/%s", mapping.GroupVersionKind.GroupVersion().String(), mapping.Resource) client, ok := clients[s] if !ok { - return &Result{singular: isSingular, err: fmt.Errorf("could not find a client for resource %q", tuple.Resource)} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("could not find a client for resource %q", tuple.Resource)} } selectorNamespace := b.namespace @@ -650,7 +650,7 @@ func (b *Builder) visitByResource() *Result { if b.allNamespace { errMsg = "a resource cannot be retrieved by name across all namespaces" } - return &Result{singular: isSingular, err: fmt.Errorf(errMsg)} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf(errMsg)} } } @@ -664,25 +664,25 @@ func (b *Builder) visitByResource() *Result { } else { visitors = VisitorList(items) } - return &Result{singular: isSingular, visitor: visitors, sources: items} + return &Result{singleItemImplied: isSingleItemImplied, visitor: visitors, sources: items} } func (b *Builder) visitByName() *Result { - isSingular := len(b.names) == 1 + isSingleItemImplied := len(b.names) == 1 if len(b.paths) != 0 { - return &Result{singular: isSingular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")} } if len(b.resources) == 0 { - return &Result{singular: isSingular, err: fmt.Errorf("you must provide a resource and a resource name together")} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("you must provide a resource and a resource name together")} } if len(b.resources) > 1 { - return &Result{singular: isSingular, err: fmt.Errorf("you must specify only one resource")} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf("you must specify only one resource")} } mappings, err := b.resourceMappings() if err != nil { - return &Result{singular: isSingular, err: err} + return &Result{singleItemImplied: isSingleItemImplied, err: err} } mapping := mappings[0] @@ -700,7 +700,7 @@ func (b *Builder) visitByName() *Result { if b.allNamespace { errMsg = "a resource cannot be retrieved by name across all namespaces" } - return &Result{singular: isSingular, err: fmt.Errorf(errMsg)} + return &Result{singleItemImplied: isSingleItemImplied, err: fmt.Errorf(errMsg)} } } @@ -709,13 +709,13 @@ func (b *Builder) visitByName() *Result { info := NewInfo(client, mapping, selectorNamespace, name, b.export) visitors = append(visitors, info) } - return &Result{singular: isSingular, visitor: VisitorList(visitors), sources: visitors} + return &Result{singleItemImplied: isSingleItemImplied, visitor: VisitorList(visitors), sources: visitors} } func (b *Builder) visitByPaths() *Result { - singular := !b.dir && !b.stream && len(b.paths) == 1 + singleItemImplied := !b.dir && !b.stream && len(b.paths) == 1 if len(b.resources) != 0 { - return &Result{singular: singular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify resource arguments as well")} + return &Result{singleItemImplied: singleItemImplied, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify resource arguments as well")} } if len(b.names) != 0 { return &Result{err: fmt.Errorf("name cannot be provided when a path is specified")} @@ -746,7 +746,7 @@ func (b *Builder) visitByPaths() *Result { if b.selector != nil { visitors = NewFilteredVisitor(visitors, FilterBySelector(b.selector)) } - return &Result{singular: singular, visitor: visitors, sources: b.paths} + return &Result{singleItemImplied: singleItemImplied, visitor: visitors, sources: b.paths} } // Do returns a Result object with a Visitor for the resources identified by the Builder. diff --git a/pkg/kubectl/resource/builder_test.go b/pkg/kubectl/resource/builder_test.go index 7380111b4ae..88b9e5d7f27 100644 --- a/pkg/kubectl/resource/builder_test.go +++ b/pkg/kubectl/resource/builder_test.go @@ -258,11 +258,11 @@ func TestPathBuilderAndVersionedObjectNotDefaulted(t *testing.T) { FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../test/fixtures/pkg/kubectl/builder/kitten-rc.yaml"}}) test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || !singular || len(test.Infos) != 1 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || !singleItemImplied || len(test.Infos) != 1 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } info := test.Infos[0] @@ -362,11 +362,11 @@ func TestPathBuilderWithMultiple(t *testing.T) { NamespaceParam("test").DefaultNamespace() testVisitor := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(testVisitor.Handle) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(testVisitor.Handle) if err != nil { - t.Fatalf("unexpected response: %v %t %#v %s", err, singular, testVisitor.Infos, test.name) + t.Fatalf("unexpected response: %v %t %#v %s", err, singleItemImplied, testVisitor.Infos, test.name) } info := testVisitor.Infos @@ -421,11 +421,11 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) { NamespaceParam("test").DefaultNamespace() testVisitor := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(testVisitor.Handle) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(testVisitor.Handle) if err == nil { - t.Fatalf("unexpected response: %v %t %#v %s", err, singular, testVisitor.Infos, test.name) + t.Fatalf("unexpected response: %v %t %#v %s", err, singleItemImplied, testVisitor.Infos, test.name) } } } @@ -436,11 +436,11 @@ func TestDirectoryBuilder(t *testing.T) { NamespaceParam("test").DefaultNamespace() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) < 3 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) < 3 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } found := false @@ -527,11 +527,11 @@ func TestURLBuilderRequireNamespace(t *testing.T) { NamespaceParam("test").RequireNamespace() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err == nil || !singular || len(test.Infos) != 0 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err == nil || !singleItemImplied || len(test.Infos) != 0 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } } @@ -543,7 +543,7 @@ func TestResourceByName(t *testing.T) { NamespaceParam("test") test := &testVisitor{} - singular := false + singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") @@ -551,9 +551,9 @@ func TestResourceByName(t *testing.T) { b.ResourceTypeOrNameArgs(true, "pods", "foo") - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || !singular || len(test.Infos) != 1 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || !singleItemImplied || len(test.Infos) != 1 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !reflect.DeepEqual(&pods.Items[0], test.Objects()[0]) { t.Errorf("unexpected object: %#v", test.Objects()[0]) @@ -579,7 +579,7 @@ func TestMultipleResourceByTheSameName(t *testing.T) { NamespaceParam("test") test := &testVisitor{} - singular := false + singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") @@ -587,9 +587,9 @@ func TestMultipleResourceByTheSameName(t *testing.T) { b.ResourceTypeOrNameArgs(true, "pods,services", "foo", "baz") - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) != 4 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) != 4 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &svcs.Items[0], &svcs.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) @@ -655,7 +655,7 @@ func TestResourceByNameWithoutRequireObject(t *testing.T) { NamespaceParam("test") test := &testVisitor{} - singular := false + singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") @@ -663,9 +663,9 @@ func TestResourceByNameWithoutRequireObject(t *testing.T) { b.ResourceTypeOrNameArgs(true, "pods", "foo").RequireObject(false) - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || !singular || len(test.Infos) != 1 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || !singleItemImplied || len(test.Infos) != 1 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if test.Infos[0].Name != "foo" { t.Errorf("unexpected name: %#v", test.Infos[0].Name) @@ -692,10 +692,10 @@ func TestResourceByNameAndEmptySelector(t *testing.T) { SelectorParam(""). ResourceTypeOrNameArgs(true, "pods", "foo") - singular := false - infos, err := b.Do().IntoSingular(&singular).Infos() - if err != nil || !singular || len(infos) != 1 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, infos) + singleItemImplied := false + infos, err := b.Do().IntoSingleItemImplied(&singleItemImplied).Infos() + if err != nil || !singleItemImplied || len(infos) != 1 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, infos) } if !reflect.DeepEqual(&pods.Items[0], infos[0].Object) { t.Errorf("unexpected object: %#v", infos[0]) @@ -722,7 +722,7 @@ func TestSelector(t *testing.T) { Flatten() test := &testVisitor{} - singular := false + singleItemImplied := false if b.Do().Err() == nil { t.Errorf("unexpected non-error") @@ -730,9 +730,9 @@ func TestSelector(t *testing.T) { b.ResourceTypeOrNameArgs(true, "pods,service") - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) != 3 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) != 3 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &svc.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) @@ -838,9 +838,9 @@ func TestResourceTuple(t *testing.T) { continue } switch { - case (r.singular && len(testCase.args) != 1), - (!r.singular && len(testCase.args) == 1): - t.Errorf("%s: result had unexpected singular value", k) + case (r.singleItemImplied && len(testCase.args) != 1), + (!r.singleItemImplied && len(testCase.args) == 1): + t.Errorf("%s: result had unexpected singleItemImplied value", k) } info, err := r.Infos() if err != nil { @@ -860,11 +860,11 @@ func TestStream(t *testing.T) { NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) != 3 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) != 3 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &rc.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) @@ -877,11 +877,11 @@ func TestYAMLStream(t *testing.T) { NamespaceParam("test").Stream(r, "STDIN").Flatten() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) != 3 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) != 3 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{&pods.Items[0], &pods.Items[1], &rc.Items[0]}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) @@ -940,7 +940,7 @@ func TestContinueOnErrorVisitor(t *testing.T) { } } -func TestSingularObject(t *testing.T) { +func TestSingleItemImpliedObject(t *testing.T) { obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/guestbook/legacy/redis-master-controller.yaml"}}). @@ -960,7 +960,7 @@ func TestSingularObject(t *testing.T) { } } -func TestSingularObjectNoExtension(t *testing.T) { +func TestSingleItemImpliedObjectNoExtension(t *testing.T) { obj, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). NamespaceParam("test").DefaultNamespace(). FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../examples/pod"}}). @@ -980,7 +980,7 @@ func TestSingularObjectNoExtension(t *testing.T) { } } -func TestSingularRootScopedObject(t *testing.T) { +func TestSingleItemImpliedRootScopedObject(t *testing.T) { node := &api.Node{ObjectMeta: api.ObjectMeta{Name: "test"}, Spec: api.NodeSpec{ExternalID: "test"}} r := streamTestObject(node) infos, err := NewBuilder(testapi.Default.RESTMapper(), api.Scheme, fakeClient(), testapi.Default.Codec()). @@ -1130,11 +1130,11 @@ func TestLatest(t *testing.T) { NamespaceParam("other").Stream(r, "STDIN").Flatten().Latest() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err != nil || singular || len(test.Infos) != 3 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err != nil || singleItemImplied || len(test.Infos) != 3 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } if !api.Semantic.DeepDerivative([]runtime.Object{newPod, newPod2, newSvc}, test.Objects()) { t.Errorf("unexpected visited objects: %#v", test.Objects()) @@ -1163,11 +1163,11 @@ func TestReceiveMultipleErrors(t *testing.T) { ContinueOnError() test := &testVisitor{} - singular := false + singleItemImplied := false - err := b.Do().IntoSingular(&singular).Visit(test.Handle) - if err == nil || singular || len(test.Infos) != 2 { - t.Fatalf("unexpected response: %v %t %#v", err, singular, test.Infos) + err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle) + if err == nil || singleItemImplied || len(test.Infos) != 2 { + t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos) } errs, ok := err.(utilerrors.Aggregate) diff --git a/pkg/kubectl/resource/result.go b/pkg/kubectl/resource/result.go index f703af06c60..27234ec455b 100644 --- a/pkg/kubectl/resource/result.go +++ b/pkg/kubectl/resource/result.go @@ -40,8 +40,8 @@ type Result struct { err error visitor Visitor - sources []Visitor - singular bool + sources []Visitor + singleItemImplied bool ignoreErrors []utilerrors.Matcher @@ -82,10 +82,10 @@ func (r *Result) Visit(fn VisitorFunc) error { return utilerrors.FilterOut(err, r.ignoreErrors...) } -// IntoSingular sets the provided boolean pointer to true if the Builder input -// reflected a single item, or multiple. -func (r *Result) IntoSingular(b *bool) *Result { - *b = r.singular +// IntoSingleItemImplied sets the provided boolean pointer to true if the Builder input +// implies a single item, or multiple. +func (r *Result) IntoSingleItemImplied(b *bool) *Result { + *b = r.singleItemImplied return r } @@ -136,7 +136,7 @@ func (r *Result) Object() (runtime.Object, error) { } if len(objects) == 1 { - if r.singular { + if r.singleItemImplied { return objects[0], nil } // if the item is a list already, don't create another list