Skip to content

Commit 3e0fc18

Browse files
sttkphated
authored andcommitted
New: Add --depth flag to pair with --tasks flag
1 parent 12f2e3f commit 3e0fc18

File tree

15 files changed

+313
-58
lines changed

15 files changed

+313
-58
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ __Some flags only work with gulp 4 and will be ignored when invoked against gulp
7878
<td>-T</td>
7979
<td>Print the task dependency tree for the loaded gulpfile.</td>
8080
</tr>
81+
<tr>
82+
<td>--depth [number]</td>
83+
<td></td>
84+
<td>Specify the depth of the task dependency tree to print.</td>
85+
</tr>
8186
<tr>
8287
<td>--tasks-simple</td>
8388
<td></td>

lib/shared/cliOptions.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ module.exports = {
4747
desc: chalk.gray(
4848
'Print the task dependency tree for the loaded gulpfile.'),
4949
},
50+
depth: {
51+
type: 'number',
52+
requiresArg: true,
53+
desc: chalk.gray(
54+
'Specify the depth of the task dependency tree.'),
55+
},
5056
'tasks-simple': {
5157
type: 'boolean',
5258
desc: chalk.gray(

lib/shared/log/tasks.js

Lines changed: 174 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,187 @@
33
var archy = require('archy');
44
var chalk = require('chalk');
55
var log = require('gulplog');
6+
var sortBy = require('lodash.sortby');
7+
8+
function isString(val) {
9+
return typeof val === 'string';
10+
}
11+
12+
function isObject(val) {
13+
return typeof val === 'object' && !Array.isArray(val);
14+
}
15+
16+
function logTasks(tree, depth, getTask) {
17+
depth = (typeof depth !== 'number') ? null : ((depth < 1) ? 1 : depth);
18+
19+
var lineInfos = [];
20+
var entryObserver = getLineInfoCollector(lineInfos);
21+
22+
tree = copyTree(tree, depth, getTask, entryObserver);
23+
24+
var spacer = getSpacerForLineIndents(tree, lineInfos);
25+
var lines = getLinesContainingOnlyBranches(tree);
26+
27+
log.info(tree.label);
28+
printTreeList(lines, spacer, lineInfos);
29+
}
30+
31+
function getLineInfoCollector(lineInfos) {
32+
return {
33+
topTask: function(node) {
34+
lineInfos.push({
35+
name: node.label,
36+
desc: node.desc,
37+
type: 'top',
38+
});
39+
},
40+
option: function(opt) {
41+
lineInfos.push({
42+
name: opt.label,
43+
desc: opt.desc,
44+
type: 'option',
45+
});
46+
},
47+
childTask: function(node) {
48+
lineInfos.push({
49+
name: node.label,
50+
type: 'child',
51+
});
52+
},
53+
};
54+
}
55+
56+
function copyTree(tree, depth, getTask, entryObserver) {
57+
var newTree = {
58+
label: tree.label,
59+
nodes: [],
60+
};
61+
62+
sortBy(tree.nodes, sorter).forEach(visit);
63+
64+
function sorter(node) {
65+
return node.label;
66+
}
67+
68+
function visit(node) {
69+
var task = getTask(node.label) || {};
70+
71+
var newNode = {
72+
label: node.label,
73+
desc: isString(task.description) ? task.description : '',
74+
opts: [],
75+
nodes: [],
76+
};
77+
entryObserver.topTask(newNode);
78+
newTree.nodes.push(newNode);
79+
80+
if (isObject(task.flags)) {
81+
Object.keys(task.flags).sort().forEach(function(flag) {
82+
if (flag.length === 0) {
83+
return;
84+
}
85+
var opt = {
86+
label: flag,
87+
desc: isString(task.flags[flag]) ? task.flags[flag] : '',
88+
};
89+
entryObserver.option(opt);
90+
newNode.opts.push(opt);
91+
newNode.label += '\n' + opt.label; // The way of archy for options.
92+
});
93+
}
94+
95+
if (!depth || depth > 1) {
96+
var fn = function(child, maxDepth, nowDepth, newParent) {
97+
var newChild = {
98+
label: child.label,
99+
nodes: [],
100+
};
101+
entryObserver.childTask(newChild);
102+
newChild.label = ''; // Because don't use child tasks to calc indents.
103+
newParent.nodes.push(newChild);
104+
if (!maxDepth || maxDepth > nowDepth) {
105+
forEachNode(child.nodes, fn, maxDepth, nowDepth + 1, newChild);
106+
}
107+
};
108+
forEachNode(node.nodes, fn, depth, 2, newNode);
109+
}
110+
}
111+
112+
return newTree;
113+
}
114+
115+
function forEachNode(nodes, fn) {
116+
if (!Array.isArray(nodes)) {
117+
return;
118+
}
119+
120+
var args = [].slice.call(arguments, 2);
121+
122+
for (var i = 0, n = nodes.length; i < n; i++) {
123+
fn.apply(nodes[i], [nodes[i]].concat(args));
124+
}
125+
}
126+
127+
function getSpacerForLineIndents(tree, lineInfos) {
128+
var maxSize = 0;
129+
var sizes = [];
6130

7-
function logTasks(tree, getDescription) {
8-
var padding = 0;
9-
var rdependency = /[ ] []/;
10131
archy(tree)
11132
.split('\n')
12-
.filter(function(v, i) {
13-
// Log first line as is
14-
if (i === 0) {
15-
log.info(v);
16-
return false;
133+
.slice(1, -1)
134+
.forEach(function(line, index) {
135+
var info = lineInfos[index];
136+
if (info.type === 'top' || info.type === 'option') {
137+
maxSize = Math.max(maxSize, line.length);
138+
sizes.push(line.length);
139+
} else {
140+
sizes.push(0);
17141
}
18-
// Search for longest line
19-
if (v.length > padding) {
20-
padding = v.length;
142+
});
143+
144+
maxSize += 3;
145+
146+
return function(index) {
147+
return Array(maxSize - sizes[index]).join(' ');
148+
};
149+
}
150+
151+
function getLinesContainingOnlyBranches(tree) {
152+
tree.nodes.forEach(function(node) {
153+
node.label = '';
154+
node.opts.forEach(function() {
155+
node.label += '\n';
156+
});
157+
});
158+
159+
return archy(tree)
160+
.split('\n')
161+
.slice(1, -1);
162+
}
163+
164+
function printTreeList(lines, spacer, lineInfos) {
165+
lines.forEach(function(branch, index) {
166+
var info = lineInfos[index];
167+
168+
var line = chalk.white(branch);
169+
170+
if (info.type === 'top') {
171+
line += chalk.cyan(info.name);
172+
if (info.desc.length > 0) {
173+
line += spacer(index) + chalk.white(info.desc);
21174
}
22-
return v.trim().length !== 0;
23-
}).forEach(function(v) {
24-
var line = v.split(' ');
25-
var task = line.slice(1).join(' ');
26-
27-
// Log dependencies as is
28-
if (rdependency.test(v)) {
29-
log.info(v);
30-
return;
175+
} else if (info.type === 'option') {
176+
line += chalk.magenta(info.name);
177+
if (info.desc.length > 0) {
178+
line += spacer(index) + chalk.white('…' + info.desc);
31179
}
180+
} else { // If (info.type === 'child') {
181+
line += chalk.white(info.name);
182+
}
32183

33-
// Pretty task with optional description
34-
log.info(
35-
line[0] + ' ' + chalk.cyan(task) +
36-
Array(padding + 3 - v.length).join(' ') +
37-
(getDescription(task) || '')
38-
);
39-
});
184+
log.info(line);
185+
});
40186
}
41187

42188
module.exports = logTasks;
189+

lib/versioned/^3.7.0/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ function execute(opts, env) {
3939
if (opts.tasks) {
4040
var tree = taskTree(gulpInst.tasks);
4141
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
42-
return logTasks(tree, function(task) {
43-
return gulpInst.tasks[task].fn.description;
42+
return logTasks(tree, opts.depth, function(task) {
43+
return gulpInst.tasks[task].fn;
4444
});
4545
}
4646
gulpInst.start.apply(gulpInst, toRun);

lib/versioned/^3.7.0/taskTree.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
'use strict';
22

33
module.exports = function(tasks) {
4-
return Object.keys(tasks)
5-
.reduce(function(prev, task) {
6-
prev.nodes.push({
7-
label: task,
8-
nodes: tasks[task].dep,
9-
});
10-
return prev;
11-
}, {
12-
nodes: [],
4+
var map = {};
5+
var arr = [];
6+
Object.keys(tasks).forEach(function(taskname) {
7+
var task = { label: taskname, nodes: [], };
8+
map[taskname] = task;
9+
arr.push(task);
10+
});
11+
Object.keys(tasks).forEach(function(taskname) {
12+
var task = map[taskname];
13+
tasks[taskname].dep.forEach(function(childname) {
14+
var child = map[childname] || { label: childname, nodes: [], };
15+
task.nodes.push(child);
1316
});
17+
});
18+
return { label: 'Tasks', nodes: arr, };
1419
};

lib/versioned/^4.0.0-alpha.1/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ function execute(opts, env) {
4646
label: 'Tasks for ' + chalk.magenta(tildify(env.configPath)),
4747
nodes: gulpInst.tree({ deep: true }),
4848
};
49-
return logTasks(tree, function(task) {
50-
return gulpInst.task(task).description;
49+
return logTasks(tree, opts.depth, function(taskname) {
50+
return gulpInst.task(taskname);
5151
});
5252
}
5353
if (opts.tasksJson) {

lib/versioned/^4.0.0-alpha.2/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ function execute(opts, env) {
4848
tree = gulpInst.tree({ deep: true });
4949
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
5050

51-
return logTasks(tree, function(task) {
52-
return gulpInst.task(task).description;
51+
return logTasks(tree, opts.depth, function(taskname) {
52+
return gulpInst.task(taskname);
5353
});
5454
}
5555
if (opts.tasksJson) {

lib/versioned/^4.0.0/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ function execute(opts, env) {
4848
tree = gulpInst.tree({ deep: true });
4949
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
5050

51-
return logTasks(tree, function(task) {
52-
return gulpInst.task(task).description;
51+
return logTasks(tree, opts.depth, function(taskname) {
52+
return gulpInst.task(taskname);
5353
});
5454
}
5555
if (opts.tasksJson) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"gulplog": "^1.0.0",
3737
"interpret": "^1.0.0",
3838
"liftoff": "^2.1.0",
39+
"lodash.sortby": "^4.0.1",
3940
"matchdep": "^1.0.0",
4041
"mute-stdout": "^1.0.0",
4142
"pretty-hrtime": "^1.0.0",

test/expected/flags-help.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Options:
99
--cwd Manually set the CWD. The search for the gulpfile, as well as the relativity of all requires will be from here. [string]
1010
--verify Will verify plugins referenced in project's package.json against the plugins blacklist.
1111
--tasks, -T Print the task dependency tree for the loaded gulpfile. [boolean]
12+
--depth Specify the depth of the task dependency tree.
1213
--tasks-simple Print a plaintext list of tasks for the loaded gulpfile. [boolean]
1314
--tasks-json Print the task dependency tree, in JSON format, for the loaded gulpfile.
1415
--color Will force gulp and gulp plugins to display colors, even when no color support is detected. [boolean]

0 commit comments

Comments
 (0)