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",