1 | ;
|
2 | var task_transforms_1 = require("./task.transforms");
|
3 | var _ = require("../lodash.custom");
|
4 | var debug = require("debug")("cb:task.resolve");
|
5 | var task_errors_1 = require("./task.errors");
|
6 | var task_utils_1 = require("./task.utils");
|
7 | var adaptors = require("./adaptors");
|
8 | var task_preprocess_1 = require("./task.preprocess");
|
9 | var 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 = {}));
|
17 | var 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 = {}));
|
28 | var TaskOriginTypes = exports.TaskOriginTypes;
|
29 | (function (TaskRunModes) {
|
30 | TaskRunModes[TaskRunModes["series"] = "series"] = "series";
|
31 | TaskRunModes[TaskRunModes["parallel"] = "parallel"] = "parallel";
|
32 | })(exports.TaskRunModes || (exports.TaskRunModes = {}));
|
33 | var TaskRunModes = exports.TaskRunModes;
|
34 | var 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 | };
|
55 | function 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 | }
|
65 | function 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 | }
|
85 | var count = 0;
|
86 | /**
|
87 | * Entry point for resolving the task tree from any given point
|
88 | */
|
89 | function 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 | */
|
243 | function createTask(obj) {
|
244 | return _.mergeWith({}, defaultTask, obj, function customizer(objValue, srcValue) {
|
245 | if (_.isArray(objValue)) {
|
246 | return objValue.concat(srcValue);
|
247 | }
|
248 | });
|
249 | }
|
250 | exports.createTask = createTask;
|
251 | /**
|
252 | * When a circular reference is detected, exit with the appropriate error
|
253 | */
|
254 | function 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 | }
|
263 | exports.createCircularReferenceTask = createCircularReferenceTask;
|
264 | /**
|
265 | * Match a task name with a top-level value from 'tasks'
|
266 | */
|
267 | function 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 | }
|
285 | exports.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 | */
|
293 | function 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 | }
|
339 | exports.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 | */
|
348 | function 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 | }
|
357 | exports.maybeTaskNames = maybeTaskNames;
|
358 | /**
|
359 | * Attempt to match a task-name from within the various 'inputs'
|
360 | * given
|
361 | */
|
362 | function 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 | */
|
380 | function 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 | }
|
442 | function 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 | }
|
466 | exports.resolveTasks = resolveTasks;
|
467 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay5yZXNvbHZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Rhc2sucmVzb2x2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsZ0NBQThCLG1CQUFtQixDQUFDLENBQUE7QUFDbEQsSUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFDdEMsSUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFHbEQsNEJBQStDLGVBQWUsQ0FBQyxDQUFBO0FBQy9ELDJCQUVPLGNBQWMsQ0FBQyxDQUFBO0FBQ3RCLElBQVksUUFBUSxXQUFNLFlBQVksQ0FBQyxDQUFBO0FBRXZDLGdDQUFrRSxtQkFBbUIsQ0FBQyxDQUFBO0FBSXRGLHFDQUFrQyx3QkFBd0IsQ0FBQyxDQUFBO0FBZTNELFdBQVksU0FBUztJQUNqQixzQ0FBb0IsY0FBYyxrQkFBQSxDQUFBO0lBQ2xDLGlDQUFlLFNBQVMsYUFBQSxDQUFBO0lBQ3hCLG1DQUFpQixXQUFXLGVBQUEsQ0FBQTtJQUM1QixxQ0FBbUIsYUFBYSxpQkFBQSxDQUFBO0lBQ2hDLHdDQUFzQixnQkFBZ0Isb0JBQUEsQ0FBQTtBQUMxQyxDQUFDLEVBTlcsaUJBQVMsS0FBVCxpQkFBUyxRQU1wQjtBQU5ELElBQVksU0FBUyxHQUFULGlCQU1YLENBQUE7QUFFRCxXQUFZLGVBQWU7SUFDdkIsb0RBQXNCLGdCQUFnQixvQkFBQSxDQUFBO0lBQ3RDLGdEQUFrQixZQUFZLGdCQUFBLENBQUE7SUFDOUIsZ0RBQWtCLFlBQVksZ0JBQUEsQ0FBQTtJQUM5Qiw2Q0FBZSxTQUFTLGFBQUEsQ0FBQTtJQUN4QixvREFBc0IsZ0JBQWdCLG9CQUFBLENBQUE7SUFDdEMsaURBQW1CLGFBQWEsaUJBQUEsQ0FBQTtJQUNoQyxrREFBb0IsY0FBYyxrQkFBQSxDQUFBO0lBQ2xDLHVEQUF5QixtQkFBbUIsdUJBQUEsQ0FBQTtBQUNoRCxDQUFDLEVB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 |
\ | No newline at end of file |