Skip to content

Commit

Permalink
Update: Apply depth/compact flags to tasks-json/tasks w/ .gulp.* supp…
Browse files Browse the repository at this point in the history
…ort & add sort flag (closes #57) (#75)
  • Loading branch information
sttk authored and phated committed Jun 12, 2017
1 parent 0abb70d commit 86f5df8
Show file tree
Hide file tree
Showing 38 changed files with 1,271 additions and 120 deletions.
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,14 @@ Configuration from the home directory (`~`) and current working directory (`cwd`

Supported configurations properties:

| Property | Description |
|----------------|-------------|
| description | Top-level description of the project/gulpfile (Replaces "Tasks for ~/path/of/gulpfile.js") |
| flags.gulpfile | Set a default gulpfile |
| flags.silent | Silence logging by default |
| Property | Description |
|--------------------|-------------|
| description | Top-level description of the project/gulpfile (Replaces "Tasks for ~/path/of/gulpfile.js") |
| flags.continue | Continue execution of tasks upon failure by default. |
| flags.compactTasks | Reduce the output of task dependency tree by default. |
| flags.tasksDepth | Set default depth of task dependency tree. |
| flags.gulpfile | Set a default gulpfile |
| flags.silent | Silence logging by default |

## Flags

Expand Down Expand Up @@ -159,11 +162,6 @@ __Some flags only work with gulp 4 and will be ignored when invoked against gulp
<td>-T</td>
<td>Print the task dependency tree for the loaded gulpfile.</td>
</tr>
<tr>
<td>--depth [number]</td>
<td></td>
<td>Specify the depth of the task dependency tree to print.</td>
</tr>
<tr>
<td>--tasks-simple</td>
<td></td>
Expand All @@ -174,6 +172,21 @@ __Some flags only work with gulp 4 and will be ignored when invoked against gulp
<td></td>
<td>Print the task dependency tree, in JSON format, for the loaded gulpfile. The [path] argument is optional, and if given writes the JSON to the path.</td>
</tr>
<tr>
<td>--tasks-depth [number]</td>
<td></td>
<td>Specify the depth of the task dependency tree to print. This flag can be used with --tasks or --tasks-json. (This flag was named --depth before but is deprecated.)</td>
</tr>
<tr>
<td>--compact-tasks</td>
<td></td>
<td>Reduce the output of task dependency tree by printing only top tasks and their child tasks. This flag can be used with --tasks or --tasks-json.</td>
</tr>
<tr>
<td>--sort-tasks</td>
<td></td>
<td>Will sort top tasks of task dependency tree. This flag can be used with --tasks.</td>
</tr>
<tr>
<td>--color</td>
<td></td>
Expand Down
9 changes: 9 additions & 0 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ gulp has very few flags to know about. All other flags are for tasks to use if n
**--tasks-json** [path]
Print the task dependency tree, in JSON format, for the loaded gulpfile. The [path] argument is optional, and if given writes the JSON to the path.

**--tasks-depth** [number]
Specify the depth of the task dependency tree to print. This flag can be used with --tasks or --tasks-json. (This flag was named --depth before but is deprecated.)

**--compact-tasks**
Reduce the output of task dependency tree by printing only top tasks and their child tasks. This flag can be used with --tasks or --tasks-json.

**--sort-tasks**
Will sort top tasks of task dependency tree. This flag can be used with --tasks.

**--color**
Will force gulp and gulp plugins to display colors, even when no color support is detected.

Expand Down
24 changes: 18 additions & 6 deletions lib/shared/cliOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ module.exports = {
desc: chalk.gray(
'Print the task dependency tree for the loaded gulpfile.'),
},
depth: {
type: 'number',
requiresArg: true,
desc: chalk.gray(
'Specify the depth of the task dependency tree.'),
},
'tasks-simple': {
type: 'boolean',
desc: chalk.gray(
Expand All @@ -63,6 +57,24 @@ module.exports = {
'Print the task dependency tree, ' +
'in JSON format, for the loaded gulpfile.'),
},
'tasks-depth': {
alias: 'depth',
type: 'number',
requiresArg: true,
desc: chalk.gray(
'Specify the depth of the task dependency tree.'),
},
'compact-tasks': {
type: 'boolean',
desc: chalk.gray(
'Reduce the output of task dependency tree by printing ' +
'only top tasks and their child tasks.'),
},
'sort-tasks': {
type: 'boolean',
desc: chalk.gray(
'Will sort top tasks of task dependency tree.'),
},
color: {
type: 'boolean',
desc: chalk.gray(
Expand Down
3 changes: 3 additions & 0 deletions lib/shared/config/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ var fromTo = {
'flags.silent': 'silent',
'flags.continue': 'continue',
'flags.logLevel': 'logLevel',
'flags.compactTasks': 'compactTasks',
'flags.tasksDepth': 'tasksDepth',
'flags.sortTasks': 'sortTasks',
};

function mergeConfigToCliFlags(opt, config) {
Expand Down
7 changes: 7 additions & 0 deletions lib/shared/is-array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

function isArray(val) {
return Array.isArray(val);
}

module.exports = isArray;
7 changes: 7 additions & 0 deletions lib/shared/is-number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

function isNumber(val) {
return (typeof val === 'number');
}

module.exports = isNumber;
84 changes: 84 additions & 0 deletions lib/shared/log/copy-tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
'use strict';

var isArray = require('../is-array');
var isNumber = require('../is-number');

function copyNode(node) {
var newNode = {};
Object.keys(node).forEach(function(key) {
newNode[key] = node[key];
});
return newNode;
}

var defaultNodeFactory = {
topNode: copyNode,
taskNode: copyNode,
childNode: copyNode,
};

function copyTree(tree, opts, nodeFactory) {
opts = opts || {};

var depth = opts.tasksDepth;
depth = !isNumber(depth) ? null : ((depth < 1) ? 1 : depth);

nodeFactory = nodeFactory || defaultNodeFactory;

var newTree = nodeFactory.topNode(tree);
newTree.nodes = [];

if (isArray(tree.nodes)) {
tree.nodes.forEach(visit);
}

function visit(node) {
var newNode = nodeFactory.taskNode(node);
newNode.nodes = [];
newTree.nodes.push(newNode);

if (opts.compactTasks) {
forEach(node.nodes, copyNotRecursively, newNode);

} else if (!depth || depth > 1) {
forEach(node.nodes, copyRecursively, depth, 2, newNode);
}
}

function copyNotRecursively(child, newParent) {
var newChild = nodeFactory.childNode(child);
newChild.nodes = [];
newParent.nodes.push(newChild);

if (child.branch) {
forEach(child.nodes, copyNotRecursively, newChild);
}
}

function copyRecursively(child, maxDepth, nowDepth, newParent) {
var newChild = nodeFactory.childNode(child);
newChild.nodes = [];
newParent.nodes.push(newChild);

if (!maxDepth || maxDepth > nowDepth) {
forEach(child.nodes, copyRecursively, maxDepth, nowDepth + 1, newChild);
}
}

return newTree;
}

function forEach(nodes, fn) {
if (!isArray(nodes)) {
return;
}

var args = Array.prototype.slice.call(arguments, 2);

for (var i = 0, n = nodes.length; i < n; i++) {
fn.apply(nodes[i], [nodes[i]].concat(args));
}
}

module.exports = copyTree;

120 changes: 52 additions & 68 deletions lib/shared/log/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@ var log = require('gulplog');

var sortBy = require('lodash.sortby');
var isObject = require('lodash.isplainobject');

var isString = require('../is-string');

function logTasks(tree, depth, getTask) {
depth = (typeof depth !== 'number') ? null : ((depth < 1) ? 1 : depth);
var copyTree = require('./copy-tree');

function sorter(node) {
return node.label;
}

function logTasks(tree, opts, getTask) {
if (opts.sortTasks) {
tree.nodes = sortBy(tree.nodes, sorter);
}

var lineInfos = [];
var entryObserver = getLineInfoCollector(lineInfos);
var nodeFactory = getNodeFactory(getTask, entryObserver);

tree = copyTree(tree, depth, getTask, entryObserver);

tree = copyTree(tree, opts, nodeFactory);
var spacer = getSpacerForLineIndents(tree, lineInfos);
var lines = getLinesContainingOnlyBranches(tree);

Expand Down Expand Up @@ -49,75 +56,52 @@ function getLineInfoCollector(lineInfos) {
};
}

function copyTree(tree, depth, getTask, entryObserver) {
var newTree = {
label: tree.label,
nodes: [],
};

sortBy(tree.nodes, sorter).forEach(visit);

function sorter(node) {
return node.label;
}
function getNodeFactory(getTask, entryObserver) {
return {
topNode: function(node) {
return {
label: node.label,
};
},

function visit(node) {
var task = getTask(node.label) || {};

var newNode = {
label: node.label,
desc: isString(task.description) ? task.description : '',
opts: [],
nodes: [],
};
entryObserver.topTask(newNode);
newTree.nodes.push(newNode);

if (isObject(task.flags)) {
Object.keys(task.flags).sort().forEach(function(flag) {
if (flag.length === 0) {
return;
}
var opt = {
label: flag,
desc: isString(task.flags[flag]) ? task.flags[flag] : '',
};
entryObserver.option(opt);
newNode.opts.push(opt);
newNode.label += '\n' + opt.label; // The way of archy for options.
});
}
taskNode: function(node) {
var task = getTask(node.label) || {};

if (!depth || depth > 1) {
var fn = function(child, maxDepth, nowDepth, newParent) {
var newChild = {
label: child.label,
nodes: [],
};
entryObserver.childTask(newChild);
newChild.label = ''; // Because don't use child tasks to calc indents.
newParent.nodes.push(newChild);
if (!maxDepth || maxDepth > nowDepth) {
forEachNode(child.nodes, fn, maxDepth, nowDepth + 1, newChild);
}
var newNode = {
label: node.label,
desc: isString(task.description) ? task.description : '',
opts: [],
};
forEachNode(node.nodes, fn, depth, 2, newNode);
}
}

return newTree;
}
entryObserver.topTask(newNode);

if (isObject(task.flags)) {
Object.keys(task.flags).sort().forEach(function(flag) {
if (flag.length === 0) {
return;
}
var opt = {
label: flag,
desc: isString(task.flags[flag]) ? task.flags[flag] : '',
};
entryObserver.option(opt);
newNode.opts.push(opt);
newNode.label += '\n' + opt.label; // The way of archy for options.
});
}

function forEachNode(nodes, fn) {
if (!Array.isArray(nodes)) {
return;
}
return newNode;
},

var args = [].slice.call(arguments, 2);
childNode: function(node) {
var newChild = {
label: node.label,
};
entryObserver.childTask(newChild);
newChild.label = ''; // Because don't use child tasks to calc indents.

for (var i = 0, n = nodes.length; i < n; i++) {
fn.apply(nodes[i], [nodes[i]].concat(args));
}
return newChild;
},
};
}

function getSpacerForLineIndents(tree, lineInfos) {
Expand Down
7 changes: 5 additions & 2 deletions lib/versioned/^3.7.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var stdout = require('mute-stdout');
var tildify = require('tildify');

var taskTree = require('./taskTree');

var logTasks = require('../../shared/log/tasks');
var isString = require('../../shared/is-string');
var logEvents = require('./log/events');
Expand Down Expand Up @@ -34,17 +35,19 @@ function execute(opts, env, config) {
stdout.unmute();

process.nextTick(function() {
var tree;

if (opts.tasksSimple) {
return logTasksSimple(env, gulpInst);
}
if (opts.tasks) {
var tree = taskTree(gulpInst.tasks);
tree = taskTree(gulpInst.tasks);
if (config.description && isString(config.description)) {
tree.label = config.description;
} else {
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
}
return logTasks(tree, opts.depth, function(task) {
return logTasks(tree, opts, function(task) {
return gulpInst.tasks[task].fn;
});
}
Expand Down

0 comments on commit 86f5df8

Please sign in to comment.