From 0c826daaf7e5840b6c3692721ddfc586d3bd4304 Mon Sep 17 00:00:00 2001
From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com>
Date: Wed, 5 Sep 2018 12:10:49 -0400
Subject: [PATCH] upgrade to gulp 4 (#2930)
* upgrade to gulp 4
* update circleci config
* removed some tasks and added notest flag
* update lint dependency for test task
---
.circleci/config.yml | 2 +-
README.md | 2 +
gulpfile.js | 318 ++++++++++++++++++++++++-------------------
package.json | 4 +-
4 files changed, 183 insertions(+), 143 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 62c23390666a..fbf7e77e10fe 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -33,7 +33,7 @@ jobs:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- - run: sudo npm install -g gulp
+ - run: sudo npm install -g gulp-cli
# Download and run BrowserStack local
- run:
name : Download BrowserStack Local binary and start it.
diff --git a/README.md b/README.md
index e43833fd4d2e..137374ebaa75 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,8 @@ Working examples can be found in [the developer docs](http://prebid.org/dev-docs
$ npm install
*Note:* You need to have `NodeJS` 4.x or greater installed.
+*Note:* Because we have transitioned to using gulp 4.0 - you need to have `gulp-cli` installed globally prior to running the general `npm install`. Run the following command to perform the install: `npm install gulp-cli -g`
+If you have a previous version of `gulp` installed globally, you'll need to remove it before installing `gulp-cli`. This removal can be done with the command: `npm rm gulp -g`
diff --git a/gulpfile.js b/gulpfile.js
index 92dd2a7c1f18..b373e6299c6d 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -5,18 +5,15 @@ var argv = require('yargs').argv;
var gulp = require('gulp');
var gutil = require('gulp-util');
var connect = require('gulp-connect');
-var path = require('path');
var webpack = require('webpack');
var webpackStream = require('webpack-stream');
var uglify = require('gulp-uglify');
-var clean = require('gulp-clean');
+var gulpClean = require('gulp-clean');
var KarmaServer = require('karma').Server;
var karmaConfMaker = require('./karma.conf.maker');
var opens = require('open');
var webpackConfig = require('./webpack.conf');
var helpers = require('./gulpHelpers');
-var del = require('del');
-var gulpDocumentation = require('gulp-documentation');
var concat = require('gulp-concat');
var header = require('gulp-header');
var footer = require('gulp-footer');
@@ -36,23 +33,131 @@ var banner = '/* <%= prebid.name %> v<%= prebid.version %>\n' + dateString + ' *
var analyticsDirectory = '../analytics';
var port = 9999;
-// Tasks
-gulp.task('default', ['webpack']);
+// these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules
+var explicitModules = [
+ 'pre1api'
+];
-gulp.task('serve', ['build-bundle-dev', 'watch', 'test']);
+// all the following functions are task functions
+function bundleToStdout() {
+ nodeBundle().then(file => console.log(file));
+}
+bundleToStdout.displayName = 'bundle-to-stdout';
-gulp.task('serve-nw', ['lint', 'watch', 'e2etest']);
+function clean() {
+ return gulp.src(['build'], {
+ read: false,
+ allowEmpty: true
+ })
+ .pipe(gulpClean());
+}
-gulp.task('run-tests', ['lint', 'test-coverage']);
+function e2etestReport() {
+ var reportPort = 9010;
+ var targetDestinationDir = './e2etest-report';
+ helpers.createEnd2EndTestReport(targetDestinationDir);
+ connect.server({
+ port: reportPort,
+ root: './',
+ livereload: true
+ });
-gulp.task('build', ['build-bundle-prod']);
+ setTimeout(function() {
+ opens('http://localhost:' + reportPort + '/' + targetDestinationDir.slice(2) + '/results.html');
+ }, 5000);
+};
+e2etestReport.displayName = 'e2etest-report';
-gulp.task('clean', function () {
- return gulp.src(['build'], {
- read: false
- })
- .pipe(clean());
-});
+// Dependant task for building postbid. It escapes postbid-config file.
+function escapePostbidConfig() {
+ gulp.src('./integrationExamples/postbid/oas/postbid-config.js')
+ .pipe(jsEscape())
+ .pipe(gulp.dest('build/postbid/'));
+};
+escapePostbidConfig.displayName = 'escape-postbid-config';
+
+function lint() {
+ return gulp.src(['src/**/*.js', 'modules/**/*.js', 'test/**/*.js'])
+ .pipe(eslint())
+ .pipe(eslint.format('stylish'))
+ .pipe(eslint.failAfterError());
+};
+
+// View the code coverage report in the browser.
+function viewCoverage(done) {
+ var coveragePort = 1999;
+
+ connect.server({
+ port: coveragePort,
+ root: 'build/coverage/karma_html',
+ livereload: false
+ });
+ opens('http://localhost:' + coveragePort);
+ done();
+};
+viewCoverage.displayName = 'view-coverage';
+
+// Watch Task with Live Reload
+function watch(done) {
+ var mainWatcher = gulp.watch([
+ 'src/**/*.js',
+ 'modules/**/*.js',
+ 'test/spec/**/*.js',
+ '!test/spec/loaders/**/*.js'
+ ]);
+ var loaderWatcher = gulp.watch([
+ 'loaders/**/*.js',
+ 'test/spec/loaders/**/*.js'
+ ]);
+
+ connect.server({
+ https: argv.https,
+ port: port,
+ root: './',
+ livereload: true
+ });
+
+ mainWatcher.on('all', gulp.series(clean, gulp.parallel(lint, 'build-bundle-dev', test)));
+ loaderWatcher.on('all', gulp.series(lint));
+ done();
+};
+
+function makeDevpackPkg() {
+ var cloned = _.cloneDeep(webpackConfig);
+ cloned.devtool = 'source-map';
+ var externalModules = helpers.getArgModules();
+
+ const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory);
+ const moduleSources = helpers.getModulePaths(externalModules);
+
+ return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
+ .pipe(helpers.nameModules(externalModules))
+ .pipe(webpackStream(cloned, webpack))
+ .pipe(replace('$prebid.version$', prebid.version))
+ .pipe(gulp.dest('build/dev'))
+ .pipe(connect.reload());
+}
+
+function makeWebpackPkg() {
+ var cloned = _.cloneDeep(webpackConfig);
+
+ delete cloned.devtool;
+
+ var externalModules = helpers.getArgModules();
+
+ const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory);
+ const moduleSources = helpers.getModulePaths(externalModules);
+
+ return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
+ .pipe(helpers.nameModules(externalModules))
+ .pipe(webpackStream(cloned, webpack))
+ .pipe(replace('$prebid.version$', prebid.version))
+ .pipe(uglify())
+ .pipe(gulpif(file => file.basename === 'prebid-core.js', header(banner, { prebid: prebid })))
+ .pipe(optimizejs())
+ .pipe(gulp.dest('build/dist'))
+ .pipe(connect.reload());
+}
function gulpBundle(dev) {
return bundle(dev).pipe(gulp.dest('build/' + (dev ? 'dev' : 'dist')));
@@ -71,14 +176,9 @@ function nodeBundle(modules) {
});
}
-// these modules must be explicitly listed in --modules to be included in the build, won't be part of "all" modules
-var explicitModules = [
- 'pre1api'
-];
-
function bundle(dev, moduleArr) {
- var modules = moduleArr || helpers.getArgModules(),
- allModules = helpers.getModuleNames(modules);
+ var modules = moduleArr || helpers.getArgModules();
+ var allModules = helpers.getModuleNames(modules);
if (modules.length === 0) {
modules = allModules.filter(module => !explicitModules.includes(module));
@@ -125,7 +225,8 @@ function newKarmaCallback(done) {
done(new Error('Karma tests failed with exit code ' + exitCode));
} else {
if (argv.browserstack) {
- process.exit(0);
+ // process.exit(0);
+ done(); // test this with travis (or circleci)
} else {
done();
}
@@ -133,51 +234,6 @@ function newKarmaCallback(done) {
}
}
-gulp.task('build-bundle-dev', ['devpack'], gulpBundle.bind(null, true));
-gulp.task('build-bundle-prod', ['webpack'], gulpBundle.bind(null, false));
-gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenating pre-built files with no build step
-
-gulp.task('bundle-to-stdout', function() {
- nodeBundle().then(file => console.log(file));
-});
-
-gulp.task('devpack', ['clean'], function () {
- var cloned = _.cloneDeep(webpackConfig);
- cloned.devtool = 'source-map';
- var externalModules = helpers.getArgModules();
-
- const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory);
- const moduleSources = helpers.getModulePaths(externalModules);
-
- return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
- .pipe(helpers.nameModules(externalModules))
- .pipe(webpackStream(cloned, webpack))
- .pipe(replace('$prebid.version$', prebid.version))
- .pipe(gulp.dest('build/dev'))
- .pipe(connect.reload());
-});
-
-gulp.task('webpack', ['clean'], function () {
- var cloned = _.cloneDeep(webpackConfig);
-
- delete cloned.devtool;
-
- var externalModules = helpers.getArgModules();
-
- const analyticsSources = helpers.getAnalyticsSources(analyticsDirectory);
- const moduleSources = helpers.getModulePaths(externalModules);
-
- return gulp.src([].concat(moduleSources, analyticsSources, 'src/prebid.js'))
- .pipe(helpers.nameModules(externalModules))
- .pipe(webpackStream(cloned, webpack))
- .pipe(replace('$prebid.version$', prebid.version))
- .pipe(uglify())
- .pipe(gulpif(file => file.basename === 'prebid-core.js', header(banner, { prebid: prebid })))
- .pipe(optimizejs())
- .pipe(gulp.dest('build/dist'))
- .pipe(connect.reload());
-});
-
// Run the unit tests.
//
// By default, this runs in headless chrome.
@@ -186,41 +242,33 @@ gulp.task('webpack', ['clean'], function () {
// If --file "" is given, the task will only run tests in the specified file.
// If --browserstack is given, it will run the full suite of currently supported browsers.
// If --browsers is given, browsers can be chosen explicitly. e.g. --browsers=chrome,firefox,ie9
-gulp.task('test', ['clean', 'lint'], function (done) {
- var karmaConf = karmaConfMaker(false, argv.browserstack, argv.watch, argv.file);
+// If --notest is given, it will immediately skip the test task (useful for developing changes with `gulp serve --notest`)
+function test(done) {
+ if (argv.notest) {
+ done();
+ } else {
+ var karmaConf = karmaConfMaker(false, argv.browserstack, argv.watch, argv.file);
- var browserOverride = helpers.parseBrowserArgs(argv).map(helpers.toCapitalCase);
- if (browserOverride.length > 0) {
- karmaConf.browsers = browserOverride;
- }
+ var browserOverride = helpers.parseBrowserArgs(argv).map(helpers.toCapitalCase);
+ if (browserOverride.length > 0) {
+ karmaConf.browsers = browserOverride;
+ }
- new KarmaServer(karmaConf, newKarmaCallback(done)).start();
-});
+ new KarmaServer(karmaConf, newKarmaCallback(done)).start();
+ }
+}
// If --file "" is given, the task will only run tests in the specified file.
-gulp.task('test-coverage', ['clean'], function(done) {
+function testCoverage(done) {
new KarmaServer(karmaConfMaker(true, false, false, argv.file), newKarmaCallback(done)).start();
-});
-
-// View the code coverage report in the browser.
-gulp.task('view-coverage', function (done) {
- var coveragePort = 1999;
-
- connect.server({
- port: coveragePort,
- root: 'build/coverage/karma_html',
- livereload: false
- });
- opens('http://localhost:' + coveragePort);
- done();
-});
+}
-gulp.task('coveralls', ['test-coverage'], function() { // 2nd arg is a dependency: 'test' must be finished
+function coveralls() { // 2nd arg is a dependency: 'test' must be finished
// first send results of istanbul's test coverage to coveralls.io.
return gulp.src('gulpfile.js', { read: false }) // You have to give it a file, but you don't
// have to read it.
.pipe(shell('cat build/coverage/lcov.info | node_modules/coveralls/bin/coveralls.js'));
-});
+}
// Watch Task with Live Reload
gulp.task('watch', function () {
@@ -242,27 +290,7 @@ gulp.task('watch', function () {
});
});
-gulp.task('lint', () => {
- return gulp.src(['src/**/*.js', 'modules/**/*.js', 'test/**/*.js'])
- .pipe(eslint())
- .pipe(eslint.format('stylish'))
- .pipe(eslint.failAfterError());
-});
-
-gulp.task('clean-docs', function () {
- del(['docs']);
-});
-
-gulp.task('docs', ['clean-docs'], function () {
- return gulp.src('src/prebid.js')
- .pipe(gulpDocumentation('md'))
- .on('error', function (err) {
- gutil.log('`gulp-documentation` failed:', err.message);
- })
- .pipe(gulp.dest('docs'));
-});
-
-gulp.task('e2etest', ['devpack', 'webpack'], function() {
+function e2eTest() {
var cmdQueue = [];
if (argv.browserstack) {
var browsers = require('./browsers.json');
@@ -289,38 +317,50 @@ gulp.task('e2etest', ['devpack', 'webpack'], function() {
return gulp.src('')
.pipe(shell(cmdQueue.join(';')));
-});
-
-gulp.task('e2etest-report', function() {
- var reportPort = 9010;
- var targetDestinationDir = './e2etest-report';
- helpers.createEnd2EndTestReport(targetDestinationDir);
- connect.server({
- port: reportPort,
- root: './',
- livereload: true
- });
-
- setTimeout(function() {
- opens('http://localhost:' + reportPort + '/' + targetDestinationDir.slice(2) + '/results.html');
- }, 5000);
-});
+}
// This task creates postbid.js. Postbid setup is different from prebid.js
// More info can be found here http://prebid.org/overview/what-is-post-bid.html
-gulp.task('build-postbid', ['escape-postbid-config'], function() {
+
+function buildPostbid() {
var fileContent = fs.readFileSync('./build/postbid/postbid-config.js', 'utf8');
return gulp.src('./integrationExamples/postbid/oas/postbid.js')
.pipe(replace('\[%%postbid%%\]', fileContent))
.pipe(gulp.dest('build/postbid/'));
-});
+}
-// Dependant task for building postbid. It escapes postbid-config file.
-gulp.task('escape-postbid-config', function() {
- gulp.src('./integrationExamples/postbid/oas/postbid-config.js')
- .pipe(jsEscape())
- .pipe(gulp.dest('build/postbid/'));
-});
+// support tasks
+gulp.task(lint);
+gulp.task(watch);
+
+gulp.task(clean);
+
+gulp.task(escapePostbidConfig);
+
+gulp.task('build-bundle-dev', gulp.series(makeDevpackPkg, gulpBundle.bind(null, true)));
+gulp.task('build-bundle-prod', gulp.series(makeWebpackPkg, gulpBundle.bind(null, false)));
+
+// public tasks (dependencies are needed for each task since they can be ran on their own)
+gulp.task('test', gulp.series(clean, lint, test));
+
+gulp.task('test-coverage', gulp.series(clean, testCoverage));
+gulp.task(viewCoverage);
+
+gulp.task('coveralls', gulp.series('test-coverage', coveralls));
+
+gulp.task('build', gulp.series(clean, 'build-bundle-prod'));
+gulp.task('build-postbid', gulp.series(escapePostbidConfig, buildPostbid));
+
+gulp.task('serve', gulp.series(clean, lint, gulp.parallel('build-bundle-dev', watch, test)));
+gulp.task('default', gulp.series(clean, makeWebpackPkg));
+
+gulp.task(e2etestReport);
+gulp.task('e2etest', gulp.series(clean, gulp.parallel(makeDevpackPkg, makeWebpackPkg), e2eTest));
+
+// other tasks
+gulp.task(bundleToStdout);
+gulp.task('bundle', gulpBundle.bind(null, false)); // used for just concatenating pre-built files with no build step
+gulp.task('serve-nw', gulp.parallel(lint, watch, 'e2etest'));
module.exports = nodeBundle;
diff --git a/package.json b/package.json
index 77181edc6a5d..9d2de7d4e379 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,6 @@
"block-loader": "^2.1.0",
"chai": "^3.3.0",
"coveralls": "^3.0.1",
- "del": "^2.2.0",
"documentation": "^5.2.2",
"ejs": "^2.5.1",
"es5-shim": "^4.5.2",
@@ -42,12 +41,11 @@
"eslint-plugin-standard": "^3.0.1",
"faker": "^3.1.0",
"fs.extra": "^1.3.2",
- "gulp": "^3.9.1",
+ "gulp": "^4.0.0",
"gulp-babel": "^6.1.2",
"gulp-clean": "^0.3.2",
"gulp-concat": "^2.6.0",
"gulp-connect": "5.5.0",
- "gulp-documentation": "^3.2.1",
"gulp-eslint": "^4.0.0",
"gulp-footer": "^1.0.5",
"gulp-header": "^1.7.1",