You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
46 lines
1.3 KiB
JavaScript
46 lines
1.3 KiB
JavaScript
"use strict";
|
|
|
|
const syncpipe = require("syncpipe");
|
|
const defaultValue = require("default-value"); // FIXME: Move to config validation
|
|
|
|
const invertMapping = require("./invert-mapping");
|
|
|
|
module.exports = function generateTaskGraph({ tags, tasks }) {
|
|
let tagsMapping = invertMapping(tags);
|
|
|
|
let tasksMap = syncpipe(tasks, [
|
|
_ => Object.entries(_),
|
|
_ => _.map(([ name, taskDefinition ]) => {
|
|
return [ name, {
|
|
... taskDefinition,
|
|
name: name,
|
|
// NOTE: The default here is for cases where a task is 'orphaned' and not associated with any tags; this can happen during development, and in that case the task won't be present in the tagsMapping at all.
|
|
tags: tagsMapping[name] ?? [],
|
|
dependencies: [],
|
|
dependents: []
|
|
}];
|
|
}),
|
|
_ => new Map(_)
|
|
]);
|
|
|
|
function getTask(name) {
|
|
if (tasksMap.has(name)) {
|
|
return tasksMap.get(name);
|
|
} else {
|
|
throw new Error(`Encountered dependency reference to non-existent task '${name}'`);
|
|
}
|
|
}
|
|
|
|
for (let task of tasksMap.values()) {
|
|
for (let dependencyName of defaultValue(task.dependsOn, [])) {
|
|
task.dependencies.push(getTask(dependencyName));
|
|
getTask(dependencyName).dependents.push(task);
|
|
}
|
|
|
|
// NOTE: We are mutating a local copy of the task definition here, that we created further up
|
|
delete task.dependsOn;
|
|
}
|
|
|
|
return tasksMap;
|
|
};
|