sequencify.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. 'use strict';
  2. const debug = require('debug')('egg-core#sequencify');
  3. function sequence(tasks, names, results, missing, recursive, nest, optional, parent) {
  4. names.forEach(function(name) {
  5. if (results.requires[name]) return;
  6. const node = tasks[name];
  7. if (!node) {
  8. if (optional === true) return;
  9. missing.push(name);
  10. } else if (nest.includes(name)) {
  11. nest.push(name);
  12. recursive.push(nest.slice(0));
  13. nest.pop(name);
  14. } else if (node.dependencies.length || node.optionalDependencies.length) {
  15. nest.push(name);
  16. if (node.dependencies.length) {
  17. sequence(tasks, node.dependencies, results, missing, recursive, nest, optional, name);
  18. }
  19. if (node.optionalDependencies.length) {
  20. sequence(tasks, node.optionalDependencies, results, missing, recursive, nest, true, name);
  21. }
  22. nest.pop(name);
  23. }
  24. if (!optional) {
  25. results.requires[name] = true;
  26. debug('task: %s is enabled by %s', name, parent);
  27. }
  28. if (!results.sequence.includes(name)) {
  29. results.sequence.push(name);
  30. }
  31. });
  32. }
  33. // tasks: object with keys as task names
  34. // names: array of task names
  35. module.exports = function(tasks, names) {
  36. const results = {
  37. sequence: [],
  38. requires: {},
  39. }; // the final sequence
  40. const missing = []; // missing tasks
  41. const recursive = []; // recursive task dependencies
  42. sequence(tasks, names, results, missing, recursive, [], false, 'app');
  43. if (missing.length || recursive.length) {
  44. results.sequence = []; // results are incomplete at best, completely wrong at worst, remove them to avoid confusion
  45. }
  46. return {
  47. sequence: results.sequence.filter(item => results.requires[item]),
  48. missingTasks: missing,
  49. recursiveDependencies: recursive,
  50. };
  51. };