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/.
4
5
6import attr
7
8
9@attr.s
10class Task:
11    """
12    Representation of a task in a TaskGraph.  Each Task has, at creation:
13
14    - kind: the name of the task kind
15    - label; the label for this task
16    - attributes: a dictionary of attributes for this task (used for filtering)
17    - task: the task definition (JSON-able dictionary)
18    - optimization: optimization to apply to the task (see taskgraph.optimize)
19    - dependencies: tasks this one depends on, in the form {name: label}, for example
20      {'build': 'build-linux64/opt', 'docker-image': 'build-docker-image-desktop-test'}
21    - soft_dependencies: tasks this one may depend on if they are available post
22      optimisation. They are set as a list of tasks label.
23
24    And later, as the task-graph processing proceeds:
25
26    - task_id -- TaskCluster taskId under which this task will be created
27
28    This class is just a convenience wrapper for the data type and managing
29    display, comparison, serialization, etc. It has no functionality of its own.
30    """
31
32    kind = attr.ib()
33    label = attr.ib()
34    attributes = attr.ib()
35    task = attr.ib()
36    task_id = attr.ib(default=None, init=False)
37    optimization = attr.ib(default=None)
38    dependencies = attr.ib(factory=dict)
39    soft_dependencies = attr.ib(factory=list)
40
41    def __attrs_post_init__(self):
42        self.attributes["kind"] = self.kind
43
44    def to_json(self):
45        rv = {
46            "kind": self.kind,
47            "label": self.label,
48            "attributes": self.attributes,
49            "dependencies": self.dependencies,
50            "soft_dependencies": self.soft_dependencies,
51            "optimization": self.optimization,
52            "task": self.task,
53        }
54        if self.task_id:
55            rv["task_id"] = self.task_id
56        return rv
57
58    @classmethod
59    def from_json(cls, task_dict):
60        """
61        Given a data structure as produced by taskgraph.to_json, re-construct
62        the original Task object.  This is used to "resume" the task-graph
63        generation process, for example in Action tasks.
64        """
65        rv = cls(
66            kind=task_dict["kind"],
67            label=task_dict["label"],
68            attributes=task_dict["attributes"],
69            task=task_dict["task"],
70            optimization=task_dict["optimization"],
71            dependencies=task_dict.get("dependencies"),
72            soft_dependencies=task_dict.get("soft_dependencies"),
73        )
74        if "task_id" in task_dict:
75            rv.task_id = task_dict["task_id"]
76        return rv
77