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 abc 8 9 10class Task(object): 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 19 And later, as the task-graph processing proceeds: 20 21 - task_id -- TaskCluster taskId under which this task will be created 22 - optimized -- true if this task need not be performed 23 24 A kind represents a collection of tasks that share common characteristics. 25 For example, all build jobs. Each instance of a kind is intialized with a 26 path from which it draws its task configuration. The instance is free to 27 store as much local state as it needs. 28 """ 29 __metaclass__ = abc.ABCMeta 30 31 def __init__(self, kind, label, attributes, task): 32 self.kind = kind 33 self.label = label 34 self.attributes = attributes 35 self.task = task 36 37 self.task_id = None 38 self.optimized = False 39 40 self.attributes['kind'] = kind 41 42 def __eq__(self, other): 43 return self.kind == other.kind and \ 44 self.label == other.label and \ 45 self.attributes == other.attributes and \ 46 self.task == other.task and \ 47 self.task_id == other.task_id 48 49 @classmethod 50 @abc.abstractmethod 51 def load_tasks(cls, kind, path, config, parameters, loaded_tasks): 52 """ 53 Load the tasks for a given kind. 54 55 The `kind` is the name of the kind; the configuration for that kind 56 named this class. 57 58 The `path` is the path to the configuration directory for the kind. This 59 can be used to load extra data, templates, etc. 60 61 The `parameters` give details on which to base the task generation. 62 See `taskcluster/docs/parameters.rst` for details. 63 64 At the time this method is called, all kinds on which this kind depends 65 (that is, specified in the `kind-dependencies` key in `self.config` 66 have already loaded their tasks, and those tasks are available in 67 the list `loaded_tasks`. 68 69 The return value is a list of Task instances. 70 """ 71 72 @abc.abstractmethod 73 def get_dependencies(self, taskgraph): 74 """ 75 Get the set of task labels this task depends on, by querying the full 76 task set, given as `taskgraph`. 77 78 Returns a list of (task_label, dependency_name) pairs describing the 79 dependencies. 80 """ 81 82 def optimize(self, params): 83 """ 84 Determine whether this task can be optimized, and if it can, what taskId 85 it should be replaced with. 86 87 The return value is a tuple `(optimized, taskId)`. If `optimized` is 88 true, then the task will be optimized (in other words, not included in 89 the task graph). If the second argument is a taskid, then any 90 dependencies on this task will isntead depend on that taskId. It is an 91 error to return no taskId for a task on which other tasks depend. 92 93 The default never optimizes. 94 """ 95 return False, None 96 97 @classmethod 98 def from_json(cls, task_dict): 99 """ 100 Given a data structure as produced by taskgraph.to_json, re-construct 101 the original Task object. This is used to "resume" the task-graph 102 generation process, for example in Action tasks. 103 """ 104 return cls( 105 kind=task_dict['attributes']['kind'], 106 label=task_dict['label'], 107 attributes=task_dict['attributes'], 108 task=task_dict['task']) 109