Bug 1682766 [wpt PR 26921] - Fix nullptr dereference accessing PolicyContainer in...
[gecko.git] / taskcluster / taskgraph / task.py
blob9933d03758b08b496562d038a0931cd256f5e4e3
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 from __future__ import absolute_import, print_function, unicode_literals
7 import attr
10 @attr.s
11 class Task(object):
12 """
13 Representation of a task in a TaskGraph. Each Task has, at creation:
15 - kind: the name of the task kind
16 - label; the label for this task
17 - attributes: a dictionary of attributes for this task (used for filtering)
18 - task: the task definition (JSON-able dictionary)
19 - optimization: optimization to apply to the task (see taskgraph.optimize)
20 - dependencies: tasks this one depends on, in the form {name: label}, for example
21 {'build': 'build-linux64/opt', 'docker-image': 'docker-image-desktop-test'}
22 - soft_dependencies: tasks this one may depend on if they are available post
23 optimisation. They are set as a list of tasks label.
24 - if_dependencies: only run this task if at least one of these dependencies
25 are present.
27 And later, as the task-graph processing proceeds:
29 - task_id -- TaskCluster taskId under which this task will be created
31 This class is just a convenience wrapper for the data type and managing
32 display, comparison, serialization, etc. It has no functionality of its own.
33 """
35 kind = attr.ib()
36 label = attr.ib()
37 attributes = attr.ib()
38 task = attr.ib()
39 description = attr.ib(default="")
40 task_id = attr.ib(default=None, init=False)
41 optimization = attr.ib(default=None)
42 dependencies = attr.ib(factory=dict)
43 soft_dependencies = attr.ib(factory=list)
44 if_dependencies = attr.ib(factory=list)
45 release_artifacts = attr.ib(
46 converter=attr.converters.optional(frozenset),
47 default=None,
50 def __attrs_post_init__(self):
51 self.attributes["kind"] = self.kind
53 @property
54 def name(self):
55 if self.label.startswith(self.kind + "-"):
56 return self.label[len(self.kind) + 1 :]
57 else:
58 raise AttributeError("Task {} does not have a name.".format(self.label))
60 def to_json(self):
61 rv = {
62 "kind": self.kind,
63 "label": self.label,
64 "description": self.description,
65 "attributes": self.attributes,
66 "dependencies": self.dependencies,
67 "soft_dependencies": sorted(self.soft_dependencies),
68 "if_dependencies": self.if_dependencies,
69 "optimization": self.optimization,
70 "task": self.task,
72 if self.task_id:
73 rv["task_id"] = self.task_id
74 if self.release_artifacts:
75 rv["release_artifacts"] = sorted(self.release_artifacts)
76 return rv
78 @classmethod
79 def from_json(cls, task_dict):
80 """
81 Given a data structure as produced by taskgraph.to_json, re-construct
82 the original Task object. This is used to "resume" the task-graph
83 generation process, for example in Action tasks.
84 """
85 rv = cls(
86 kind=task_dict["kind"],
87 label=task_dict["label"],
88 description=task_dict.get("description", ""),
89 attributes=task_dict["attributes"],
90 task=task_dict["task"],
91 optimization=task_dict["optimization"],
92 dependencies=task_dict.get("dependencies"),
93 soft_dependencies=task_dict.get("soft_dependencies"),
94 if_dependencies=task_dict.get("if_dependencies"),
95 release_artifacts=task_dict.get("release-artifacts"),
97 if "task_id" in task_dict:
98 rv.task_id = task_dict["task_id"]
99 return rv