diff --git a/docs/cmd/tkn_pipeline_list.md b/docs/cmd/tkn_pipeline_list.md index 098951220d..72c5d7e300 100644 --- a/docs/cmd/tkn_pipeline_list.md +++ b/docs/cmd/tkn_pipeline_list.md @@ -17,8 +17,10 @@ Lists pipelines in a namespace ### Options ``` + -A, --all-namespaces list pipelines from all namespaces --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) -h, --help help for list + --no-headers do not print column headers with output (default print column headers with output) -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file. --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. ``` diff --git a/docs/cmd/tkn_task_list.md b/docs/cmd/tkn_task_list.md index f82ccdbb90..b71db050ff 100644 --- a/docs/cmd/tkn_task_list.md +++ b/docs/cmd/tkn_task_list.md @@ -17,8 +17,10 @@ Lists tasks in a namespace ### Options ``` + -A, --all-namespaces list tasks from all namespaces --allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true) -h, --help help for list + --no-headers do not print column headers with output (default print column headers with output) -o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file. --template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]. ``` diff --git a/docs/man/man1/tkn-pipeline-list.1 b/docs/man/man1/tkn-pipeline-list.1 index 68a658ce9c..2802accc1a 100644 --- a/docs/man/man1/tkn-pipeline-list.1 +++ b/docs/man/man1/tkn-pipeline-list.1 @@ -19,6 +19,10 @@ Lists pipelines in a namespace .SH OPTIONS +.PP +\fB\-A\fP, \fB\-\-all\-namespaces\fP[=false] + list pipelines from all namespaces + .PP \fB\-\-allow\-missing\-template\-keys\fP[=true] If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. @@ -27,6 +31,10 @@ Lists pipelines in a namespace \fB\-h\fP, \fB\-\-help\fP[=false] help for list +.PP +\fB\-\-no\-headers\fP[=false] + do not print column headers with output (default print column headers with output) + .PP \fB\-o\fP, \fB\-\-output\fP="" Output format. One of: json|yaml|name|go\-template|go\-template\-file|template|templatefile|jsonpath|jsonpath\-file. diff --git a/docs/man/man1/tkn-task-list.1 b/docs/man/man1/tkn-task-list.1 index df26aee438..cb12b76d98 100644 --- a/docs/man/man1/tkn-task-list.1 +++ b/docs/man/man1/tkn-task-list.1 @@ -19,6 +19,10 @@ Lists tasks in a namespace .SH OPTIONS +.PP +\fB\-A\fP, \fB\-\-all\-namespaces\fP[=false] + list tasks from all namespaces + .PP \fB\-\-allow\-missing\-template\-keys\fP[=true] If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. @@ -27,6 +31,10 @@ Lists tasks in a namespace \fB\-h\fP, \fB\-\-help\fP[=false] help for list +.PP +\fB\-\-no\-headers\fP[=false] + do not print column headers with output (default print column headers with output) + .PP \fB\-o\fP, \fB\-\-output\fP="" Output format. One of: json|yaml|name|go\-template|go\-template\-file|template|templatefile|jsonpath|jsonpath\-file. diff --git a/pkg/cmd/pipeline/list.go b/pkg/cmd/pipeline/list.go index 0bad8822bc..04b683337a 100644 --- a/pkg/cmd/pipeline/list.go +++ b/pkg/cmd/pipeline/list.go @@ -34,21 +34,41 @@ import ( ) const listTemplate = `{{- $pl := len .Pipelines.Items }}{{ if eq $pl 0 -}} -No pipelines -{{- else -}} +No Pipelines found +{{ else -}} +{{- if not $.NoHeaders -}} +{{- if $.AllNamespaces -}} +NAMESPACE NAME AGE LAST RUN STARTED DURATION STATUS +{{ else -}} NAME AGE LAST RUN STARTED DURATION STATUS +{{ end }} +{{- end -}} {{- range $_, $p := .Pipelines.Items }} {{- $pr := accessMap $.PipelineRuns $p.Name }} {{- if $pr }} +{{- if $.AllNamespaces -}} +{{ $p.Namespace }} {{ $p.Name }} {{ formatAge $p.CreationTimestamp $.Params.Time }} {{ $pr.Name }} {{ formatAge $pr.Status.StartTime $.Params.Time }} {{ formatDuration $pr.Status.StartTime $pr.Status.CompletionTime }} {{ formatCondition $pr.Status.Conditions }} +{{ else -}} {{ $p.Name }} {{ formatAge $p.CreationTimestamp $.Params.Time }} {{ $pr.Name }} {{ formatAge $pr.Status.StartTime $.Params.Time }} {{ formatDuration $pr.Status.StartTime $pr.Status.CompletionTime }} {{ formatCondition $pr.Status.Conditions }} +{{ end }} {{- else }} +{{- if $.AllNamespaces -}} +{{ $p.Namespace }} {{ $p.Name }} {{ formatAge $p.CreationTimestamp $.Params.Time }} --- --- --- --- +{{ else -}} {{ $p.Name }} {{ formatAge $p.CreationTimestamp $.Params.Time }} --- --- --- --- +{{ end }} {{- end }} {{- end }} -{{- end }} +{{- end -}} ` +type ListOptions struct { + AllNamespaces bool + NoHeaders bool +} + func listCommand(p cli.Params) *cobra.Command { + opts := &ListOptions{} f := cliopts.NewPrintFlags("list") c := &cobra.Command{ @@ -61,7 +81,7 @@ func listCommand(p cli.Params) *cobra.Command { SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { - if err := validate.NamespaceExists(p); err != nil { + if err := validate.NamespaceExists(p); err != nil && !opts.AllNamespaces { return err } @@ -79,36 +99,46 @@ func listCommand(p cli.Params) *cobra.Command { Out: cmd.OutOrStdout(), Err: cmd.OutOrStderr(), } - return printPipelineDetails(stream, p) + return printPipelineDetails(stream, p, opts.AllNamespaces, opts.NoHeaders) }, } f.AddFlags(c) + c.Flags().BoolVarP(&opts.AllNamespaces, "all-namespaces", "A", opts.AllNamespaces, "list pipelines from all namespaces") + c.Flags().BoolVarP(&opts.NoHeaders, "no-headers", "", opts.NoHeaders, "do not print column headers with output (default print column headers with output)") return c } -func printPipelineDetails(s *cli.Stream, p cli.Params) error { +func printPipelineDetails(s *cli.Stream, p cli.Params, allnamespaces bool, noheaders bool) error { cs, err := p.Clients() if err != nil { return err } - ps, prs, err := listPipelineDetails(cs, p.Namespace()) + ns := p.Namespace() + if allnamespaces { + ns = "" + } + ps, prs, err := listPipelineDetails(cs, ns) if err != nil { - fmt.Fprintf(s.Err, "Failed to list pipelines from %s namespace\n", p.Namespace()) + fmt.Fprintf(s.Err, "Failed to list pipelines from %s namespace\n", ns) return err } var data = struct { - Pipelines *v1beta1.PipelineList - PipelineRuns pipelineruns - Params cli.Params + Pipelines *v1beta1.PipelineList + PipelineRuns pipelineruns + Params cli.Params + AllNamespaces bool + NoHeaders bool }{ - Pipelines: ps, - PipelineRuns: prs, - Params: p, + Pipelines: ps, + PipelineRuns: prs, + Params: p, + AllNamespaces: allnamespaces, + NoHeaders: noheaders, } funcMap := template.FuncMap{ @@ -116,7 +146,6 @@ func printPipelineDetails(s *cli.Stream, p cli.Params) error { if pr, ok := prs[name]; ok { return &pr } - return nil }, "formatAge": formatted.Age, diff --git a/pkg/cmd/pipeline/list_test.go b/pkg/cmd/pipeline/list_test.go index 9be5bd2da8..dbfa04cfdc 100644 --- a/pkg/cmd/pipeline/list_test.go +++ b/pkg/cmd/pipeline/list_test.go @@ -82,14 +82,14 @@ func TestPipelinesList_empty(t *testing.T) { t.Errorf("Unexpected error: %v", err) } - test.AssertOutput(t, "No pipelines\n", output) + test.AssertOutput(t, "No Pipelines found\n", output) } func TestPipelineList_only_pipelines(t *testing.T) { pipelines := []pipelineDetails{ - {"tomatoes", 1 * time.Minute}, - {"mangoes", 20 * time.Second}, - {"bananas", 512 * time.Hour}, // 3 weeks + {"tomatoes", 1 * time.Minute, "namespace"}, + {"mangoes", 20 * time.Second, "namespace"}, + {"bananas", 512 * time.Hour, "namespace"}, // 3 weeks } nsList := []*corev1.Namespace{ @@ -101,7 +101,7 @@ func TestPipelineList_only_pipelines(t *testing.T) { } version := "v1alpha1" clock := clockwork.NewFakeClock() - cs, pdata := seedPipelines(t, clock, pipelines, "namespace", nsList) + cs, pdata := seedPipelines(t, clock, pipelines, nsList) cs.Pipeline.Resources = cb.APIResourceList(version, []string{"pipeline"}) tdc := testDynamic.Options{} dc, err := tdc.Client( @@ -124,9 +124,9 @@ func TestPipelineList_only_pipelines(t *testing.T) { func TestPipelineList_only_pipelines_v1beta1(t *testing.T) { pipelines := []pipelineDetails{ - {"tomatoes", 1 * time.Minute}, - {"mangoes", 20 * time.Second}, - {"bananas", 512 * time.Hour}, // 3 weeks + {"tomatoes", 1 * time.Minute, "namespace"}, + {"mangoes", 20 * time.Second, "namespace"}, + {"bananas", 512 * time.Hour, "namespace"}, // 3 weeks } nsList := []*corev1.Namespace{ @@ -138,7 +138,7 @@ func TestPipelineList_only_pipelines_v1beta1(t *testing.T) { } version := "v1beta1" clock := clockwork.NewFakeClock() - cs, pdata := seedPipelines(t, clock, pipelines, "namespace", nsList) + cs, pdata := seedPipelines(t, clock, pipelines, nsList) cs.Pipeline.Resources = cb.APIResourceList(version, []string{"pipeline"}) tdc := testDynamic.Options{} dc, err := tdc.Client( @@ -159,6 +159,115 @@ func TestPipelineList_only_pipelines_v1beta1(t *testing.T) { golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) } +func TestPipelineList_only_pipelines_no_headers_v1beta1(t *testing.T) { + pipelines := []pipelineDetails{ + {"tomatoes", 1 * time.Minute, "namespace"}, + {"mangoes", 20 * time.Second, "namespace"}, + {"bananas", 512 * time.Hour, "namespace"}, // 3 weeks + } + + nsList := []*corev1.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace", + }, + }, + } + version := "v1beta1" + clock := clockwork.NewFakeClock() + cs, pdata := seedPipelines(t, clock, pipelines, nsList) + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"pipeline"}) + tdc := testDynamic.Options{} + dc, err := tdc.Client( + cb.UnstructuredP(pdata[0], version), + cb.UnstructuredP(pdata[1], version), + cb.UnstructuredP(pdata[2], version), + ) + if err != nil { + t.Errorf("unable to create dynamic clinet: %v", err) + } + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dc} + + pipeline := Command(p) + output, err := test.ExecuteCommand(pipeline, "list", "-n", "namespace", "--no-headers") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} + +func TestPipelineList_only_pipelines_all_namespaces_v1beta1(t *testing.T) { + pipelines := []pipelineDetails{ + {"tomatoes", 1 * time.Minute, "namespace"}, + {"mangoes", 20 * time.Second, "namespace"}, + {"bananas", 512 * time.Hour, "namespace"}, // 3 weeks + {"tomates", 1 * time.Minute, "espace-de-nom"}, + {"mangues", 20 * time.Second, "espace-de-nom"}, + {"bananes", 512 * time.Hour, "espace-de-nom"}, // 3 weeks + } + + version := "v1beta1" + clock := clockwork.NewFakeClock() + cs, pdata := seedPipelines(t, clock, pipelines, nil) + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"pipeline"}) + tdc := testDynamic.Options{} + dc, err := tdc.Client( + cb.UnstructuredP(pdata[0], version), + cb.UnstructuredP(pdata[1], version), + cb.UnstructuredP(pdata[2], version), + cb.UnstructuredP(pdata[3], version), + cb.UnstructuredP(pdata[4], version), + cb.UnstructuredP(pdata[5], version), + ) + if err != nil { + t.Errorf("unable to create dynamic clinet: %v", err) + } + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dc} + + pipeline := Command(p) + output, err := test.ExecuteCommand(pipeline, "list", "--all-namespaces") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} + +func TestPipelineList_only_pipelines_all_namespaces_no_headers_v1beta1(t *testing.T) { + pipelines := []pipelineDetails{ + {"tomatoes", 1 * time.Minute, "namespace"}, + {"mangoes", 20 * time.Second, "namespace"}, + {"bananas", 512 * time.Hour, "namespace"}, // 3 weeks + {"tomates", 1 * time.Minute, "espace-de-nom"}, + {"mangues", 20 * time.Second, "espace-de-nom"}, + {"bananes", 512 * time.Hour, "espace-de-nom"}, // 3 weeks + } + + version := "v1beta1" + clock := clockwork.NewFakeClock() + cs, pdata := seedPipelines(t, clock, pipelines, nil) + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"pipeline"}) + tdc := testDynamic.Options{} + dc, err := tdc.Client( + cb.UnstructuredP(pdata[0], version), + cb.UnstructuredP(pdata[1], version), + cb.UnstructuredP(pdata[2], version), + cb.UnstructuredP(pdata[3], version), + cb.UnstructuredP(pdata[4], version), + cb.UnstructuredP(pdata[5], version), + ) + if err != nil { + t.Errorf("unable to create dynamic clinet: %v", err) + } + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dc} + + pipeline := Command(p) + output, err := test.ExecuteCommand(pipeline, "list", "--all-namespaces", "--no-headers") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} + func TestPipelinesList_with_single_run(t *testing.T) { clock := clockwork.NewFakeClock() version := "v1alpha1" @@ -311,18 +420,16 @@ func TestPipelinesList_latest_run(t *testing.T) { } type pipelineDetails struct { - name string - age time.Duration + name string + age time.Duration + namespace string } -func seedPipelines(t *testing.T, clock clockwork.Clock, ps []pipelineDetails, ns string, nsList []*corev1.Namespace) (pipelinetest.Clients, []*v1alpha1.Pipeline) { +func seedPipelines(t *testing.T, clock clockwork.Clock, ps []pipelineDetails, nsList []*corev1.Namespace) (pipelinetest.Clients, []*v1alpha1.Pipeline) { pipelines := []*v1alpha1.Pipeline{} for _, p := range ps { - pipelines = append(pipelines, - tb.Pipeline(p.name, ns, - cb.PipelineCreationTimestamp(clock.Now().Add(p.age*-1)), - ), - ) + pipelines = append(pipelines, tb.Pipeline(p.name, p.namespace, + cb.PipelineCreationTimestamp(clock.Now().Add(p.age*-1)))) } cs, _ := test.SeedTestData(t, pipelinetest.Data{Pipelines: pipelines, Namespaces: nsList}) diff --git a/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_no_headers_v1beta1.golden b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_no_headers_v1beta1.golden new file mode 100644 index 0000000000..8c1a98646b --- /dev/null +++ b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_no_headers_v1beta1.golden @@ -0,0 +1,6 @@ +namespace tomatoes 1 minute ago --- --- --- --- +namespace mangoes 20 seconds ago --- --- --- --- +namespace bananas 3 weeks ago --- --- --- --- +espace-de-nom tomates 1 minute ago --- --- --- --- +espace-de-nom mangues 20 seconds ago --- --- --- --- +espace-de-nom bananes 3 weeks ago --- --- --- --- diff --git a/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_v1beta1.golden b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_v1beta1.golden new file mode 100644 index 0000000000..195d489668 --- /dev/null +++ b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_all_namespaces_v1beta1.golden @@ -0,0 +1,7 @@ +NAMESPACE NAME AGE LAST RUN STARTED DURATION STATUS +namespace tomatoes 1 minute ago --- --- --- --- +namespace mangoes 20 seconds ago --- --- --- --- +namespace bananas 3 weeks ago --- --- --- --- +espace-de-nom tomates 1 minute ago --- --- --- --- +espace-de-nom mangues 20 seconds ago --- --- --- --- +espace-de-nom bananes 3 weeks ago --- --- --- --- diff --git a/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_no_headers_v1beta1.golden b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_no_headers_v1beta1.golden new file mode 100644 index 0000000000..f0669afdd0 --- /dev/null +++ b/pkg/cmd/pipeline/testdata/TestPipelineList_only_pipelines_no_headers_v1beta1.golden @@ -0,0 +1,3 @@ +tomatoes 1 minute ago --- --- --- --- +mangoes 20 seconds ago --- --- --- --- +bananas 3 weeks ago --- --- --- --- diff --git a/pkg/cmd/task/list.go b/pkg/cmd/task/list.go index cb10d5689e..e422647247 100644 --- a/pkg/cmd/task/list.go +++ b/pkg/cmd/task/list.go @@ -18,25 +18,48 @@ import ( "fmt" "os" "text/tabwriter" + "text/template" + + "github.com/jonboulle/clockwork" + "github.com/tektoncd/cli/pkg/task" "github.com/spf13/cobra" "github.com/tektoncd/cli/pkg/actions" "github.com/tektoncd/cli/pkg/cli" "github.com/tektoncd/cli/pkg/formatted" - "github.com/tektoncd/cli/pkg/task" "github.com/tektoncd/cli/pkg/validate" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" cliopts "k8s.io/cli-runtime/pkg/genericclioptions" ) -const ( - emptyMsg = "No tasks found" - header = "NAME\tDESCRIPTION\tAGE" - body = "%s\t%s\t%s\n" -) +const listTemplate = `{{- $tl := len .Tasks.Items }}{{ if eq $tl 0 -}} +No Tasks found +{{ else -}} +{{- if not $.NoHeaders -}} +{{- if $.AllNamespaces -}} +NAMESPACE NAME DESCRIPTION AGE +{{ else -}} +NAME DESCRIPTION AGE +{{ end -}} +{{- end -}} +{{- range $_, $t := .Tasks.Items }}{{- if $t }} +{{- if $.AllNamespaces -}} +{{ $t.Namespace }} {{ $t.Name }} {{ formatDesc $t.Spec.Description }} {{ formatAge $t.CreationTimestamp $.Time }} +{{ else -}} +{{ $t.Name }} {{ formatDesc $t.Spec.Description }} {{ formatAge $t.CreationTimestamp $.Time }} +{{ end }}{{- end }}{{- end }} +{{- end -}} +` + +type ListOptions struct { + AllNamespaces bool + NoHeaders bool +} func listCommand(p cli.Params) *cobra.Command { + opts := &ListOptions{} f := cliopts.NewPrintFlags("list") c := &cobra.Command{ @@ -48,13 +71,13 @@ func listCommand(p cli.Params) *cobra.Command { }, RunE: func(cmd *cobra.Command, args []string) error { - if err := validate.NamespaceExists(p); err != nil { + if err := validate.NamespaceExists(p); err != nil && !opts.AllNamespaces { return err } output, err := cmd.LocalFlags().GetString("output") if err != nil { - fmt.Fprint(os.Stderr, "Error: output option not set properly \n") + fmt.Fprint(os.Stderr, "error: output option not set properly \n") return err } @@ -66,40 +89,56 @@ func listCommand(p cli.Params) *cobra.Command { Out: cmd.OutOrStdout(), Err: cmd.OutOrStderr(), } - return printTaskDetails(stream, p) + return printTaskDetails(stream, p, opts.AllNamespaces, opts.NoHeaders) }, } f.AddFlags(c) + c.Flags().BoolVarP(&opts.AllNamespaces, "all-namespaces", "A", opts.AllNamespaces, "list tasks from all namespaces") + c.Flags().BoolVarP(&opts.NoHeaders, "no-headers", "", opts.NoHeaders, "do not print column headers with output (default print column headers with output)") return c } -func printTaskDetails(s *cli.Stream, p cli.Params) error { +func printTaskDetails(s *cli.Stream, p cli.Params, allnamespaces bool, noheaders bool) error { cs, err := p.Clients() if err != nil { return err } - tasks, err := task.List(cs, metav1.ListOptions{}, p.Namespace()) + ns := p.Namespace() + if allnamespaces { + ns = "" + } + tasks, err := task.List(cs, metav1.ListOptions{}, ns) if err != nil { - fmt.Fprintf(os.Stderr, "Failed to list tasks from %s namespace \n", p.Namespace()) + fmt.Fprintf(os.Stderr, "failed to list tasks from %s namespace \n", ns) return err } - if len(tasks.Items) == 0 { - fmt.Fprintln(s.Err, emptyMsg) - return nil + var data = struct { + Tasks *v1beta1.TaskList + Time clockwork.Clock + AllNamespaces bool + NoHeaders bool + }{ + Tasks: tasks, + Time: p.Time(), + AllNamespaces: allnamespaces, + NoHeaders: noheaders, + } + + funcMap := template.FuncMap{ + "formatAge": formatted.Age, + "formatDesc": formatted.FormatDesc, } w := tabwriter.NewWriter(s.Out, 0, 5, 3, ' ', tabwriter.TabIndent) - fmt.Fprintln(w, header) - - for _, task := range tasks.Items { - fmt.Fprintf(w, body, - task.Name, - formatted.FormatDesc(task.Spec.Description), - formatted.Age(&task.CreationTimestamp, p.Time()), - ) + t := template.Must(template.New("List Tasks").Funcs(funcMap).Parse(listTemplate)) + + err = t.Execute(w, data) + if err != nil { + return err } + return w.Flush() } diff --git a/pkg/cmd/task/list_test.go b/pkg/cmd/task/list_test.go index d9757308ae..371a710912 100644 --- a/pkg/cmd/task/list_test.go +++ b/pkg/cmd/task/list_test.go @@ -68,7 +68,7 @@ func TestTaskList_Empty(t *testing.T) { if err != nil { t.Errorf("Unexpected error: %v", err) } - test.AssertOutput(t, emptyMsg+"\n", output) + test.AssertOutput(t, "No Tasks found\n", output) } func TestTaskList_Only_Tasks_v1alpha1(t *testing.T) { @@ -80,7 +80,7 @@ func TestTaskList_Only_Tasks_v1alpha1(t *testing.T) { tb.Task("bananas", "namespace", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), tb.Task("apples", "namespace", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), tb.Task("potatoes", "namespace", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), - tb.Task("onionss", "namespace", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + tb.Task("onions", "namespace", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), } ns := []*corev1.Namespace{ @@ -154,7 +154,7 @@ func TestTaskList_Only_Tasks_v1beta1(t *testing.T) { cs, _ := test.SeedTestData(t, pipelinetest.Data{Tasks: tasks, Namespaces: ns}) p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dynamic} - cs.Pipeline.Resources = cb.APIResourceList("v1beta1", []string{"task"}) + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"task"}) task := Command(p) output, err := test.ExecuteCommand(task, "list", "-n", "namespace") @@ -164,3 +164,152 @@ func TestTaskList_Only_Tasks_v1beta1(t *testing.T) { golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) } + +func TestTaskList_Only_Tasks_no_headers_v1beta1(t *testing.T) { + clock := clockwork.NewFakeClock() + + tasks := []*v1alpha1.Task{ + tb.Task("tomatoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-1*time.Minute))), + tb.Task("mangoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-20*time.Second))), + tb.Task("bananas", "namespace", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), + tb.Task("apples", "namespace", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), + tb.Task("potatoes", "namespace", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), + tb.Task("onions", "namespace", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + } + + ns := []*corev1.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "namespace", + }, + }, + } + + version := "v1beta1" + tdc := testDynamic.Options{} + dynamic, err := tdc.Client( + cb.UnstructuredT(tasks[0], version), + cb.UnstructuredT(tasks[1], version), + cb.UnstructuredT(tasks[2], version), + cb.UnstructuredT(tasks[3], version), + cb.UnstructuredT(tasks[4], version), + cb.UnstructuredT(tasks[5], version), + ) + if err != nil { + t.Errorf("unable to create dynamic client: %v", err) + } + + cs, _ := test.SeedTestData(t, pipelinetest.Data{Tasks: tasks, Namespaces: ns}) + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dynamic} + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"task"}) + task := Command(p) + + output, err := test.ExecuteCommand(task, "list", "-n", "namespace", "--no-headers") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} + +func TestTaskList_Only_Tasks_all_namespaces_v1beta1(t *testing.T) { + clock := clockwork.NewFakeClock() + + tasks := []*v1alpha1.Task{ + tb.Task("tomatoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-1*time.Minute))), + tb.Task("mangoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-20*time.Second))), + tb.Task("bananas", "namespace", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), + tb.Task("apples", "namespace", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), + tb.Task("potatoes", "namespace", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), + tb.Task("onions", "namespace", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + tb.Task("tomates", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-1*time.Minute))), + tb.Task("mangues", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-20*time.Second))), + tb.Task("bananes", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), + tb.Task("pommes", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), + tb.Task("patates", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), + tb.Task("oignons", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + } + + version := "v1beta1" + tdc := testDynamic.Options{} + dynamic, err := tdc.Client( + cb.UnstructuredT(tasks[0], version), + cb.UnstructuredT(tasks[1], version), + cb.UnstructuredT(tasks[2], version), + cb.UnstructuredT(tasks[3], version), + cb.UnstructuredT(tasks[4], version), + cb.UnstructuredT(tasks[5], version), + cb.UnstructuredT(tasks[6], version), + cb.UnstructuredT(tasks[7], version), + cb.UnstructuredT(tasks[8], version), + cb.UnstructuredT(tasks[9], version), + cb.UnstructuredT(tasks[10], version), + cb.UnstructuredT(tasks[11], version), + ) + if err != nil { + t.Errorf("unable to create dynamic client: %v", err) + } + + cs, _ := test.SeedTestData(t, pipelinetest.Data{Tasks: tasks}) + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dynamic} + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"task"}) + task := Command(p) + + output, err := test.ExecuteCommand(task, "list", "--all-namespaces") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} + +func TestTaskList_Only_Tasks_all_namespaces_no_headers_v1beta1(t *testing.T) { + clock := clockwork.NewFakeClock() + + tasks := []*v1alpha1.Task{ + tb.Task("tomatoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-1*time.Minute))), + tb.Task("mangoes", "namespace", cb.TaskCreationTime(clock.Now().Add(-20*time.Second))), + tb.Task("bananas", "namespace", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), + tb.Task("apples", "namespace", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), + tb.Task("potatoes", "namespace", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), + tb.Task("onions", "namespace", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + tb.Task("tomates", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-1*time.Minute))), + tb.Task("mangues", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-20*time.Second))), + tb.Task("bananes", "espace-de-nom", cb.TaskCreationTime(clock.Now().Add(-512*time.Hour))), + tb.Task("pommes", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("")), cb.TaskCreationTime(clock.Now().Add(-513*time.Hour))), + tb.Task("patates", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("a test task")), cb.TaskCreationTime(clock.Now().Add(-514*time.Hour))), + tb.Task("oignons", "espace-de-nom", tb.TaskSpec(tb.TaskDescription("a test task to test description of task")), cb.TaskCreationTime(clock.Now().Add(-515*time.Hour))), + } + + version := "v1beta1" + tdc := testDynamic.Options{} + dynamic, err := tdc.Client( + cb.UnstructuredT(tasks[0], version), + cb.UnstructuredT(tasks[1], version), + cb.UnstructuredT(tasks[2], version), + cb.UnstructuredT(tasks[3], version), + cb.UnstructuredT(tasks[4], version), + cb.UnstructuredT(tasks[5], version), + cb.UnstructuredT(tasks[6], version), + cb.UnstructuredT(tasks[7], version), + cb.UnstructuredT(tasks[8], version), + cb.UnstructuredT(tasks[9], version), + cb.UnstructuredT(tasks[10], version), + cb.UnstructuredT(tasks[11], version), + ) + if err != nil { + t.Errorf("unable to create dynamic client: %v", err) + } + + cs, _ := test.SeedTestData(t, pipelinetest.Data{Tasks: tasks}) + p := &test.Params{Tekton: cs.Pipeline, Clock: clock, Kube: cs.Kube, Dynamic: dynamic} + cs.Pipeline.Resources = cb.APIResourceList(version, []string{"task"}) + task := Command(p) + + output, err := test.ExecuteCommand(task, "list", "--all-namespaces", "--no-headers") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + golden.Assert(t, output, fmt.Sprintf("%s.golden", t.Name())) +} diff --git a/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_no_headers_v1beta1.golden b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_no_headers_v1beta1.golden new file mode 100644 index 0000000000..c416dafe34 --- /dev/null +++ b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_no_headers_v1beta1.golden @@ -0,0 +1,12 @@ +namespace tomatoes 1 minute ago +namespace mangoes 20 seconds ago +namespace bananas 3 weeks ago +namespace apples 3 weeks ago +namespace potatoes a test task 3 weeks ago +namespace onions a test task to test... 3 weeks ago +espace-de-nom tomates 1 minute ago +espace-de-nom mangues 20 seconds ago +espace-de-nom bananes 3 weeks ago +espace-de-nom pommes 3 weeks ago +espace-de-nom patates a test task 3 weeks ago +espace-de-nom oignons a test task to test... 3 weeks ago diff --git a/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_v1beta1.golden b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_v1beta1.golden new file mode 100644 index 0000000000..a612853671 --- /dev/null +++ b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_all_namespaces_v1beta1.golden @@ -0,0 +1,13 @@ +NAMESPACE NAME DESCRIPTION AGE +namespace tomatoes 1 minute ago +namespace mangoes 20 seconds ago +namespace bananas 3 weeks ago +namespace apples 3 weeks ago +namespace potatoes a test task 3 weeks ago +namespace onions a test task to test... 3 weeks ago +espace-de-nom tomates 1 minute ago +espace-de-nom mangues 20 seconds ago +espace-de-nom bananes 3 weeks ago +espace-de-nom pommes 3 weeks ago +espace-de-nom patates a test task 3 weeks ago +espace-de-nom oignons a test task to test... 3 weeks ago diff --git a/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_no_headers_v1beta1.golden b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_no_headers_v1beta1.golden new file mode 100644 index 0000000000..143ee82486 --- /dev/null +++ b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_no_headers_v1beta1.golden @@ -0,0 +1,6 @@ +tomatoes 1 minute ago +mangoes 20 seconds ago +bananas 3 weeks ago +apples 3 weeks ago +potatoes a test task 3 weeks ago +onions a test task to test... 3 weeks ago diff --git a/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_v1alpha1.golden b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_v1alpha1.golden index ff901f0af3..ae6771fbd1 100644 --- a/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_v1alpha1.golden +++ b/pkg/cmd/task/testdata/TestTaskList_Only_Tasks_v1alpha1.golden @@ -4,4 +4,4 @@ mangoes 20 seconds ago bananas 3 weeks ago apples 3 weeks ago potatoes a test task 3 weeks ago -onionss a test task to test... 3 weeks ago +onions a test task to test... 3 weeks ago diff --git a/test/e2e/pipeline_e2e_test.go b/test/e2e/pipeline_e2e_test.go index f37dc09764..f8e3f844d8 100644 --- a/test/e2e/pipeline_e2e_test.go +++ b/test/e2e/pipeline_e2e_test.go @@ -114,7 +114,7 @@ func TestPipelinesE2E(t *testing.T) { res.Assert(t, icmd.Expected{ ExitCode: 0, - Out: "No pipelines\n", + Out: "No Pipelines found\n", Err: icmd.None, }) }) @@ -359,7 +359,7 @@ func TestPipelinesNegativeE2E(t *testing.T) { res.Assert(t, icmd.Expected{ ExitCode: 0, - Out: "No pipelines\n", + Out: "No Pipelines found\n", Err: icmd.None, }) }) @@ -575,7 +575,7 @@ func TestDeletePipelinesE2E(t *testing.T) { res.Assert(t, icmd.Expected{ ExitCode: 0, - Out: "No pipelines\n", + Out: "No Pipelines found\n", Err: icmd.None, }) })