Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/cmd/tkn_pipeline_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].
```
Expand Down
2 changes: 2 additions & 0 deletions docs/cmd/tkn_task_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].
```
Expand Down
8 changes: 8 additions & 0 deletions docs/man/man1/tkn-pipeline-list.1
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions docs/man/man1/tkn-task-list.1
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
59 changes: 44 additions & 15 deletions pkg/cmd/pipeline/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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
}

Expand All @@ -79,44 +99,53 @@ 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()
Comment thread
waveywaves marked this conversation as resolved.
Outdated
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{
"accessMap": func(prs pipelineruns, name string) *v1alpha1.PipelineRun {
if pr, ok := prs[name]; ok {
return &pr
}

return nil
},
"formatAge": formatted.Age,
Expand Down
141 changes: 124 additions & 17 deletions pkg/cmd/pipeline/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment thread
waveywaves marked this conversation as resolved.
Outdated
}

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{
Expand All @@ -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(
Expand All @@ -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{
Expand All @@ -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(
Expand All @@ -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"
Expand Down Expand Up @@ -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})

Expand Down
Original file line number Diff line number Diff line change
@@ -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 --- --- --- ---
Original file line number Diff line number Diff line change
@@ -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 --- --- --- ---
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tomatoes 1 minute ago --- --- --- ---
mangoes 20 seconds ago --- --- --- ---
bananas 3 weeks ago --- --- --- ---
Loading