Skip to content

Commit baf96e2

Browse files
committed
feat: use primary-dependency attribute to find primary dependency of a task
Storing this on `from_deps` tasks allows us to avoid iterating over potentially all the task dependencies when finding it later, which can add up to a lot of time in larger graphs.
1 parent 5ffdbdb commit baf96e2

File tree

4 files changed

+68
-32
lines changed

4 files changed

+68
-32
lines changed

src/taskgraph/transforms/from_deps.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ def from_deps(config, tasks):
206206
)
207207

208208
primary_dep = [dep for dep in group if dep.kind == primary_kind][0]
209+
new_task["attributes"]["primary-dependency-label"] = primary_dep.label
209210

210211
if set_name:
211212
func = SET_NAME_MAP[set_name]

src/taskgraph/util/dependencies.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,9 @@ def get_dependencies(config: TransformConfig, task: Dict) -> Iterator[Task]:
6868

6969

7070
def get_primary_dependency(config: TransformConfig, task: Dict) -> Optional[Task]:
71-
"""Return the ``Task`` object associated with the primary dependency.
72-
73-
This uses the task's ``primary-kind-dependency`` attribute to find the primary
74-
dependency, or returns ``None`` if the attribute is unset.
71+
"""Return the ``Task`` object associated with the primary dependency,
72+
which is assumed to be available in the ``primary-dependency`` attribute.
73+
(Which is always the case for tasks created with ``from_deps``.)
7574
7675
Args:
7776
config (TransformConfig): The ``TransformConfig`` object associated
@@ -83,10 +82,7 @@ def get_primary_dependency(config: TransformConfig, task: Dict) -> Optional[Task
8382
primary dependency or ``None``.
8483
"""
8584
try:
86-
primary_kind = task["attributes"]["primary-kind-dependency"]
85+
label = task["attributes"]["primary-dependency-label"]
86+
return config.kind_dependencies_tasks[label]
8787
except KeyError:
8888
return None
89-
90-
for dep in get_dependencies(config, task):
91-
if dep.kind == primary_kind:
92-
return dep

test/test_transforms_from_deps.py

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,103 @@
33
"""
44

55
from pprint import pprint
6+
from typing import Dict
67

78
import pytest
89
from pytest_taskgraph import make_task
910

11+
from taskgraph.task import Task
1012
from taskgraph.transforms import from_deps
1113

1214

15+
def get_task_label_by_attributes(
16+
tasks: Dict[str, Task], attributes: Dict[str, str]
17+
) -> str:
18+
for task in tasks.values():
19+
if all([task.attributes[k] == v for k, v in attributes.items()]):
20+
return task.label
21+
22+
return ""
23+
24+
1325
def handle_exception(obj, exc=None):
1426
if exc:
1527
assert isinstance(obj, exc)
1628
elif isinstance(obj, Exception):
1729
raise obj
1830

1931

20-
def assert_no_kind_dependencies(e):
32+
def assert_no_kind_dependencies(_, e):
2133
handle_exception(e, exc=Exception)
2234

2335

24-
def assert_invalid_only_kinds(e):
36+
def assert_invalid_only_kinds(_, e):
2537
handle_exception(e, exc=Exception)
2638

2739

28-
def assert_defaults(tasks):
40+
def assert_defaults(deps, tasks):
2941
handle_exception(tasks)
3042
assert len(tasks) == 2
31-
assert tasks[0]["attributes"] == {"primary-kind-dependency": "foo"}
43+
assert tasks[0]["attributes"] == {
44+
"primary-kind-dependency": "foo",
45+
"primary-dependency-label": get_task_label_by_attributes(deps, {"kind": "foo"}),
46+
}
3247
assert tasks[0]["dependencies"] == {"foo": "a"}
3348
assert tasks[0]["name"] == "a"
34-
assert tasks[1]["attributes"] == {"primary-kind-dependency": "bar"}
49+
assert tasks[1]["attributes"] == {
50+
"primary-kind-dependency": "bar",
51+
"primary-dependency-label": get_task_label_by_attributes(deps, {"kind": "bar"}),
52+
}
3553
assert tasks[1]["dependencies"] == {"bar": "bar-b"}
3654
assert tasks[1]["name"] == "b"
3755

3856

3957
assert_group_by_single = assert_defaults
4058

4159

42-
def assert_group_by_attribute(tasks):
60+
def assert_group_by_attribute(deps, tasks):
4361
handle_exception(tasks)
4462
assert len(tasks) == 2
4563
assert tasks[0]["dependencies"] == {"foo": "a"}
46-
assert tasks[0]["attributes"] == {"primary-kind-dependency": "foo"}
64+
assert tasks[0]["attributes"] == {
65+
"primary-kind-dependency": "foo",
66+
"primary-dependency-label": get_task_label_by_attributes(
67+
deps, {"kind": "foo", "build-type": "linux"}
68+
),
69+
}
4770
assert tasks[1]["dependencies"] == {"foo": "b", "bar": "c"}
48-
assert tasks[1]["attributes"] == {"primary-kind-dependency": "foo"}
71+
assert tasks[1]["attributes"] == {
72+
"primary-kind-dependency": "foo",
73+
"primary-dependency-label": get_task_label_by_attributes(
74+
deps, {"kind": "foo", "build-type": "win"}
75+
),
76+
}
4977

5078

51-
def assert_group_by_attribute_dupe(e):
79+
def assert_group_by_attribute_dupe(_, e):
5280
handle_exception(e, exc=Exception)
5381

5482

55-
def assert_group_by_attribute_dupe_allowed(tasks):
83+
def assert_group_by_attribute_dupe_allowed(deps, tasks):
5684
handle_exception(tasks)
5785
assert len(tasks) == 2
5886
assert tasks[0]["dependencies"] == {"a": "a"}
59-
assert tasks[0]["attributes"] == {"primary-kind-dependency": "foo"}
87+
assert tasks[0]["attributes"] == {
88+
"primary-kind-dependency": "foo",
89+
"primary-dependency-label": get_task_label_by_attributes(
90+
deps, {"kind": "foo", "build-type": "linux"}
91+
),
92+
}
6093
assert tasks[1]["dependencies"] == {"b": "b", "c": "c"}
61-
assert tasks[1]["attributes"] == {"primary-kind-dependency": "foo"}
94+
assert tasks[1]["attributes"] == {
95+
"primary-kind-dependency": "foo",
96+
"primary-dependency-label": get_task_label_by_attributes(
97+
deps, {"kind": "foo", "build-type": "win"}
98+
),
99+
}
62100

63101

64-
def assert_copy_attributes(tasks):
102+
def assert_copy_attributes(deps, tasks):
65103
handle_exception(tasks)
66104
assert len(tasks) == 1
67105

@@ -70,48 +108,49 @@ def assert_copy_attributes(tasks):
70108
"build-type": "win",
71109
"kind": "foo",
72110
"primary-kind-dependency": "foo",
111+
"primary-dependency-label": get_task_label_by_attributes(deps, {"kind": "foo"}),
73112
}
74113

