Compare commits

..

16 Commits

Author SHA1 Message Date
Andrey Nering
6ff9ba9df9 v2.5.2 2019-05-11 11:28:21 -03:00
Andrey Nering
b2df398a12 go mod vendor 2019-05-11 11:22:47 -03:00
Andrey Nering
83d618e1eb Revert "Upgrade to yaml/go-yaml v3"
This reverts commit 8001fb3915.
2019-05-11 11:22:13 -03:00
Andrey Nering
f0768b3af1 Allow setting global variables through the CLI
Closes #192
2019-05-11 11:06:47 -03:00
Andrey Nering
0233ce52ed v2.5.1 2019-04-27 17:56:30 -03:00
Andrey Nering
6e6f337509 Updated change log 2019-04-27 17:28:58 -03:00
Andrey Nering
1546415b8f Update CHANGELOG.md 2019-04-21 17:16:35 -03:00
Andrey Nering
20725c69bf Merge pull request #200 from go-task/fix-output-issues
Fixes some bugs relatated to commands output handling
2019-04-21 17:05:21 -03:00
Andrey Nering
90613220c6 Fixes some bugs relatated to commands output handling
This seems to fix some of the bugs reported by issues like #114 and #190.

Seems that the standard library's os/exec package has some black magic to
detect if a writer is an actual *os.File, and some stuff are handled
differently, then.

Fixes #114
Fixes #190
2019-04-21 16:55:47 -03:00
Andrey Nering
659fd2ae93 Update Go version on CI 2019-04-13 17:44:55 -03:00
Andrey Nering
29d899f7da Merge pull request #198 from go-task/yaml-v3
Upgrade to go-yaml/yaml v3
2019-04-13 17:29:36 -03:00
Andrey Nering
902a0a01a9 go vendor mod 2019-04-13 17:26:27 -03:00
Andrey Nering
8001fb3915 Upgrade to yaml/go-yaml v3 2019-04-13 17:25:28 -03:00
Andrey Nering
e81e2802f0 Small fix to redirector 2019-03-23 17:48:18 -03:00
Andrey Nering
1ee066ec42 Merge pull request #188 from sosiska/patch-1
Rewrite if-else chain to switch statement
2019-03-23 17:04:31 -03:00
Kirill Motkov
53d54d1c4a Rewrite if-else chain to switch statement 2019-03-19 14:19:21 +03:00
13 changed files with 92 additions and 62 deletions

View File

@@ -1,8 +1,8 @@
language: go language: go
go: go:
- 1.10.x
- 1.11.x - 1.11.x
- 1.12.x
addons: addons:
apt: apt:

View File

@@ -1,6 +1,20 @@
# Changelog # Changelog
## v2.5.0 = 2019-03-16 ## v2.5.2 - 2019-05-11
- Reverted YAML upgrade due issues with CRLF on Windows
([#201](https://github.com/go-task/task/issues/201), [go-yaml/yaml#450](https://github.com/go-yaml/yaml/issues/450)).
- 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
the output were not being shown, and similar issues
([#114](https://github.com/go-task/task/issues/114), [#190](https://github.com/go-task/task/issues/190), [#200](https://github.com/go-task/task/pull/200)).
- Upgraded [go-yaml/yaml](https://github.com/go-yaml/yaml) from v2 to v3.
## v2.5.0 - 2019-03-16
- We moved from the taskfile.org domain to the new fancy taskfile.dev domain. - We moved from the taskfile.org domain to the new fancy taskfile.dev domain.
While stuff is being redirected, we strongly recommend to everyone that use While stuff is being redirected, we strongly recommend to everyone that use

View File

@@ -1,5 +1,3 @@
//+build ignore
// This small web app is used to redirect from the old taskfile.org domain // This small web app is used to redirect from the old taskfile.org domain
// to the new taskfile.dev without breaking CIs that uses cURL to download // to the new taskfile.dev without breaking CIs that uses cURL to download
// "/install.sh" without the -L flag (which follow redirects). // "/install.sh" without the -L flag (which follow redirects).
@@ -19,9 +17,9 @@ func main() {
return return
} }
println("Redirecting to taskfile.dev") println("Redirecting to https://taskfile.dev" + r.URL.Path)
w.Header().Set("Location", "https://taskfile.dev") w.Header().Set("Location", "https://taskfile.dev"+r.URL.Path)
w.WriteHeader(301) w.WriteHeader(301)
}) })

