diff --git a/load/dependencyresolver.go b/load/dependencyresolver.go index 8f7a0dadf..300006c23 100644 --- a/load/dependencyresolver.go +++ b/load/dependencyresolver.go @@ -59,18 +59,23 @@ func ResolveDependencies(ctx context.Context, g *graph.Graph) (*graph.Graph, err out.Connect(meta.ID, dep) } } + return nil }) } -func getDepends(_ *graph.Graph, id string, node *parse.Node) ([]string, error) { +func getDepends(g *graph.Graph, id string, node *parse.Node) ([]string, error) { deps, err := node.GetStringSlice("depends") switch err { case parse.ErrNotFound: return []string{}, nil case nil: - for idx := range deps { - deps[idx] = graph.SiblingID(id, deps[idx]) + for idx, dep := range deps { + if ancestor, ok := getNearestAncestor(g, id, dep); ok { + deps[idx] = ancestor + } else { + return nil, fmt.Errorf("nonexistent vertices in edges: %s", dep) + } } return deps, nil default: diff --git a/load/dependencyresolver_test.go b/load/dependencyresolver_test.go index c28e58990..6afc064d7 100644 --- a/load/dependencyresolver_test.go +++ b/load/dependencyresolver_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" ) +// TestDependencyResolverResolvesDependencies tests dependency resolution func TestDependencyResolverResolvesDependencies(t *testing.T) { defer logging.HideLogs(t)() @@ -40,6 +41,23 @@ func TestDependencyResolverResolvesDependencies(t *testing.T) { ) } +// TestDependencyResolverResolvesExplicitDepsInBranch tests explicit +// dependencies inside of case branch nodes +func TestDependencyResolverResolvesExplicitDepsInBranch(t *testing.T) { + defer logging.HideLogs(t)() + + nodes, err := load.Nodes(context.Background(), "../samples/conditionalDeps.hcl", false) + require.NoError(t, err) + + resolved, err := load.ResolveDependencies(context.Background(), nodes) + assert.NoError(t, err) + assert.Contains( + t, + graph.Targets(resolved.DownEdges("root/macro.switch.sample/macro.case.true/file.content.foo-output")), + "root/task.query.foo", + ) +} + func TestDependencyResolverBadDependency(t *testing.T) { defer logging.HideLogs(t)() @@ -48,7 +66,7 @@ func TestDependencyResolverBadDependency(t *testing.T) { _, err = load.ResolveDependencies(context.Background(), nodes) if assert.Error(t, err) { - assert.EqualError(t, err, "nonexistent vertices in edges: root/task.nonexistent") + assert.EqualError(t, err, "1 error(s) occurred:\n\n* root/task.bad_requirement: nonexistent vertices in edges: task.nonexistent") } } diff --git a/samples/conditionalDeps.hcl b/samples/conditionalDeps.hcl new file mode 100644 index 000000000..f82e447eb --- /dev/null +++ b/samples/conditionalDeps.hcl @@ -0,0 +1,26 @@ +task.query "foo" { + query = "echo foo" +} + +task.query "bar" { + query = "echo bar" +} + +switch "sample" { + case "true" "true" { + task.query "baz" { + query = "echo baz" + } + + file.content "baz" { + destination = "baz-file.txt" + content = "{{lookup `task.query.baz.status.stdout`}}" + } + + file.content "foo-output" { + destination = "foo-file.txt" + content = "{{lookup `task.query.foo.status.stdout`}}" + depends = ["task.query.bar", "file.content.baz"] + } + } +} diff --git a/transform/control.go b/transform/control.go index a082de57f..647bad955 100644 --- a/transform/control.go +++ b/transform/control.go @@ -74,10 +74,6 @@ func getSwitchNode(id string, g *graph.Graph) (*control.SwitchTask, bool) { return nil, false } elem := elemMeta.Value() - elem, canResolve := resource.ResolveTask(elem) - if !canResolve { - return nil, false - } if asSwitch, ok := elem.(*control.SwitchTask); ok { return asSwitch, true } @@ -90,10 +86,6 @@ func getCaseNode(id string, g *graph.Graph) (*control.CaseTask, bool) { return nil, false } elem := elemMeta.Value() - elem, canResolve := resource.ResolveTask(elem) - if !canResolve { - return nil, false - } if asCase, ok := elem.(*control.CaseTask); ok { return asCase, true }