75114

76-
def assert_group_by_all(tasks):
115+
def assert_group_by_all(deps, tasks):
77116
handle_exception(tasks)
78117
assert len(tasks) == 1
79118
assert tasks[0]["dependencies"] == {"foo": "a", "bar": "bar-b"}
80119

81120

82-
def assert_group_by_all_dupe_allowed(tasks):
121+
def assert_group_by_all_dupe_allowed(deps, tasks):
83122
handle_exception(tasks)
84123
assert len(tasks) == 1
85124
assert tasks[0]["dependencies"] == {"a": "a", "b": "b", "c": "c"}
86125

87126

88-
def assert_dont_set_name(tasks):
127+
def assert_dont_set_name(deps, tasks):
89128
handle_exception(tasks)
90129
assert len(tasks) == 1
91130
assert tasks[0]["name"] == "a-special-name"
92131

93132

94-
def assert_dont_set_name_false(tasks):
133+
def assert_dont_set_name_false(deps, tasks):
95134
handle_exception(tasks)
96135
assert len(tasks) == 1
97136
assert tasks[0]["name"] == "a-special-name"
98137

99138

100-
def assert_set_name_strip_kind(tasks):
139+
def assert_set_name_strip_kind(deps, tasks):
101140
handle_exception(tasks)
102141
assert len(tasks) == 2
103142
assert tasks[0]["name"] == "a"
104143
assert tasks[1]["name"] == "b"
105144

106145

107-
def assert_set_name_retain_kind(tasks):
146+
def assert_set_name_retain_kind(deps, tasks):
108147
handle_exception(tasks)
109148
assert len(tasks) == 2
110149
assert tasks[0]["name"] == "a"
111150
assert tasks[1]["name"] == "bar-b"
112151

113152

114-
def assert_group_by_all_with_fetch(tasks):
153+
def assert_group_by_all_with_fetch(deps, tasks):
115154
handle_exception(tasks)
116155
assert len(tasks) == 1
117156
assert tasks[0]["dependencies"] == {
@@ -412,4 +451,4 @@ def test_transforms(
412451

413452
param_id = request.node.callspec.id
414453
assert_func = globals()[f"assert_{param_id}"]
415-
assert_func(result)
454+
assert_func(deps, result)

test/test_util_dependencies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ def test_get_primary_dependency(make_transform_config):
2222
"foo": make_task("foo", kind="kind1"),
2323
"bar": make_task("bar", kind="kind2"),
2424
}
25-
config = make_transform_config(kind_dependencies_tasks=dep_tasks)
2625
task = {
2726
"attributes": {},
2827
"dependencies": {"kind1": "foo", "kind2": "bar"},
2928
}
29+
config = make_transform_config(kind_dependencies_tasks=dep_tasks)
3030
assert get_primary_dependency(config, task) is None
3131

32-
task["attributes"]["primary-kind-dependency"] = "kind2"
32+
task["attributes"]["primary-dependency-label"] = dep_tasks["bar"].label
3333
assert get_primary_dependency(config, task) == list(dep_tasks.values())[1]

0 commit comments

Comments
 (0)