Skip to content

Commit fb4b0a1

Browse files
committed
Merge branch 'issue-37-cyclic-dep'
2 parents 9bea80b + ac48ee0 commit fb4b0a1

File tree

4 files changed

+41
-20
lines changed

4 files changed

+41
-20
lines changed

cyclic.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
package task
22

3-
// HasCyclicDep checks if a task tree has any cyclic dependency
4-
func (e *Executor) HasCyclicDep() bool {
3+
// CheckCyclicDep checks if a task tree has any cyclic dependency
4+
func (e *Executor) CheckCyclicDep() error {
55
visits := make(map[string]struct{}, len(e.Tasks))
66

7-
var checkCyclicDep func(string, *Task) bool
8-
checkCyclicDep = func(name string, t *Task) bool {
7+
var checkCyclicDep func(string, *Task) error
8+
checkCyclicDep = func(name string, t *Task) error {
99
if _, ok := visits[name]; ok {
10-
return false
10+
return ErrCyclicDepDetected
1111
}
1212
visits[name] = struct{}{}
1313
defer delete(visits, name)
1414

1515
for _, d := range t.Deps {
16-
if !checkCyclicDep(d.Task, e.Tasks[d.Task]) {
17-
return false
16+
// FIXME: ignoring by now. should return an error instead?
17+
task, ok := e.Tasks[d.Task]
18+
if !ok {
19+
continue
20+
}
21+
if err := checkCyclicDep(d.Task, task); err != nil {
22+
return err
1823
}
1924
}
20-
return true
25+
return nil
2126
}
2227

2328
for k, v := range e.Tasks {
24-
if !checkCyclicDep(k, v) {
25-
return true
29+
if err := checkCyclicDep(k, v); err != nil {
30+
return err
2631
}
2732
}
28-
return false
33+
return nil
2934
}

cyclic_test.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"testing"
55

66
"github.com/go-task/task"
7+
8+
"github.com/stretchr/testify/assert"
79
)
810

911
func TestCyclicDepCheck(t *testing.T) {
@@ -18,9 +20,7 @@ func TestCyclicDepCheck(t *testing.T) {
1820
},
1921
}
2022

21-
if !isCyclic.HasCyclicDep() {
22-
t.Error("Task should be cyclic")
23-
}
23+
assert.Equal(t, task.ErrCyclicDepDetected, isCyclic.CheckCyclicDep(), "task should be cyclic")
2424

2525
isNotCyclic := &task.Executor{
2626
Tasks: task.Tasks{
@@ -34,7 +34,23 @@ func TestCyclicDepCheck(t *testing.T) {
3434
},
3535
}
3636

37-
if isNotCyclic.HasCyclicDep() {
38-
t.Error("Task should not be cyclic")
37+
assert.NoError(t, isNotCyclic.CheckCyclicDep())
38+
39+
inexixtentTask := &task.Executor{
40+
Tasks: task.Tasks{
41+
"task-a": &task.Task{
42+
Deps: []*task.Dep{&task.Dep{Task: "invalid-task"}},
43+
},
44+
},
3945
}
46+
47+
// FIXME: by now Task should ignore non existent tasks
48+
// in the future we should improve the detection of
49+
// tasks called with interpolation?
50+
// task:
51+
// deps:
52+
// - task: "task{{.VARIABLE}}"
53+
// vars:
54+
// VARIABLE: something
55+
assert.NoError(t, inexixtentTask.CheckCyclicDep())
4056
}

errors.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
)
77

88
var (
9-
// ErrCyclicDependencyDetected is returned when a cyclic dependency was found in the Taskfile
10-
ErrCyclicDependencyDetected = errors.New("task: cyclic dependency detected")
9+
// ErrCyclicDepDetected is returned when a cyclic dependency was found in the Taskfile
10+
ErrCyclicDepDetected = errors.New("task: cyclic dependency detected")
1111
// ErrTaskfileAlreadyExists is returned on creating a Taskfile if one already exists
1212
ErrTaskfileAlreadyExists = errors.New("task: A Taskfile already exists")
1313
)

task.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ type Task struct {
6161

6262
// Run runs Task
6363
func (e *Executor) Run(args ...string) error {
64-
if e.HasCyclicDep() {
65-
return ErrCyclicDependencyDetected
64+
if err := e.CheckCyclicDep(); err != nil {
65+
return err
6666
}
6767

6868
if e.Stdin == nil {

0 commit comments

Comments
 (0)