Skip to content

Commit 50027d4

Browse files
committed
New: Add initial support for 3.x & 4.0
1 parent 5ea7700 commit 50027d4

19 files changed

+465
-144
lines changed

index.js

Lines changed: 93 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
#!/usr/bin/env node
22

33
'use strict';
4+
var path = require('path');
45
var gutil = require('gulp-util');
5-
var prettyTime = require('pretty-hrtime');
66
var chalk = require('chalk');
7+
var nomnom = require('nomnom');
78
var semver = require('semver');
8-
var archy = require('archy');
99
var Liftoff = require('liftoff');
1010
var tildify = require('tildify');
1111
var interpret = require('interpret');
1212
var v8flags = require('v8flags');
13+
var exit = require('./lib/exit');
14+
var cliOptions = require('./lib/cliOptions');
1315
var completion = require('./lib/completion');
14-
var argv = require('minimist')(process.argv.slice(2));
15-
var taskTree = require('./lib/taskTree');
16+
var verifyDeps = require('./lib/verifyDependencies');
17+
var cliVersion = require('./package.json').version;
18+
var getBlacklist = require('./lib/getBlacklist');
19+
20+
// Logging functions
21+
var logVerify = require('./lib/log/verify');
22+
var logBlacklistError = require('./lib/log/blacklistError');
1623

1724
// Set env var for ORIGINAL cwd
1825
// before anything touches it
@@ -25,25 +32,16 @@ var cli = new Liftoff({
2532
v8flags: v8flags,
2633
});
2734

28-
// Exit with 0 or 1
29-
var failed = false;
30-
process.once('exit', function(code) {
31-
if (code === 0 && failed) {
32-
exit(1);
33-
}
34-
});
35-
36-
// Parse those args m8
37-
var cliPackage = require('./package');
38-
var versionFlag = argv.v || argv.version;
39-
var tasksFlag = argv.T || argv.tasks;
40-
var tasks = argv._;
35+
var opts = nomnom
36+
.script('gulp')
37+
.options(cliOptions)
38+
.parse();
39+
var tasks = opts._;
4140
var toRun = tasks.length ? tasks : ['default'];
4241

4342
// This is a hold-over until we have a better logging system
4443
// with log levels
45-
var simpleTasksFlag = argv['tasks-simple'];
46-
var shouldLog = !argv.silent && !simpleTasksFlag;
44+
var shouldLog = !opts.silent && !opts.tasksSimple;
4745

