Skip to content

Commit

Permalink
Add a --filename parameter to 'tkn tasks start'.
Browse files Browse the repository at this point in the history
This parameter lets users specify a local task definition. tkn will then
inline that definition in the generated TaskRun, without creating it first.
This is useful for "as-code" scenarios and development.
  • Loading branch information
dlorenc authored and tekton-robot committed Nov 15, 2019
1 parent dd25a65 commit d6f2e11
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 10 deletions.
4 changes: 4 additions & 0 deletions docs/cmd/tkn_task_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@ Start tasks
# start task foo by creating a taskrun named "foo-run-xyz123" from the namespace "bar"
tkn task start foo -s ServiceAccountName -n bar

The task can either be specified by reference in a cluster using the positional argument
or in a file using the --filename argument.

For params value, if you want to provide multiple values, provide them comma separated
like cat,foo,bar


### Options

```
-f, --filename string filename containing a task definition
-h, --help help for start
-i, --inputresource strings pass the input resource name and ref as name=ref
-l, --labels strings pass labels as label=value.
Expand Down
8 changes: 8 additions & 0 deletions docs/man/man1/tkn-task-start.1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Start tasks


.SH OPTIONS
.PP
\fB\-f\fP, \fB\-\-filename\fP=""
filename containing a task definition

.PP
\fB\-h\fP, \fB\-\-help\fP[=false]
help for start
Expand Down Expand Up @@ -72,6 +76,10 @@ Start tasks
.PP
tkn task start foo \-s ServiceAccountName \-n bar

.PP
The task can either be specified by reference in a cluster using the positional argument
or in a file using the \-\-filename argument.

.PP
For params value, if you want to provide multiple values, provide them comma separated
like cat,foo,bar
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/cpuguy83/go-md2man v1.0.10
github.com/evanphx/json-patch v4.1.0+incompatible // indirect
github.com/fatih/color v1.7.0
github.com/ghodss/yaml v1.0.0
github.com/google/go-cmp v0.3.1
github.com/google/go-containerregistry v0.0.0-20190320210540-8d4083db9aa0 // indirect
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 // indirect
Expand Down
55 changes: 48 additions & 7 deletions pkg/cmd/task/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ package task
import (
"errors"
"fmt"
"io/ioutil"
"strings"

"github.com/ghodss/yaml"

"github.com/spf13/cobra"
"github.com/tektoncd/cli/pkg/cli"
"github.com/tektoncd/cli/pkg/cmd/taskrun"
Expand Down Expand Up @@ -48,6 +51,7 @@ type startOptions struct {
Last bool
Labels []string
ShowLog bool
Filename string
}

// NameArg validates that the first argument is a valid task name
Expand Down Expand Up @@ -90,6 +94,9 @@ func startCommand(p cli.Params) *cobra.Command {
# start task foo by creating a taskrun named "foo-run-xyz123" from the namespace "bar"
tkn task start foo -s ServiceAccountName -n bar
The task can either be specified by reference in a cluster using the positional argument
or in a file using the --filename argument.
For params value, if you want to provide multiple values, provide them comma separated
like cat,foo,bar
`,
Expand All @@ -98,15 +105,21 @@ like cat,foo,bar
if err := flags.InitParams(p, cmd); err != nil {
return err
}
return NameArg(args, p)
if len(args) != 0 {
return NameArg(args, p)
}
if opt.Filename == "" {
return errors.New("Either a task name or a --filename parameter must be supplied")
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
opt.stream = &cli.Stream{
Out: cmd.OutOrStdout(),
Err: cmd.OutOrStderr(),
}

return startTask(opt, args[0])
return startTask(opt, args)
},
}

Expand All @@ -118,22 +131,50 @@ like cat,foo,bar
c.Flags().BoolVarP(&opt.Last, "last", "L", false, "re-run the task using last taskrun values")
c.Flags().StringSliceVarP(&opt.Labels, "labels", "l", []string{}, "pass labels as label=value.")
c.Flags().BoolVarP(&opt.ShowLog, "showlog", "", true, "show logs right after starting the task")
c.Flags().StringVarP(&opt.Filename, "filename", "f", "", "filename containing a task definition")

_ = c.MarkZshCompPositionalArgumentCustom(1, "__tkn_get_task")

return c
}

func startTask(opt startOptions, tname string) error {
// Setting as var for stubbing in tests
var parseTask = func(p string) (*v1alpha1.Task, error) {
b, err := ioutil.ReadFile(p)
if err != nil {
return nil, err
}
task := v1alpha1.Task{}
if err := yaml.Unmarshal(b, &task); err != nil {
return nil, err
}
return &task, nil
}

func startTask(opt startOptions, args []string) error {
tr := &v1alpha1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Namespace: opt.cliparams.Namespace(),
GenerateName: tname + "-run-",
Namespace: opt.cliparams.Namespace(),
},
Spec: v1alpha1.TaskRunSpec{
}

var tname string
if len(args) > 0 {
tname = args[0]
tr.Spec = v1alpha1.TaskRunSpec{
TaskRef: &v1alpha1.TaskRef{Name: tname},
},
}
} else {
task, err := parseTask(opt.Filename)
if err != nil {
return err
}
tname = task.ObjectMeta.Name
tr.Spec = v1alpha1.TaskRunSpec{
TaskSpec: &task.Spec,
}
}
tr.ObjectMeta.GenerateName = tname + "-run-"

cs, err := opt.cliparams.Clients()
if err != nil {
Expand Down
27 changes: 25 additions & 2 deletions pkg/cmd/task/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,34 @@ func Test_start_has_task_arg(t *testing.T) {
c := Command(&test.Params{})

_, err := test.ExecuteCommand(c, "start", "-n", "ns")

if err == nil {
t.Error("Expecting an error but it's empty")
}
test.AssertOutput(t, "missing task name", err.Error())
test.AssertOutput(t, "Either a task name or a --filename parameter must be supplied", err.Error())
}

func Test_start_has_task_filename(t *testing.T) {
ns := []*corev1.Namespace{
{
ObjectMeta: metav1.ObjectMeta{
Name: "ns",
},
},
}
cs, _ := test.SeedTestData(t, pipelinetest.Data{Namespaces: ns})
c := Command(&test.Params{Tekton: cs.Pipeline, Kube: cs.Kube})

oldParseTask := parseTask
defer func() {
parseTask = oldParseTask
}()
parseTask = func(p string) (*v1alpha1.Task, error) {
return tb.Task("task", "ns"), nil
}
_, err := test.ExecuteCommand(c, "start", "-n", "ns", "--filename=foo", "--showlog=false")
if err != nil {
t.Errorf("Not expecting an error, but got %s", err)
}
}

func Test_start_task_not_found(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion test/resources/task-volume.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ metadata:
namespace: tektoncd
spec:
taskRef:
name: task-volume
name: task-volume

0 comments on commit d6f2e11

Please sign in to comment.