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 5from __future__ import absolute_import, print_function, unicode_literals 6 7import attr 8 9 10@attr.s 11class Task(object): 12 """ 13 Representation of a task in a TaskGraph. Each Task has, at creation: 14 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': 'build-docker-image-desktop-test'} 22 23 And later, as the task-graph processing proceeds: 24 25 - task_id -- TaskCluster taskId under which this task will be created 26 27 This class is just a convenience wrapper for the data type and managing 28 display, comparison, serialization, etc. It has no functionality of its own. 29 """ 30 31 kind = attr.ib() 32 label = attr.ib() 33 attributes = attr.ib() 34 task = attr.ib() 35 task_id = attr.ib(default=None, init=False) 36 optimization = attr.ib(default=None) 37 dependencies = attr.ib(factory=dict) 38 release_artifacts = attr.ib( 39 converter=attr.converters.optional(frozenset), 40 default=None, 41 ) 42 43 def __attrs_post_init__(self): 44 self.attributes['kind'] = self.kind 45 46 def to_json(self): 47 rv = { 48 'kind': self.kind, 49 'label': self.label, 50 'attributes': self.attributes, 51 'dependencies': self.dependencies, 52 'optimization': self.optimization, 53 'task': self.task, 54 } 55 if self.task_id: 56 rv['task_id'] = self.task_id 57 if self.release_artifacts: 58 rv['release_artifacts'] = sorted(self.release_artifacts) 59 return rv 60 61 @classmethod 62 def from_json(cls, task_dict): 63 """ 64 Given a data structure as produced by taskgraph.to_json, re-construct 65 the original Task object. This is used to "resume" the task-graph 66 generation process, for example in Action tasks. 67 """ 68 rv = cls( 69 kind=task_dict['kind'], 70 label=task_dict['label'], 71 attributes=task_dict['attributes'], 72 task=task_dict['task'], 73 optimization=task_dict['optimization'], 74 dependencies=task_dict.get('dependencies'), 75 release_artifacts=task_dict.get('release-artifacts'), 76 ) 77 if 'task_id' in task_dict: 78 rv.task_id = task_dict['task_id'] 79 return rv 80