Skip to content

Commit f06ff30

Browse files
authored
feat: Add versioned handler for gulp v5 (#265)
1 parent e16d675 commit f06ff30

File tree

6 files changed

+248
-0
lines changed

6 files changed

+248
-0
lines changed

lib/versioned/^5.0.0/format-error.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
// Format orchestrator errors
4+
/* istanbul ignore next */
5+
function formatError(e) {
6+
if (!e.error) {
7+
return e.message;
8+
}
9+
10+
// PluginError
11+
if (typeof e.error.showStack === 'boolean') {
12+
return e.error.toString();
13+
}
14+
15+
// Normal error
16+
if (e.error.stack) {
17+
return e.error.stack;
18+
}
19+
20+
// Unknown (string, number, etc.)
21+
return new Error(String(e.error)).stack;
22+
}
23+
24+
module.exports = formatError;

lib/versioned/^5.0.0/index.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
'use strict';
2+
3+
var fs = require('fs');
4+
5+
var log = require('gulplog');
6+
var stdout = require('mute-stdout');
7+
var messages = require('@gulpjs/messages');
8+
9+
var exit = require('../../shared/exit');
10+
11+
var logTasks = require('../../shared/log/tasks');
12+
var logEvents = require('./log/events');
13+
var logSyncTask = require('./log/sync-task');
14+
var logTasksSimple = require('./log/tasks-simple');
15+
var registerExports = require('../../shared/register-exports');
16+
17+
var copyTree = require('../../shared/log/copy-tree');
18+
var getTask = require('./log/get-task');
19+
var requireOrImport = require('../../shared/require-or-import');
20+
21+
function execute(env, opts, translate) {
22+
var tasks = opts._;
23+
var toRun = tasks.length ? tasks : ['default'];
24+
25+
if (opts.tasksSimple || opts.tasks || opts.tasksJson) {
26+
// Mute stdout if we are listing tasks
27+
stdout.mute();
28+
}
29+
30+
var gulpInst = require(env.modulePath);
31+
logEvents(gulpInst);
32+
logSyncTask(gulpInst, opts);
33+
34+
// This is what actually loads up the gulpfile
35+
requireOrImport(env.configPath, function(err, exported) {
36+
// Before import(), if require() failed we got an unhandled exception on the module level.
37+
// So console.error() & exit() were added here to mimic the old behavior as close as possible.
38+
if (err) {
39+
console.error(err);
40+
exit(1);
41+
}
42+
43+
registerExports(gulpInst, exported);
44+
45+
// Always unmute stdout after gulpfile is required
46+
stdout.unmute();
47+
48+
var tree;
49+
if (opts.tasksSimple) {
50+
tree = gulpInst.tree();
51+
return logTasksSimple(tree.nodes);
52+
}
53+
if (opts.tasks) {
54+
tree = gulpInst.tree({ deep: true });
55+
tree.label = translate.message({ tag: messages.DESCRIPTION, path: env.configPath });
56+
57+
return logTasks(tree, opts, getTask(gulpInst), translate);
58+
}
59+
if (opts.tasksJson) {
60+
tree = gulpInst.tree({ deep: true });
61+
tree.label = translate.message({ tag: messages.DESCRIPTION, path: env.configPath });
62+
63+
var output = JSON.stringify(copyTree(tree, opts));
64+
65+
if (typeof opts.tasksJson === 'boolean' && opts.tasksJson) {
66+
return console.log(output);
67+
}
68+
return fs.writeFileSync(opts.tasksJson, output, 'utf-8');
69+
}
70+
try {
71+
log.info({ tag: messages.GULPFILE, path: env.configPath });
72+
var runMethod = opts.series ? 'series' : 'parallel';
73+
gulpInst[runMethod](toRun)(function(err) {
74+
if (err) {
75+
exit(1);
76+
}
77+
});
78+
} catch (err) {
79+
if (err.task) {
80+
log.error({ tag: messages.TASK_MISSING, task: err.task, similar: err.similar });
81+
} else {
82+
log.error({ tag: messages.EXEC_ERROR, message: err.message, error: err });
83+
}
84+
exit(1);
85+
}
86+
});
87+
}
88+
89+
module.exports = execute;

lib/versioned/^5.0.0/log/events.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
3+
var log = require('gulplog');
4+
var messages = require('@gulpjs/messages');
5+
6+
var formatError = require('../format-error');
7+
8+
// Wire up logging events
9+
function logEvents(gulpInst) {
10+
11+
var loggedErrors = [];
12+
13+
gulpInst.on('start', function(evt) {
14+
/* istanbul ignore next */
15+
// TODO: batch these
16+
// so when 5 tasks start at once it only logs one time with all 5
17+
var level = evt.branch ? 'debug' : 'info';
18+
log[level]({ tag: messages.TASK_START, task: evt.name });
19+
});
20+
21+
gulpInst.on('stop', function(evt) {
22+
/* istanbul ignore next */
23+
var level = evt.branch ? 'debug' : 'info';
24+
log[level]({ tag: messages.TASK_STOP, task: evt.name, duration: evt.duration });
25+
});
26+
27+
gulpInst.on('error', function(evt) {
28+
var level = evt.branch ? 'debug' : 'error';
29+
log[level]({ tag: messages.TASK_FAILURE, task: evt.name, duration: evt.duration });
30+
31+
// If we haven't logged this before, log it and add to list
32+
if (loggedErrors.indexOf(evt.error) === -1) {
33+
log.error({ tag: messages.TASK_ERROR, message: formatError(evt) });
34+
loggedErrors.push(evt.error);
35+
}
36+
});
37+
}
38+
39+
module.exports = logEvents;

lib/versioned/^5.0.0/log/get-task.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
var isObject = require('../../../shared/is-object');
4+
5+
function getTask(gulpInst) {
6+
return function(name) {
7+
var task = gulpInst.task(name);
8+
return {
9+
description: getDescription(task),
10+
flags: getFlags(task),
11+
};
12+
};
13+
}
14+
15+
function getDescription(task) {
16+
if (typeof task.description === 'string') {
17+
return task.description;
18+
}
19+
/* istanbul ignore else */
20+
if (typeof task.unwrap === 'function') {
21+
var origFn = task.unwrap();
22+
if (typeof origFn.description === 'string') {
23+
return origFn.description;
24+
}
25+
}
26+
return undefined;
27+
}
28+
29+
function getFlags(task) {
30+
if (isObject(task.flags)) {
31+
return task.flags;
32+
}
33+
/* istanbul ignore else */
34+
if (typeof task.unwrap === 'function') {
35+
var origFn = task.unwrap();
36+
if (isObject(origFn.flags)) {
37+
return origFn.flags;
38+
}
39+
}
40+
return undefined;
41+
}
42+
43+
module.exports = getTask;

lib/versioned/^5.0.0/log/sync-task.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
var log = require('gulplog');
4+
var messages = require('@gulpjs/messages');
5+
6+
var tasks = {};
7+
8+
function warn() {
9+
var taskKeys = Object.keys(tasks);
10+
11+
if (!taskKeys.length) {
12+
return;
13+
}
14+
15+
var taskNames = taskKeys.map(function(key) {
16+
return tasks[key];
17+
}).join(', ');
18+
19+
process.exitCode = 1;
20+
21+
log.warn({ tag: messages.TASK_SYNC, tasks: taskNames });
22+
}
23+
24+
function start(e) {
25+
tasks[e.uid] = e.name;
26+
}
27+
28+
function clear(e) {
29+
delete tasks[e.uid];
30+
}
31+
32+
function clearAll() {
33+
tasks = {};
34+
}
35+
36+
function logSyncTask(gulpInst, opts) {
37+
38+
process.once('exit', warn);
39+
gulpInst.on('start', start);
40+
gulpInst.on('stop', clear);
41+
// When not running in --continue mode, we need to clear everything on error to avoid
42+
// false positives.
43+
gulpInst.on('error', opts.continue ? clear : clearAll);
44+
}
45+
46+
module.exports = logSyncTask;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
function logTasksSimple(nodes) {
4+
console.log(nodes.join('\n').trim());
5+
}
6+
7+
module.exports = logTasksSimple;

0 commit comments

Comments
 (0)