View File

@@ -121,9 +121,9 @@ func main() {
arguments = []string{"default"} arguments = []string{"default"}
} }
calls, err := args.Parse(arguments...) calls, globals := args.Parse(arguments...)
if err != nil { for name, value := range globals {
log.Fatal(err) e.Taskfile.Vars[name] = value
} }
ctx := context.Background() ctx := context.Background()
@@ -132,7 +132,7 @@ func main() {
} }
if status { if status {
if err = e.Status(ctx, calls...); err != nil { if err := e.Status(ctx, calls...); err != nil {
log.Fatal(err) log.Fatal(err)
} }
return return

View File

@@ -371,6 +371,12 @@ right before.
$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!" $ 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: Example of locally declared vars:
```yaml ```yaml

View File

@@ -1,36 +1,43 @@
package args package args
import ( import (
"errors"
"strings" "strings"
"github.com/go-task/task/v2/internal/taskfile" "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 // 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 calls []taskfile.Call
var globals taskfile.Vars
for _, arg := range args { for _, arg := range args {
if !strings.Contains(arg, "=") { if !strings.Contains(arg, "=") {
calls = append(calls, taskfile.Call{Task: arg}) calls = append(calls, taskfile.Call{Task: arg})
continue continue
} }
if len(calls) < 1 { if len(calls) < 1 {
return nil, ErrVariableWithoutTask if globals == nil {
} globals = taskfile.Vars{}
}
if calls[len(calls)-1].Vars == nil { name, value := splitVar(arg)
calls[len(calls)-1].Vars = make(taskfile.Vars) 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) name, value := splitVar((arg))
calls[len(calls)-1].Vars[pair[0]] = taskfile.Var{Static: pair[1]} 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]
} }

View File

@@ -12,13 +12,13 @@ import (
func TestArgs(t *testing.T) { func TestArgs(t *testing.T) {
tests := []struct { tests := []struct {
Args []string Args []string
Expected []taskfile.Call ExpectedCalls []taskfile.Call
Err error ExpectedGlobals taskfile.Vars
}{ }{
{ {
Args: []string{"task-a", "task-b", "task-c"}, Args: []string{"task-a", "task-b", "task-c"},
Expected: []taskfile.Call{ ExpectedCalls: []taskfile.Call{
{Task: "task-a"}, {Task: "task-a"},
{Task: "task-b"}, {Task: "task-b"},
{Task: "task-c"}, {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"}, Args: []string{"task-a", "FOO=bar", "task-b", "task-c", "BAR=baz", "BAZ=foo"},
Expected: []taskfile.Call{ ExpectedCalls: []taskfile.Call{
{ {
Task: "task-a", Task: "task-a",
Vars: taskfile.Vars{ Vars: taskfile.Vars{
@@ -45,7 +45,7 @@ func TestArgs(t *testing.T) {
}, },
{ {
Args: []string{"task-a", "CONTENT=with some spaces"}, Args: []string{"task-a", "CONTENT=with some spaces"},
Expected: []taskfile.Call{ ExpectedCalls: []taskfile.Call{
{ {
Task: "task-a", Task: "task-a",
Vars: taskfile.Vars{ Vars: taskfile.Vars{
@@ -55,16 +55,22 @@ func TestArgs(t *testing.T) {
}, },
}, },
{ {
Args: []string{"FOO=bar", "task-a"}, Args: []string{"FOO=bar", "task-a", "task-b"},
Err: args.ErrVariableWithoutTask, ExpectedCalls: []taskfile.Call{
{Task: "task-a"},
{Task: "task-b"},
},
ExpectedGlobals: taskfile.Vars{
"FOO": {Static: "bar"},
},
}, },
} }
for i, test := range tests { for i, test := range tests {
t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) {
calls, err := args.Parse(test.Args...) calls, globals := args.Parse(test.Args...)
assert.Equal(t, test.Err, err) assert.Equal(t, test.ExpectedCalls, calls)
assert.Equal(t, test.Expected, calls) assert.Equal(t, test.ExpectedGlobals, globals)
}) })
} }
} }

View File

@@ -7,7 +7,7 @@ import (
type Group struct{} type Group struct{}
func (Group) WrapWriter(w io.Writer, _ string) io.WriteCloser { func (Group) WrapWriter(w io.Writer, _ string) io.Writer {
return &groupWriter{writer: w} return &groupWriter{writer: w}
} }

View File

@@ -6,18 +6,6 @@ import (
type Interleaved struct{} type Interleaved struct{}
func (Interleaved) WrapWriter(w io.Writer, _ string) io.WriteCloser { func (Interleaved) WrapWriter(w io.Writer, _ string) io.Writer {
return nopWriterCloser{w: w} return w
}
type nopWriterCloser struct {
w io.Writer
}
func (wc nopWriterCloser) Write(p []byte) (int, error) {
return wc.w.Write(p)
}
func (wc nopWriterCloser) Close() error {
return nil
} }

View File

@@ -5,5 +5,5 @@ import (
) )
type Output interface { type Output interface {
WrapWriter(w io.Writer, prefix string) io.WriteCloser WrapWriter(w io.Writer, prefix string) io.Writer
} }

View File

@@ -3,6 +3,7 @@ package output_test
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"testing" "testing"
"github.com/go-task/task/v2/internal/output" "github.com/go-task/task/v2/internal/output"
@@ -24,7 +25,7 @@ func TestInterleaved(t *testing.T) {
func TestGroup(t *testing.T) { func TestGroup(t *testing.T) {
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Group{} var o output.Output = output.Group{}
var w = o.WrapWriter(&b, "") var w = o.WrapWriter(&b, "").(io.WriteCloser)
fmt.Fprintln(w, "foo\nbar") fmt.Fprintln(w, "foo\nbar")
assert.Equal(t, "", b.String()) assert.Equal(t, "", b.String())
@@ -37,7 +38,7 @@ func TestGroup(t *testing.T) {
func TestPrefixed(t *testing.T) { func TestPrefixed(t *testing.T) {
var b bytes.Buffer var b bytes.Buffer
var o output.Output = output.Prefixed{} var o output.Output = output.Prefixed{}
var w = o.WrapWriter(&b, "prefix") var w = o.WrapWriter(&b, "prefix").(io.WriteCloser)
t.Run("simple use cases", func(t *testing.T) { t.Run("simple use cases", func(t *testing.T) {
b.Reset() b.Reset()

View File

@@ -9,7 +9,7 @@ import (
type Prefixed struct{} type Prefixed struct{}
func (Prefixed) WrapWriter(w io.Writer, prefix string) io.WriteCloser { func (Prefixed) WrapWriter(w io.Writer, prefix string) io.Writer {
return &prefixWriter{writer: w, prefix: prefix} return &prefixWriter{writer: w, prefix: prefix}
} }
@@ -34,12 +34,12 @@ func (pw *prefixWriter) Close() error {
func (pw *prefixWriter) writeOutputLines(force bool) error { func (pw *prefixWriter) writeOutputLines(force bool) error {
for { for {
line, err := pw.buff.ReadString('\n') switch line, err := pw.buff.ReadString('\n'); err {
if err == nil { case nil:
if err = pw.writeLine(line); err != nil { if err = pw.writeLine(line); err != nil {
return err return err
} }
} else if err == io.EOF { case io.EOF:
// if this line was not a complete line, re-add to the buffer // if this line was not a complete line, re-add to the buffer
if !force && !strings.HasSuffix(line, "\n") { if !force && !strings.HasSuffix(line, "\n") {
_, err = pw.buff.WriteString(line) _, err = pw.buff.WriteString(line)
@@ -47,7 +47,7 @@ func (pw *prefixWriter) writeOutputLines(force bool) error {
} }
return pw.writeLine(line) return pw.writeLine(line)
} else { default:
return err return err
} }
} }

14
task.go
View File

@@ -248,8 +248,18 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi
stdOut := e.Output.WrapWriter(e.Stdout, t.Prefix) stdOut := e.Output.WrapWriter(e.Stdout, t.Prefix)
stdErr := e.Output.WrapWriter(e.Stderr, t.Prefix) stdErr := e.Output.WrapWriter(e.Stderr, t.Prefix)
defer stdOut.Close() defer func() {
defer stdErr.Close() if _, ok := stdOut.(*os.File); !ok {
if closer, ok := stdOut.(io.Closer); ok {
closer.Close()
}
}
if _, ok := stdErr.(*os.File); !ok {
if closer, ok := stdErr.(io.Closer); ok {
closer.Close()
}
}
}()
err := execext.RunCommand(ctx, &execext.RunCommandOptions{ err := execext.RunCommand(ctx, &execext.RunCommandOptions{
Command: cmd.Cmd, Command: cmd.Cmd,