UNPKG

33.6 kBJavaScriptView Raw
1"use strict";
2var task_transforms_1 = require("./task.transforms");
3var _ = require("../lodash.custom");
4var debug = require("debug")("cb:task.resolve");
5var task_errors_1 = require("./task.errors");
6var task_utils_1 = require("./task.utils");
7var adaptors = require("./adaptors");
8var task_preprocess_1 = require("./task.preprocess");
9var task_tree_transforms_1 = require("./task.tree.transforms");
10(function (TaskTypes) {
11 TaskTypes[TaskTypes["ExternalTask"] = "ExternalTask"] = "ExternalTask";
12 TaskTypes[TaskTypes["Adaptor"] = "Adaptor"] = "Adaptor";
13 TaskTypes[TaskTypes["TaskGroup"] = "TaskGroup"] = "TaskGroup";
14 TaskTypes[TaskTypes["ParentGroup"] = "ParentGroup"] = "ParentGroup";
15 TaskTypes[TaskTypes["InlineFunction"] = "InlineFunction"] = "InlineFunction";
16})(exports.TaskTypes || (exports.TaskTypes = {}));
17var TaskTypes = exports.TaskTypes;
18(function (TaskOriginTypes) {
19 TaskOriginTypes[TaskOriginTypes["CrossbowConfig"] = "CrossbowConfig"] = "CrossbowConfig";
20 TaskOriginTypes[TaskOriginTypes["NpmScripts"] = "NpmScripts"] = "NpmScripts";
21 TaskOriginTypes[TaskOriginTypes["FileSystem"] = "FileSystem"] = "FileSystem";
22 TaskOriginTypes[TaskOriginTypes["Adaptor"] = "Adaptor"] = "Adaptor";
23 TaskOriginTypes[TaskOriginTypes["InlineFunction"] = "InlineFunction"] = "InlineFunction";
24 TaskOriginTypes[TaskOriginTypes["InlineArray"] = "InlineArray"] = "InlineArray";
25 TaskOriginTypes[TaskOriginTypes["InlineObject"] = "InlineObject"] = "InlineObject";
26 TaskOriginTypes[TaskOriginTypes["InlineChildObject"] = "InlineChildObject"] = "InlineChildObject";
27})(exports.TaskOriginTypes || (exports.TaskOriginTypes = {}));
28var TaskOriginTypes = exports.TaskOriginTypes;
29(function (TaskRunModes) {
30 TaskRunModes[TaskRunModes["series"] = "series"] = "series";
31 TaskRunModes[TaskRunModes["parallel"] = "parallel"] = "parallel";
32})(exports.TaskRunModes || (exports.TaskRunModes = {}));
33var TaskRunModes = exports.TaskRunModes;
34var defaultTask = {
35 baseTaskName: "",
36 valid: false,
37 query: {},
38 flags: {},
39 subTasks: [],
40 inlineFunctions: [],
41 externalTasks: [],
42 tasks: [],
43 parents: [],
44 errors: [],
45 cbflags: [],
46 description: "",
47 rawInput: "",
48 env: {},
49 taskName: undefined,
50 runMode: TaskRunModes.series,
51 skipped: false,
52 ifChanged: [],
53 options: {}
54};
55function mergeOptions(incoming) {
56 return function (task) {
57 return _.merge(task, {
58 env: incoming.env,
59 options: _.merge({}, _.get(incoming.options, "_default", {}), _.get(incoming.options, incoming.subTasks.slice(), {})),
60 flags: incoming.flags,
61 query: incoming.query
62 });
63 };
64}
65function fromInlineItems(incoming, current, name, parents, trigger) {
66 if (parents.indexOf(name) > -1) {
67 return createCircularReferenceTask(incoming, parents);
68 }
69 if (Array.isArray(current)) {
70 var thisParents_1 = parents.concat(incoming.baseTaskName);
71 var name_1 = "ParallelGroup(" + current.toString().slice(0, 20) + "...";
72 var task = createTask({
73 baseTaskName: name_1,
74 taskName: name_1,
75 runMode: TaskRunModes.parallel,
76 tasks: current.map(function (x) { return createFlattenedTask(x, thisParents_1, trigger); }),
77 parents: thisParents_1,
78 valid: true,
79 type: TaskTypes.TaskGroup
80 });
81 return task;
82 }
83 return createFlattenedTask(current, parents.concat(name), trigger);
84}
85var count = 0;
86/**
87 * Entry point for resolving the task tree from any given point
88 */
89function createFlattenedTask(taskItem, parents, trigger) {
90 /** DEBUG **/
91 debug("resolving ('" + typeof taskItem + "') " + taskItem);
92 /** DEBUG-END **/
93 /**
94 * We first 'preprocess' the task in order to
95 * handle different types of task input. Supported:
96 * - string
97 * - function
98 * - object literal
99 * @type {Task}
100 */
101 var incoming = task_preprocess_1.preprocessTask(taskItem, trigger, parents);
102 /** DEBUG **/
103 debug("preprocessed '" + taskItem + "'", incoming);
104 /** DEBUG-END **/
105 /**
106 * We exit very quickly if the pre-process step has delivered
107 * an 'adaptor' task - which means that's nothing left to determine.
108 */
109 if (incoming.type === TaskTypes.Adaptor) {
110 return incoming;
111 }
112 if (incoming.type === TaskTypes.ParentGroup) {
113 var subtask = incoming.subTasks[0];
114 var topLevelValue_1 = _.get(trigger.input.tasks, [("(" + incoming.baseTaskName + ")")], {});
115 var toResolve = (subtask === "*") ? Object.keys(topLevelValue_1) : [subtask];
116 if (incoming.tasks.length) {
117 var combinedName_1 = incoming.baseTaskName + ":" + incoming.subTasks[0];
118 incoming.tasks = [].concat(incoming.tasks)
119 .map(function (x) { return fromInlineItems(incoming, x, combinedName_1, parents, trigger); })
120 .map(mergeOptions(incoming));
121 }
122 else {
123 incoming.tasks = toResolve.reduce(function (acc, x) {
124 var match = _.get(topLevelValue_1, [x]);
125 if (match) {
126 var combinedName_2 = incoming.baseTaskName + ":" + x;
127 return acc.concat([].concat(match)
128 .map(function (x) { return fromInlineItems(incoming, x, combinedName_2, parents, trigger); }));
129 }
130 return acc;
131 }, []);
132 }
133 }
134 if (incoming.origin === TaskOriginTypes.InlineObject || incoming.origin === TaskOriginTypes.InlineChildObject) {
135 // todo top level object lookup
136 if (incoming.tasks) {
137 var taskItems = incoming.tasks;
138 incoming.tasks = [].concat(taskItems)
139 .map(function (x) { return fromInlineItems(incoming, x, incoming.baseTaskName, parents, trigger); });
140 }
141 }
142 if (incoming.type !== TaskTypes.ParentGroup && incoming.origin !== TaskOriginTypes.InlineChildObject) {
143 var toplevelValue = getTopLevelValue(incoming.baseTaskName, trigger.input);
144 if (incoming.baseTaskName === 'parallel-tasks') {
145 }
146 if (toplevelValue) {
147 incoming.tasks = [].concat(toplevelValue)
148 .map(function (x) { return fromInlineItems(incoming, x, incoming.baseTaskName, parents, trigger); })
149 .map(function (out) {
150 if (incoming.runMode === TaskRunModes.parallel) {
151 if (out.tasks.length > 1 || out.subTasks.length > 1) {
152 out.runMode = incoming.runMode;
153 }
154 }
155 return out;
156 });
157 }
158 else {
159 }
160 }
161 /**
162 * @type {CBFunction[]}
163 */
164 incoming.inlineFunctions = (function () {
165 if (incoming.inlineFunctions.length)
166 return incoming.inlineFunctions;
167 if (incoming.tasks.length)
168 return [];
169 var toplevel = getTopLevelValue(incoming.baseTaskName, trigger.input);
170 if (typeof toplevel === "function") {
171 return [toplevel];
172 }
173 return [];
174 })();
175 /**
176 * @type {ExternalTask[]}
177 */
178 incoming.externalTasks = (function () {
179 if (incoming.tasks.length)
180 return [];
181 if (incoming.inlineFunctions.length)
182 return [];
183 return task_utils_1.locateModule(trigger.config, incoming.baseTaskName);
184 })();
185 debug("externalTasks: " + JSON.stringify(incoming.externalTasks[0]));
186 /**
187 * Set task types
188 * @type {TaskTypes}
189 */
190 incoming.type = (function () {
191 if (typeof incoming.type !== "undefined")
192 return incoming.type;
193 if (incoming.externalTasks.length) {
194 return TaskTypes.ExternalTask;
195 }
196 if (incoming.inlineFunctions.length) {
197 return TaskTypes.InlineFunction;
198 }
199 return TaskTypes.TaskGroup;
200 })();
201 debug("type: " + incoming.type);
202 /**
203 * @type {boolean}
204 */
205 incoming.valid = (function () {
206 if (incoming.type === TaskTypes.ParentGroup) {
207 if (incoming.tasks.length) {
208 return true;
209 }
210 }
211 if (incoming.type === TaskTypes.TaskGroup)
212 return true;
213 if (incoming.type === TaskTypes.InlineFunction)
214 return true;
215 if (incoming.type === TaskTypes.ExternalTask)
216 return true;
217 return false;
218 })();
219 debug("valid: " + incoming.valid);
220 /**
221 * Now apply any transformations
222 * @type {Task}
223 */
224 incoming = task_transforms_1.applyTransforms(incoming);
225 /**
226 * Collect errors
227 * @type {TaskError[]}
228 */
229 incoming.errors = task_errors_1.gatherTaskErrors(incoming, trigger);
230 debug("errors: " + incoming.errors);
231 /**
232 * Add parents array (for detecting circular references);
233 * @type {string[]}
234 */
235 incoming.parents = parents;
236 return incoming;
237}
238/**
239 * Factory for creating a new Task Item
240 * @param {object} obj
241 * @returns {object}
242 */
243function createTask(obj) {
244 return _.mergeWith({}, defaultTask, obj, function customizer(objValue, srcValue) {
245 if (_.isArray(objValue)) {
246 return objValue.concat(srcValue);
247 }
248 });
249}
250exports.createTask = createTask;
251/**
252 * When a circular reference is detected, exit with the appropriate error
253 */
254function createCircularReferenceTask(incoming, parents) {
255 return _.merge({}, defaultTask, incoming, {
256 errors: [{
257 type: task_errors_1.TaskErrorTypes.CircularReference,
258 incoming: incoming,
259 parents: parents
260 }]
261 });
262}
263exports.createCircularReferenceTask = createCircularReferenceTask;
264/**
265 * Match a task name with a top-level value from 'tasks'
266 */
267function getTopLevelValue(baseTaskName, input) {
268 var exactMatch = input.tasks[baseTaskName];
269 if (exactMatch !== undefined) {
270 return exactMatch;
271 }
272 var maybeGroup = Object.keys(input.tasks)
273 .filter(function (x) { return x.indexOf("(" + baseTaskName + ")") > -1; });
274 if (maybeGroup.length) {
275 return input.tasks[maybeGroup[0]];
276 }
277 var maybes = Object.keys(input.tasks)
278 .filter(function (x) { return !task_utils_1.isParentGroupName(x); })
279 .filter(function (taskName) { return taskName.match(new RegExp("^" + baseTaskName + "($|@(.+?))")) !== null; });
280 if (maybes.length) {
281 return input.tasks[maybes[0]];
282 }
283 return undefined;
284}
285exports.getTopLevelValue = getTopLevelValue;
286/**
287 * Anything that begins @ is always an adaptor and will skip
288 * file i/o etc.
289 * @param taskName
290 * @param parents
291 * @returns {Task}
292 */
293function createAdaptorTask(taskName, parents) {
294 taskName = task_utils_1.removeTrailingNewlines(taskName);
295 /**
296 * Strip the first part of the task name.
297 * eg: `@npm eslint`
298 * -> eslint
299 * @type {string}
300 */
301 var commandInput = taskName.replace(/^@(.+?) /, "");
302 /**
303 * Get a valid adaptors adaptor name
304 * @type {string|undefined}
305 */
306 var validAdaptorName = Object.keys(adaptors).filter(function (x) {
307 return taskName.match(new RegExp("^@" + x + " "));
308 })[0];
309 /**
310 * If it was not valid, return a simple
311 * task that will be invalid
312 */
313 if (!validAdaptorName) {
314 return createTask({
315 rawInput: taskName,
316 taskName: taskName,
317 type: TaskTypes.Adaptor,
318 origin: TaskOriginTypes.Adaptor,
319 adaptor: taskName.split(" ")[0],
320 errors: [{
321 type: task_errors_1.TaskErrorTypes.AdaptorNotFound,
322 taskName: taskName
323 }]
324 });
325 }
326 return createTask({
327 baseTaskName: taskName,
328 valid: true,
329 adaptor: validAdaptorName,
330 taskName: taskName,
331 rawInput: taskName,
332 parents: parents,
333 command: commandInput,
334 runMode: TaskRunModes.series,
335 origin: TaskOriginTypes.Adaptor,
336 type: TaskTypes.Adaptor,
337 });
338}
339exports.createAdaptorTask = createAdaptorTask;
340/**
341 * Look at a hash and determine if the incoming 'taskName'
342 * could match a valid taskName.
343 * eg:
344 * $ crossbow run shane
345 *
346 * -> matches: 'shane' & 'shane@p'
347 */
348function maybeTaskNames(tasks, taskName) {
349 return Object.keys(tasks).reduce(function (all, key) {
350 var match = key.match(new RegExp("^" + taskName + "@(.+)"));
351 if (match) {
352 return tasks[key];
353 }
354 return all;
355 }, []);
356}
357exports.maybeTaskNames = maybeTaskNames;
358/**
359 * Attempt to match a task-name from within the various 'inputs'
360 * given
361 */
362function pullTaskFromInput(taskName, input) {
363 if (input.tasks[taskName] !== undefined) {
364 return { items: [].concat(input.tasks[taskName]), origin: TaskOriginTypes.CrossbowConfig };
365 }
366 /**
367 * Next, look at the top-level input,
368 * is this taskname going to match, and if so, does it contain any flags?
369 */
370 var maybes = maybeTaskNames(input.tasks, taskName);
371 if (maybes.length) {
372 return { items: maybes, origin: TaskOriginTypes.CrossbowConfig };
373 }
374 return { items: [], origin: TaskOriginTypes.CrossbowConfig };
375}
376/**
377 * A task is valid if every child eventually resolves to
378 * having a module or has a adaptors helper
379 */
380function validateTask(task, trigger) {
381 /**
382 * Return early if a task has previously
383 * been marked as invalid
384 */
385 if (task.valid === false) {
386 return false;
387 }
388 /**
389 * If the task has errors attached, it's always invalid
390 */
391 if (task.errors.length) {
392 return false;
393 }
394 /**
395 * If this task has subtasks in the `task.tasks` Array
396 * return the result of validating each of those.
397 */
398 if (task.tasks.length) {
399 return task.tasks.every(function (t) {
400 return validateTask(t, trigger);
401 });
402 }
403 /**
404 * The final chance for a task to be deemed valid
405 * is when `task.adaptors` is set to a string.
406 * eg: lint: '@npm eslint'
407 * -> true
408 */
409 if (typeof task.adaptor === "string") {
410 /**
411 * task.adaptor is a string, but does it match any adaptors?
412 * If it does, return the result of running the
413 * validate method from the adaptor
414 */
415 if (adaptors[task.adaptor]) {
416 return adaptors[task.adaptor].validate.apply(null, [task, trigger]);
417 }
418 }
419 /**
420 * If this task was set to InlineFunction, it's always valid
421 * (as there's a function to call)
422 */
423 if (task.type === TaskTypes.InlineFunction) {
424 return true;
425 }
426 /**
427 * If the task has external modules associated
428 * with it, it's always valid (as it has things to run)
429 */
430 if (task.type === TaskTypes.ExternalTask) {
431 return true;
432 }
433 /**
434 * In the case where `task.modules` has a length (meaning a JS file was found)
435 * and there are NO sub tasks to validate, this means the current
436 * task is ALWAYS valid so we can return true;
437 */
438 if (task.externalTasks.length && !task.tasks.length) {
439 return true;
440 }
441}
442function resolveTasks(taskCollection, trigger) {
443 /**
444 * Now begin making the nested task tree
445 */
446 var taskList = taskCollection
447 .map(function (task) {
448 return createFlattenedTask(task, [], trigger);
449 });
450 /**
451 * Now apply any last-minute tree transformations
452 */
453 taskList = task_tree_transforms_1.applyTreeTransforms(taskList);
454 /**
455 * Return both valid & invalid tasks. We want to let consumers
456 * handle errors/successes
457 * @type {{valid: Array, invalid: Array}}
458 */
459 var output = {
460 valid: taskList.filter(function (x) { return validateTask(x, trigger); }),
461 invalid: taskList.filter(function (x) { return !validateTask(x, trigger); }),
462 all: taskList
463 };
464 return output;
465}
466exports.resolveTasks = resolveTasks;
467//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay5yZXNvbHZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Rhc2sucmVzb2x2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsZ0NBQThCLG1CQUFtQixDQUFDLENBQUE7QUFDbEQsSUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDdEMsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFHbEQsNEJBQStDLGVBQWUsQ0FBQyxDQUFBO0FBQy9ELDJCQUVPLGNBQWMsQ0FBQyxDQUFBO0FBQ3RCLElBQVksUUFBUSxXQUFNLFlBQVksQ0FBQyxDQUFBO0FBRXZDLGdDQUFrRSxtQkFBbUIsQ0FBQyxDQUFBO0FBSXRGLHFDQUFrQyx3QkFBd0IsQ0FBQyxDQUFBO0FBZTNELFdBQVksU0FBUztJQUNqQixzQ0FBb0IsY0FBYyxrQkFBQSxDQUFBO0lBQ2xDLGlDQUFlLFNBQVMsYUFBQSxDQUFBO0lBQ3hCLG1DQUFpQixXQUFXLGVBQUEsQ0FBQTtJQUM1QixxQ0FBbUIsYUFBYSxpQkFBQSxDQUFBO0lBQ2hDLHdDQUFzQixnQkFBZ0Isb0JBQUEsQ0FBQTtBQUMxQyxDQUFDLEVBTlcsaUJBQVMsS0FBVCxpQkFBUyxRQU1wQjtBQU5ELElBQVksU0FBUyxHQUFULGlCQU1YLENBQUE7QUFFRCxXQUFZLGVBQWU7SUFDdkIsb0RBQXNCLGdCQUFnQixvQkFBQSxDQUFBO0lBQ3RDLGdEQUFrQixZQUFZLGdCQUFBLENBQUE7SUFDOUIsZ0RBQWtCLFlBQVksZ0JBQUEsQ0FBQTtJQUM5Qiw2Q0FBZSxTQUFTLGFBQUEsQ0FBQTtJQUN4QixvREFBc0IsZ0JBQWdCLG9CQUFBLENBQUE7SUFDdEMsaURBQW1CLGFBQWEsaUJBQUEsQ0FBQTtJQUNoQyxrREFBb0IsY0FBYyxrQkFBQSxDQUFBO0lBQ2xDLHVEQUF5QixtQkFBbUIsdUJBQUEsQ0FBQTtBQUNoRCxDQUFDLEVB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
\No newline at end of file