4846
if (!shouldLog) {
4947
gutil.log = function() {};
@@ -66,25 +64,42 @@ cli.on('respawn', function(flags, child) {
6664

6765
function run() {
6866
cli.launch({
69-
cwd: argv.cwd,
70-
configPath: argv.gulpfile,
71-
require: argv.require,
72-
completion: argv.completion,
67+
cwd: opts.cwd,
68+
configPath: opts.gulpfile,
69+
require: opts.require,
70+
completion: opts.completion,
7371
}, handleArguments);
7472
}
7573

7674
module.exports = run;
7775

7876
// The actual logic
7977
function handleArguments(env) {
80-
if (versionFlag && tasks.length === 0) {
81-
gutil.log('CLI version', cliPackage.version);
78+
if (opts.version) {
79+
gutil.log('CLI version', cliVersion);
8280
if (env.modulePackage && typeof env.modulePackage.version !== 'undefined') {
8381
gutil.log('Local version', env.modulePackage.version);
8482
}
8583
exit(0);
8684
}
8785

86+
if (opts.verify) {
87+
var pkgPath = opts.verify !== true ? opts.verify : 'package.json';
88+
if (path.resolve(pkgPath) !== path.normalize(pkgPath)) {
89+
pkgPath = path.join(env.configBase, pkgPath);
90+
}
91+
gutil.log('Verifying plugins in ' + pkgPath);
92+
return getBlacklist(function(err, blacklist) {
93+
if (err) {
94+
return logBlacklistError(err);
95+
}
96+
97+
var blacklisted = verifyDeps(require(pkgPath), blacklist);
98+
99+
logVerify(blacklisted);
100+
});
101+
}
102+
88103
if (!env.modulePath) {
89104
gutil.log(
90105
chalk.red('Local gulp not found in'),
@@ -100,9 +115,9 @@ function handleArguments(env) {
100115
}
101116

102117
// Check for semver difference between cli and local installation
103-
if (semver.gt(cliPackage.version, env.modulePackage.version)) {
118+
if (semver.gt(cliVersion, env.modulePackage.version)) {
104119
gutil.log(chalk.red('Warning: gulp version mismatch:'));
105-
gutil.log(chalk.red('Global gulp is', cliPackage.version));
120+
gutil.log(chalk.red('Global gulp is', cliVersion));
106121
gutil.log(chalk.red('Local gulp is', env.modulePackage.version));
107122
}
108123

@@ -116,6 +131,20 @@ function handleArguments(env) {
116131
);
117132
}
118133

134+
if (semver.satisfies(env.modulePackage.version, '^3')) {
135+
return gulp3(env);
136+
}
137+
138+
if (semver.satisfies(env.modulePackage.version, '^4')) {
139+
return gulp4(env);
140+
}
141+
}
142+
143+
function gulp3(env) {
144+
var logTasks = require('./lib/3/logTasks');
145+
var logEvents = require('./lib/3/logEvents');
146+
var logTasksSimple = require('./lib/3/logTasksSimple');
147+
119148
// This is what actually loads up the gulpfile
120149
require(env.configPath);
121150
gutil.log('Using gulpfile', chalk.magenta(tildify(env.configPath)));
@@ -124,128 +153,53 @@ function handleArguments(env) {
124153
logEvents(gulpInst);
125154

126155
process.nextTick(function() {
127-
if (simpleTasksFlag) {
156+
if (opts.tasksSimple) {
128157
return logTasksSimple(env, gulpInst);
129158
}
130-
if (tasksFlag) {
159+
if (opts.tasks) {
131160
return logTasks(env, gulpInst);
132161
}
133162
gulpInst.start.apply(gulpInst, toRun);
134163
});
135164
}
136165

137-
function logTasks(env, localGulp) {
138-
var tree = taskTree(localGulp.tasks);
139-
var padding = 0;
140-
var rdependency = /[ ] []/;
141-
tree.label = 'Tasks for ' + chalk.magenta(tildify(env.configPath));
142-
archy(tree)
143-
.split('\n')
144-
.filter(function(v, i) {
145-
// Log first line as is
146-
if (i === 0) {
147-
gutil.log(v);
148-
return false;
149-
}
150-
// Search for longest line
151-
if (v.length > padding) {
152-
padding = v.length;
153-
}
154-
return v.trim().length !== 0;
155-
}).forEach(function(v) {
156-
var line = v.split(' ');
157-
var task = line.slice(1).join(' ');
158-
159-
// Log dependencies as is
160-
if (rdependency.test(v)) {
161-
gutil.log(v);
162-
return;
163-
}
164-
165-
// Pretty task with optional description
166-
gutil.log(
167-
line[0] + ' ' + chalk.cyan(task) +
168-
Array(padding + 3 - v.length).join(' ') +
169-
(localGulp.tasks[task].fn.description || '')
170-
);
171-
});
172-
}
173-
174-
function logTasksSimple(env, localGulp) {
175-
console.log(Object.keys(localGulp.tasks)
176-
.join('\n')
177-
.trim());
178-
}
179-
180-
// Format orchestrator errors
181-
function formatError(e) {
182-
if (!e.err) {
183-
return e.message;
184-
}
185-
186-
// PluginError
187-
if (typeof e.err.showStack === 'boolean') {
188-
return e.err.toString();
189-
}
190-
191-
// Normal error
192-
if (e.err.stack) {
193-
return e.err.stack;
194-
}
195-
196-
// Unknown (string, number, etc.)
197-
return new Error(String(e.err)).stack;
198-
}
199-
200-
// Wire up logging events
201-
function logEvents(gulpInst) {
166+
function gulp4(env) {
167+
var logTasks = require('./lib/log/tasks');
168+
var logEvents = require('./lib/logEvents');
169+
var logTasksSimple = require('./lib/log/tasksSimple');
202170

203-
// Total hack due to poor error management in orchestrator
204-
gulpInst.on('err', function() {
205-
failed = true;
206-
});
207-
208-
gulpInst.on('task_start', function(e) {
209-
// TODO: batch these
210-
// So when 5 tasks start at once it only logs one time with all 5
211-
gutil.log('Starting', '\'' + chalk.cyan(e.task) + '\'...');
212-
});
213-
214-
gulpInst.on('task_stop', function(e) {
215-
var time = prettyTime(e.hrDuration);
216-
gutil.log(
217-
'Finished', '\'' + chalk.cyan(e.task) + '\'',
218-
'after', chalk.magenta(time)
219-
);
220-
});
171+
var gulpInst = require(env.modulePath);
172+
logEvents(gulpInst);
221173

222-
gulpInst.on('task_err', function(e) {
223-
var msg = formatError(e);
224-
var time = prettyTime(e.hrDuration);
225-
gutil.log(
226-
'\'' + chalk.cyan(e.task) + '\'',
227-
chalk.red('errored after'),
228-
chalk.magenta(time)
229-
);
230-
gutil.log(msg);
231-
});
174+
// This is what actually loads up the gulpfile
175+
require(env.configPath);
232176

233-
gulpInst.on('task_not_found', function(err) {
234-
gutil.log(
235-
chalk.red('Task \'' + err.task + '\' is not in your gulpfile')
236-
);
237-
gutil.log('Please check the documentation for proper gulpfile formatting');
238-
exit(1);
177+
process.nextTick(function() {
178+
if (opts.tasksSimple) {
179+
return logTasksSimple(gulpInst.tree());
180+
}
181+
if (opts.tasks) {
182+
var tree = {
183+
label: 'Tasks for ' + chalk.magenta(tildify(env.configPath)),
184+
nodes: gulpInst.tree({ deep: true }),
185+
};
186+
return logTasks(tree);
187+
}
188+
if (opts.tasksJson) {
189+
return console.log(
190+
JSON.stringify(gulpInst.tree({ deep: true }), null, 2)
191+
);
192+
}
193+
try {
194+
gutil.log('Using gulpfile', chalk.magenta(tildify(env.configPath)));
195+
// TODO: do we care about the error/result from calling this?
196+
gulpInst.parallel(toRun)();
197+
} catch (err) {
198+
gutil.log(chalk.red(err.message));
199+
gutil.log(
200+
'Please check the documentation for proper gulpfile formatting'
201+
);
202+
exit(1);
203+
}
239204
});
240205
}
241-
242-
// Fix stdout truncation on windows
243-
function exit(code) {
244-
if (process.platform === 'win32' && process.stdout.bufferSize) {
245-
process.stdout.once('drain', function() {
246-
process.exit(code);
247-
});
248-
return;
249-
}
250-
process.exit(code);
251-
}

lib/3/formatError.js

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

lib/3/logEvents.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
var chalk = require('chalk');
4+
var gutil = require('gulp-util');
5+
var prettyTime = require('pretty-hrtime');
6+
7+
var exit = require('../exit');
8+
var formatError = require('./formatError');
9+
10+
// Wire up logging events
11+
function logEvents(gulpInst) {
12+
13+
// Exit with 0 or 1
14+
var failed = false;
15+
process.once('exit', function(code) {
16+
if (code === 0 && failed) {
17+
exit(1);
18+
}
19+
});
20+
21+
// Total hack due to poor error management in orchestrator
22+
gulpInst.on('err', function() {
23+
failed = true;
24+
});
25+
26+
gulpInst.on('task_start', function(e) {
27+
// TODO: batch these
28+
// so when 5 tasks start at once it only logs one time with all 5
29+
gutil.log('Starting', '\'' + chalk.cyan(e.task) + '\'...');
30+
});
31+
32+
gulpInst.on('task_stop', function(e) {
33+
var time = prettyTime(e.hrDuration);
34+
gutil.log(
35+
'Finished', '\'' + chalk.cyan(e.task) + '\'',
36+
'after', chalk.magenta(time)
37+
);
38+
});
39+
40+
gulpInst.on('task_err', function(e) {
41+
var msg = formatError(e);
42+
var time = prettyTime(e.hrDuration);
43+
gutil.log(
44+
'\'' + chalk.cyan(e.task) + '\'',
45+
chalk.red('errored after'),
46+
chalk.magenta(time)
47+
);
48+
gutil.log(msg);
49+
});
50+
51+
gulpInst.on('task_not_found', function(err) {
52+
gutil.log(
53+
chalk.red('Task \'' + err.task + '\' is not in your gulpfile')
54+
);
55+
gutil.log('Please check the documentation for proper gulpfile formatting');
56+
exit(1);
57+
});
58+
}
59+
60+
module.exports = logEvents;

0 commit comments

Comments
 (0)