diff --git a/cmd/cue/cmd/custom.go b/cmd/cue/cmd/custom.go index 22e5a7986..5ab3cdfb1 100644 --- a/cmd/cue/cmd/custom.go +++ b/cmd/cue/cmd/custom.go @@ -283,13 +283,23 @@ func executeTasks(cmd *Command, typ, command string, inst *cue.Instance) (err er exitIfErr(cmd, inst, err, true) } + visited := make(map[string]bool) task.Walk(func(v cue.Value) bool { if v == task { return true } - if after.Err() == nil && v.Equals(after) { - return false + + // Prevent inifinite walks + _, vPath := v.Reference() + if vPath != nil { + vPath := string(keyForReference(vPath...)) + _, isVisited := visited[vPath] + if isVisited { + return false + } + visited[vPath] = true } + for _, r := range appendReferences(nil, cr.root, v) { if dep := cr.findTask(r); dep != nil && t != dep { // TODO(string): consider adding dependencies diff --git a/cmd/cue/cmd/testdata/script/cmd_dep_cycle.txt b/cmd/cue/cmd/testdata/script/cmd_dep_cycle.txt new file mode 100644 index 000000000..56f6cfd04 --- /dev/null +++ b/cmd/cue/cmd/testdata/script/cmd_dep_cycle.txt @@ -0,0 +1,33 @@ +! cue cmd cycle +cmp stderr expect-stderr +! cue cmd aftercycle +cmp stderr expect-stderr +cue cmd interlockedTasks +cmp stdout interlocked-stdout + +-- expect-stderr -- +cyclic dependency in tasks +-- interlocked-stdout -- +v +v +-- after_tool.cue -- +package home + +import ( + "tool/cli" +) + +command: interlockedTasks: { + t1: cli.Print & { text: ref.value, ref: t2, value: "v" } + t2: cli.Print & { text: ref.value, ref: t1, value: "v" } +} + +command: aftercycle: { + t1: cli.Print & { $after: t2, text: "t1" } + t2: cli.Print & { $after: t1, text: "t2" } +} + +command: cycle: { + t1: cli.Print & { text: t2.text } + t2: cli.Print & { text: t1.text } +}