2016-05-17 01:53:22 +03:00
|
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
|
2016-07-11 20:09:04 +03:00
|
|
|
import os
|
|
|
|
|
|
|
|
from .graph import Graph
|
|
|
|
from .util.python_path import find_object
|
|
|
|
|
|
|
|
TASKCLUSTER_QUEUE_URL = "https://queue.taskcluster.net/v1/task/"
|
|
|
|
GECKO = os.path.realpath(os.path.join(__file__, '..', '..', '..'))
|
|
|
|
|
2016-06-21 04:06:55 +03:00
|
|
|
|
2016-05-17 01:53:22 +03:00
|
|
|
class TaskGraph(object):
|
|
|
|
"""
|
|
|
|
Representation of a task graph.
|
|
|
|
|
|
|
|
A task graph is a combination of a Graph and a dictionary of tasks indexed
|
|
|
|
by label. TaskGraph instances should be treated as immutable.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, tasks, graph):
|
|
|
|
assert set(tasks) == graph.nodes
|
|
|
|
self.tasks = tasks
|
|
|
|
self.graph = graph
|
|
|
|
|
2016-06-07 06:09:48 +03:00
|
|
|
def to_json(self):
|
|
|
|
"Return a JSON-able object representing the task graph, as documented"
|
|
|
|
named_links_dict = self.graph.named_links_dict()
|
|
|
|
# this dictionary may be keyed by label or by taskid, so let's just call it 'key'
|
|
|
|
tasks = {}
|
|
|
|
for key in self.graph.visit_postorder():
|
|
|
|
task = self.tasks[key]
|
2016-07-11 20:09:04 +03:00
|
|
|
implementation = task.__class__.__module__ + ":" + task.__class__.__name__
|
2016-06-07 06:09:48 +03:00
|
|
|
task_json = {
|
|
|
|
'label': task.label,
|
|
|
|
'attributes': task.attributes,
|
|
|
|
'dependencies': named_links_dict.get(key, {}),
|
2016-07-11 20:09:04 +03:00
|
|
|
'task': task.task,
|
|
|
|
'kind_implementation': implementation
|
2016-06-07 06:09:48 +03:00
|
|
|
}
|
|
|
|
if task.task_id:
|
|
|
|
task_json['task_id'] = task.task_id
|
|
|
|
tasks[key] = task_json
|
|
|
|
return tasks
|
|
|
|
|
2016-05-17 01:53:22 +03:00
|
|
|
def __getitem__(self, label):
|
|
|
|
"Get a task by label"
|
|
|
|
return self.tasks[label]
|
|
|
|
|
|
|
|
def __iter__(self):
|
|
|
|
"Iterate over tasks in undefined order"
|
|
|
|
return self.tasks.itervalues()
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return "<TaskGraph graph={!r} tasks={!r}>".format(self.graph, self.tasks)
|
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
return self.tasks == other.tasks and self.graph == other.graph
|
2016-07-11 20:09:04 +03:00
|
|
|
|
|
|
|
@classmethod
|
2016-09-23 16:56:39 +03:00
|
|
|
def from_json(cls, tasks_dict):
|
2016-07-11 20:09:04 +03:00
|
|
|
"""
|
|
|
|
This code is used to generate the a TaskGraph using a dictionary
|
|
|
|
which is representative of the TaskGraph.
|
|
|
|
"""
|
|
|
|
tasks = {}
|
|
|
|
edges = set()
|
|
|
|
for key, value in tasks_dict.iteritems():
|
|
|
|
# We get the implementation from JSON
|
|
|
|
implementation = value['kind_implementation']
|
|
|
|
# Loading the module and creating a Task from a dictionary
|
|
|
|
task_kind = find_object(implementation)
|
|
|
|
tasks[key] = task_kind.from_json(value)
|
|
|
|
if 'task_id' in value:
|
|
|
|
tasks[key].task_id = value['task_id']
|
|
|
|
for depname, dep in value['dependencies'].iteritems():
|
|
|
|
edges.add((key, dep, depname))
|
|
|
|
task_graph = cls(tasks, Graph(set(tasks), edges))
|
|
|
|
return tasks, task_graph
|