tasks.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. 'use strict';
  2. var archy = require('archy');
  3. var log = require('gulplog');
  4. var sortBy = require('array-sort');
  5. var isObject = require('isobject');
  6. var ansi = require('../ansi');
  7. var copyTree = require('./copy-tree');
  8. function logTasks(tree, opts, getTask) {
  9. if (opts.sortTasks) {
  10. tree.nodes = sortBy(tree.nodes, 'label');
  11. }
  12. var lineInfos = [];
  13. var entryObserver = getLineInfoCollector(lineInfos);
  14. var nodeFactory = getNodeFactory(getTask, entryObserver);
  15. tree = copyTree(tree, opts, nodeFactory);
  16. var spacer = getSpacerForLineIndents(tree, lineInfos);
  17. var lines = getLinesContainingOnlyBranches(tree);
  18. log.info(tree.label);
  19. printTreeList(lines, spacer, lineInfos);
  20. }
  21. function getLineInfoCollector(lineInfos) {
  22. return {
  23. topTask: function(node) {
  24. lineInfos.push({
  25. name: node.label,
  26. desc: node.desc,
  27. type: 'top',
  28. });
  29. },
  30. option: function(opt) {
  31. lineInfos.push({
  32. name: opt.label,
  33. desc: opt.desc,
  34. type: 'option',
  35. });
  36. },
  37. childTask: function(node) {
  38. lineInfos.push({
  39. name: node.label,
  40. type: 'child',
  41. });
  42. },
  43. };
  44. }
  45. function getNodeFactory(getTask, entryObserver) {
  46. return {
  47. topNode: function(node) {
  48. return {
  49. label: node.label,
  50. };
  51. },
  52. taskNode: function(node) {
  53. /* istanbul ignore next */
  54. var task = getTask(node.label) || {};
  55. var newNode = {
  56. label: node.label,
  57. desc: typeof task.description === 'string' ? task.description : '',
  58. opts: [],
  59. };
  60. entryObserver.topTask(newNode);
  61. if (isObject(task.flags)) {
  62. Object.keys(task.flags).sort().forEach(function(flag) {
  63. if (flag.length === 0) {
  64. return;
  65. }
  66. /* istanbul ignore next */
  67. var opt = {
  68. label: flag,
  69. desc: typeof task.flags[flag] === 'string' ? task.flags[flag] : '',
  70. };
  71. entryObserver.option(opt);
  72. newNode.opts.push(opt);
  73. newNode.label += '\n' + opt.label; // The way of archy for options.
  74. });
  75. }
  76. return newNode;
  77. },
  78. childNode: function(node) {
  79. var newChild = {
  80. label: node.label,
  81. };
  82. entryObserver.childTask(newChild);
  83. newChild.label = ''; // Because don't use child tasks to calc indents.
  84. return newChild;
  85. },
  86. };
  87. }
  88. function getSpacerForLineIndents(tree, lineInfos) {
  89. var maxSize = 0;
  90. var sizes = [];
  91. archy(tree)
  92. .split('\n')
  93. .slice(1, -1)
  94. .forEach(function(line, index) {
  95. var info = lineInfos[index];
  96. if (info.type === 'top' || info.type === 'option') {
  97. maxSize = Math.max(maxSize, line.length);
  98. sizes.push(line.length);
  99. } else {
  100. sizes.push(0);
  101. }
  102. });
  103. maxSize += 3;
  104. return function(index) {
  105. return Array(maxSize - sizes[index]).join(' ');
  106. };
  107. }
  108. function getLinesContainingOnlyBranches(tree) {
  109. tree.nodes.forEach(function(node) {
  110. node.label = '';
  111. node.opts.forEach(function() {
  112. node.label += '\n';
  113. });
  114. });
  115. return archy(tree)
  116. .split('\n')
  117. .slice(1, -1);
  118. }
  119. function printTreeList(lines, spacer, lineInfos) {
  120. lines.forEach(function(branch, index) {
  121. var info = lineInfos[index];
  122. var line = ansi.white(branch);
  123. if (info.type === 'top') {
  124. line += ansi.cyan(info.name);
  125. if (info.desc.length > 0) {
  126. line += spacer(index) + ansi.white(info.desc);
  127. }
  128. } else if (info.type === 'option') {
  129. line += ansi.magenta(info.name);
  130. if (info.desc.length > 0) {
  131. line += spacer(index) + ansi.white('…' + info.desc);
  132. }
  133. } else { // If (info.type === 'child') {
  134. line += ansi.white(info.name);
  135. }
  136. log.info(line);
  137. });
  138. }
  139. module.exports = logTasks;