From f0768b3af191efa2a9ef32fba53262eaa914d02f Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Sat, 11 May 2019 11:06:47 -0300 Subject: [PATCH] Allow setting global variables through the CLI Closes #192 --- CHANGELOG.md | 5 +++++ cmd/task/task.go | 8 ++++---- docs/usage.md | 8 +++++++- internal/args/args.go | 37 ++++++++++++++++++++++--------------- internal/args/args_test.go | 28 +++++++++++++++++----------- 5 files changed, 55 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ada22a19..766f35ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +- Allow setting global variables through the CLI + ([#192](https://github.com/go-task/task/issues/192)). + ## 2.5.1 - 2019-04-27 - Fixed some issues with interactive command line tools, where sometimes diff --git a/cmd/task/task.go b/cmd/task/task.go index 2e853580..4070e1b9 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -121,9 +121,9 @@ func main() { arguments = []string{"default"} } - calls, err := args.Parse(arguments...) - if err != nil { - log.Fatal(err) + calls, globals := args.Parse(arguments...) + for name, value := range globals { + e.Taskfile.Vars[name] = value } ctx := context.Background() @@ -132,7 +132,7 @@ func main() { } if status { - if err = e.Status(ctx, calls...); err != nil { + if err := e.Status(ctx, calls...); err != nil { log.Fatal(err) } return diff --git a/docs/usage.md b/docs/usage.md index fd597ec9..40c3dd4a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -371,6 +371,12 @@ right before. $ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!" ``` +If you want to set global variables using this syntax, give it before any task: + +```bash +$ task OUTPUT=file.txt generate-file +``` + Example of locally declared vars: ```yaml @@ -582,7 +588,7 @@ dependencies: commands: - your-release-tool ``` -If a summary is missing, the description will be printed. +If a summary is missing, the description will be printed. If the task does not have a summary or a description, a warning is printed. Please note: *showing the summary will not execute the command*. diff --git a/internal/args/args.go b/internal/args/args.go index da731891..0993e549 100644 --- a/internal/args/args.go +++ b/internal/args/args.go @@ -1,36 +1,43 @@ package args import ( - "errors" "strings" "github.com/go-task/task/v2/internal/taskfile" ) -var ( - // ErrVariableWithoutTask is returned when variables are given before any task - ErrVariableWithoutTask = errors.New("task: variable given before any task") -) - // Parse parses command line argument: tasks and vars of each task -func Parse(args ...string) ([]taskfile.Call, error) { +func Parse(args ...string) ([]taskfile.Call, taskfile.Vars) { var calls []taskfile.Call + var globals taskfile.Vars for _, arg := range args { if !strings.Contains(arg, "=") { calls = append(calls, taskfile.Call{Task: arg}) continue } + if len(calls) < 1 { - return nil, ErrVariableWithoutTask - } + if globals == nil { + globals = taskfile.Vars{} + } - if calls[len(calls)-1].Vars == nil { - calls[len(calls)-1].Vars = make(taskfile.Vars) - } + name, value := splitVar(arg) + globals[name] = taskfile.Var{Static: value} + } else { + if calls[len(calls)-1].Vars == nil { + calls[len(calls)-1].Vars = make(taskfile.Vars) + } - pair := strings.SplitN(arg, "=", 2) - calls[len(calls)-1].Vars[pair[0]] = taskfile.Var{Static: pair[1]} + name, value := splitVar((arg)) + calls[len(calls)-1].Vars[name] = taskfile.Var{Static: value} + } } - return calls, nil + + return calls, globals +} + +func splitVar(s string) (string, string) { + pair := strings.SplitN(s, "=", 2) + return pair[0], pair[1] } diff --git a/internal/args/args_test.go b/internal/args/args_test.go index 86b230fb..137c23e3 100644 --- a/internal/args/args_test.go +++ b/internal/args/args_test.go @@ -12,13 +12,13 @@ import ( func TestArgs(t *testing.T) { tests := []struct { - Args []string - Expected []taskfile.Call - Err error + Args []string + ExpectedCalls []taskfile.Call + ExpectedGlobals taskfile.Vars }{ { Args: []string{"task-a", "task-b", "task-c"}, - Expected: []taskfile.Call{ + ExpectedCalls: []taskfile.Call{ {Task: "task-a"}, {Task: "task-b"}, {Task: "task-c"}, @@ -26,7 +26,7 @@ func TestArgs(t *testing.T) { }, { Args: []string{"task-a", "FOO=bar", "task-b", "task-c", "BAR=baz", "BAZ=foo"}, - Expected: []taskfile.Call{ + ExpectedCalls: []taskfile.Call{ { Task: "task-a", Vars: taskfile.Vars{ @@ -45,7 +45,7 @@ func TestArgs(t *testing.T) { }, { Args: []string{"task-a", "CONTENT=with some spaces"}, - Expected: []taskfile.Call{ + ExpectedCalls: []taskfile.Call{ { Task: "task-a", Vars: taskfile.Vars{ @@ -55,16 +55,22 @@ func TestArgs(t *testing.T) { }, }, { - Args: []string{"FOO=bar", "task-a"}, - Err: args.ErrVariableWithoutTask, + Args: []string{"FOO=bar", "task-a", "task-b"}, + ExpectedCalls: []taskfile.Call{ + {Task: "task-a"}, + {Task: "task-b"}, + }, + ExpectedGlobals: taskfile.Vars{ + "FOO": {Static: "bar"}, + }, }, } for i, test := range tests { t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) { - calls, err := args.Parse(test.Args...) - assert.Equal(t, test.Err, err) - assert.Equal(t, test.Expected, calls) + calls, globals := args.Parse(test.Args...) + assert.Equal(t, test.ExpectedCalls, calls) + assert.Equal(t, test.ExpectedGlobals, globals) }) } }