From 9ec1ed08c1ebb1f7d0bcdcb19d342541fb220e4f Mon Sep 17 00:00:00 2001 From: Christopher McCulloh Date: Fri, 20 Feb 2015 12:21:07 -0500 Subject: [PATCH] fixes #1094 makes dist compile and test prior to release. Also prompts for release type to determine new version number --- Gruntfile.js | 172 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 120 insertions(+), 52 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 536f59e19..613aee879 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,6 +1,6 @@ /*jshint expr:true*/ /*global module:false, process:false*/ -module.exports = function(grunt) { +module.exports = function (grunt) { 'use strict'; // use --no-livereload to disable livereload. Helpful to 'serve' multiple projects @@ -25,8 +25,8 @@ module.exports = function(grunt) { ' */\n', bump: { options: { - files: [ 'bower.json', 'package.json' ], - updateConfigs: [ 'pkg' ], + files: ['bower.json', 'package.json'], + updateConfigs: ['pkg'], commit: false, createTag: false, tagName: '%VERSION%', @@ -43,10 +43,11 @@ module.exports = function(grunt) { sauceLoginFile: grunt.file.exists('SAUCE_API_KEY.yml') ? grunt.file.readYAML('SAUCE_API_KEY.yml') : undefined, sauceUser: process.env.SAUCE_USERNAME || 'fuelux', sauceKey: process.env.SAUCE_ACCESS_KEY ? process.env.SAUCE_ACCESS_KEY : '<%= sauceLoginFile.key %>', - allTestUrls: ['2.1.0', '1.11.0', '1.9.1', 'browserGlobals'].map(function(ver) { + allTestUrls: ['2.1.0', '1.11.0', '1.9.1', 'browserGlobals'].map(function (ver) { if (ver === 'browserGlobals') { return 'http://localhost:<%= connect.testServer.options.port %>/test/fuelux-browser-globals.html'; } + return 'http://localhost:<%= connect.testServer.options.port %>/test/fuelux.html?jquery=' + ver + '&testdist=true'; }), testUrl: ['http://localhost:<%= connect.testServer.options.port %>/test/fuelux.html?jquery=' + '1.9.1&testdist=true'], @@ -54,7 +55,7 @@ module.exports = function(grunt) { //Tasks configuration clean: { dist: ['dist'], - zipsrc: ['dist/fuelux'], // temp folder + zipsrc: ['dist/fuelux'],// temp folder screenshots: ['page-at-timeout-*.jpg'] }, compress: { @@ -112,9 +113,9 @@ module.exports = function(grunt) { '<%= jqueryCheck %>' + '<%= bootstrapCheck %>', footer: '\n}));', - process: function(source) { + process: function (source) { source = '(function ($) {\n\n' + - source.replace(/\/\/ -- BEGIN UMD WRAPPER PREFACE --(\n|.)*\/\/ -- END UMD WRAPPER PREFACE --/g, ''); + source.replace(/\/\/ -- BEGIN UMD WRAPPER PREFACE --(\n|.)*\/\/ -- END UMD WRAPPER PREFACE --/g, ''); source = source.replace(/\/\/ -- BEGIN UMD WRAPPER AFTERWORD --(\n|.)*\/\/ -- END UMD WRAPPER AFTERWORD --/g, '') + '\n})(jQuery);\n\n'; return source; } @@ -126,14 +127,14 @@ module.exports = function(grunt) { options: { hostname: '*', port: process.env.PORT || 8000, - useAvailablePort: true // increment port number, if unavailable... + useAvailablePort: true// increment port number, if unavailable... } }, testServer: { options: { hostname: '*', - port: 9000, // allows main server to be run simultaneously - useAvailablePort: true // increment port number, if unavailable... + port: 9000,// allows main server to be run simultaneously + useAvailablePort: true// increment port number, if unavailable... } } }, @@ -193,7 +194,7 @@ module.exports = function(grunt) { noarg: true, sub: true, undef: true, - unused: false // changed + unused: false// changed }, source: ['Gruntfile.js', 'js/*.js', 'dist/fuelux.js'], tests: { @@ -253,15 +254,14 @@ module.exports = function(grunt) { 'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css' } }, - }, prompt: { bump: { options: { questions: [ { - config: 'bump.increment', - type: 'list', + config: 'bump.increment', + type: 'list', message: 'Bump version from ' + '<%= pkg.version %>' + ' to:', choices: [ // { @@ -270,27 +270,27 @@ module.exports = function(grunt) { // }, { value: 'patch', - name: 'Patch: ' + semver.inc(currentVersion, 'patch') + ' Backwards-compatible bug fixes.' + name: 'Patch: ' + semver.inc(currentVersion, 'patch') + ' Backwards-compatible bug fixes.' }, { value: 'minor', - name: 'Minor: ' + semver.inc(currentVersion, 'minor') + ' Add functionality in a backwards-compatible manner.' + name: 'Minor: ' + semver.inc(currentVersion, 'minor') + ' Add functionality in a backwards-compatible manner.' }, { value: 'major', - name: 'Major: ' + semver.inc(currentVersion, 'major') + ' Incompatible API changes.' + name: 'Major: ' + semver.inc(currentVersion, 'major') + ' Incompatible API changes.' }, { value: 'custom', - name: 'Custom: ?.?.? Specify version...' + name: 'Custom: ?.?.? Specify version...' } ] }, { - config: 'bump.version', - type: 'input', - message: 'What specific version would you like', - when: function (answers) { + config: 'bump.version', + type: 'input', + message: 'What specific version would you like', + when: function (answers) { return answers['bump.increment'] === 'custom'; }, validate: function (value) { @@ -313,11 +313,11 @@ module.exports = function(grunt) { // name: 'bower.json' + (!grunt.file.isFile('bower.json') ? ' not found, will create one' : ''), // checked: grunt.file.isFile('bower.json') // }, - // { - // value: 'git', - // name: 'git tag', - // checked: grunt.file.isDir('.git') - // } + // { + // value: 'git', + // name: 'git tag', + // checked: grunt.file.isDir('.git') + // } // ] // } ] @@ -327,7 +327,7 @@ module.exports = function(grunt) { replace: { readme: { src: ['DETAILS.md', 'README.md'], - overwrite: true, // overwrite matched source files + overwrite: true,// overwrite matched source files replacements: [{ from: /fuelux\/\d\.\d\.\d/g, to: "fuelux/<%= pkg.version %>" @@ -354,7 +354,7 @@ module.exports = function(grunt) { key: '<%= sauceKey %>', tunnelTimeout: 45, testInterval: 3000, - tags: ['<%= pkg.version %>','<%= sauceUser %>' + '@' + process.env.TRAVIS_BRANCH || '<%= sauceUser %>@local'], + tags: ['<%= pkg.version %>', '<%= sauceUser %>' + '@' + process.env.TRAVIS_BRANCH || '<%= sauceUser %>@local'], browsers: grunt.file.readYAML('sauce_browsers.yml'), build: process.env.TRAVIS_BUILD_NUMBER || '<%= pkg.version %>', testname: process.env.TRAVIS_JOB_ID || '<%= pkg.version %>-<%= grunt.template.today("dddd, mmmm dS, yyyy, h:MM:ss TT") %>', @@ -404,11 +404,11 @@ module.exports = function(grunt) { validation: { // if many errors are found, this may log to console while other tasks are running options: { - reset: function() { + reset: function () { grunt.option('reset') || false ; }, stoponerror: true, - relaxerror: [ //ignores these errors + relaxerror: [//ignores these errors 'Bad value X-UA-Compatible for attribute http-equiv on element meta.', 'Element head is missing a required instance of child element title.' ], @@ -420,26 +420,45 @@ module.exports = function(grunt) { } }, watch: { + //watch everything and test everything (test dist) full: { files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'lib/**', 'test/**', 'index.html', 'dev.html'], options: { livereload: isLivereloadEnabled }, - tasks: ['test', 'dist'] + tasks: ['jshint', 'dist', 'qunit:dist', 'validation'] }, - css: { + //watch everything but only perform simple qunit tests (don't test dist) + simple: { files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'lib/**', 'test/**', 'index.html', 'dev.html'], options: { livereload: isLivereloadEnabled }, + tasks: ['jshint', 'qunit:simple', 'validation'] + }, + //only watch and dist less, useful when doing LESS/CSS work + less: { + files: ['fonts/**', 'less/**'], + options: { + livereload: isLivereloadEnabled + }, tasks: ['distcss'] }, - contrib: { - files: ['Gruntfile.js', 'fonts/**', 'js/**', 'less/**', 'lib/**', 'test/**', 'index.html', 'dev.html'], + //watch things that need compiled, useful for debugging/developing against dist + dist: { + files: ['fonts/**', 'js/**', 'less/**'], + options: { + livereload: isLivereloadEnabled + }, + tasks: ['dist'] + }, + //just keep the server running, best for when you are just in the zone slinging code and don't want to be interrupted with tests + lite: { + files: [], options: { livereload: isLivereloadEnabled }, - tasks: ['test'] + tasks: [] } } }); @@ -461,7 +480,7 @@ module.exports = function(grunt) { grunt.registerTask('distcss', 'Compile LESS into CSS', ['less', 'usebanner', 'delete-temp-less-file']); // Temporary LESS file deletion task - grunt.registerTask('delete-temp-less-file', 'Delete the temporary LESS file created during the build process', function() { + grunt.registerTask('delete-temp-less-file', 'Delete the temporary LESS file created during the build process', function () { var options = { force: true }; @@ -482,7 +501,7 @@ module.exports = function(grunt) { TESTS ------------- */ // The default build task - grunt.registerTask('default', 'Run simple tests.', ['test', 'clean:screenshots']); + grunt.registerTask('default', 'Run simple tests. Pass --no-resetdist to keep dist changes from being wiped out', ['test', 'clean:screenshots', 'resetdist']); // to be run prior to submitting a PR grunt.registerTask('test', 'run jshint, qunit:simple, and validate HTML', ['jshint', 'qunit:simple', 'validation']); @@ -502,20 +521,30 @@ module.exports = function(grunt) { // Travis CI task. This task no longer uses SauceLabs. Please run 'grunt saucelabs' manually. grunt.registerTask('travisci', 'Tests to run when in Travis CI environment', ['connect:testServer', 'jshint', 'qunit:simple', 'dist', 'qunit:full']); + //if you've already accidentally added your files for commit, this will at least unstage them. If you haven't, this will wipe them out. + grunt.registerTask('resetdist', 'resets changes to dist to keep them from being checked in', function () { + //default resetdist to true... basically. + if (typeof grunt.option('resetdist') === "undefined" || grunt.option('resetdist')) { + var exec = require('child_process').exec; + exec('git reset HEAD dist/*'); + exec('git checkout -- dist/*'); + } + }); /* ------------- RELEASE ------------- */ // Maintainers: Run prior to a release. Includes SauceLabs VM tests. grunt.registerTask('release', 'Release a new version, push it and publish it', ['prompt:bump', 'dorelease']); - grunt.registerTask('dorelease', '', function() { - if(typeof grunt.config('bump.increment') === 'undefined'){ + grunt.registerTask('dorelease', '', function () { + if (typeof grunt.config('bump.increment') === 'undefined') { grunt.fail.fatal('you must choose a version to bump to'); } + grunt.log.writeln(''); grunt.log.oklns('releasing: ', grunt.config('bump.increment')); - if (! grunt.option('no-tests') ) { + if (!grunt.option('no-tests')) { grunt.task.run(['releasetest']); //delete any screenshots that may have happened if it got this far. This isn't foolproof because it relies on the phantomjs server/page timeout, which can take longer than this grunt task depending on how long saucelabs takes to run... grunt.task.run('clean:screenshots'); @@ -528,20 +557,59 @@ module.exports = function(grunt) { /* ------------- - SERVEFAST + SERVE ------------- */ - grunt.registerTask('servefast', 'Serve the files with no "dist" build or tests. Optional --no-less to also disable compiling less into css.', function() { - if (! grunt.option('no-less') ) { - grunt.task.run(['distcss']); + //most basic serve task, it's the safest, but also the slowest. + grunt.registerTask('serve', 'Serve the files. --no-test to skip tests', function () { + //default --test=true + if (typeof grunt.option('test') === "undefined") { + grunt.option('test', true); } - grunt.task.run(['connect:server', 'watch:css']); + + grunt.task.run(['servedist']); }); - /* ------------- - SERVE - ------------- */ - // use '--no-livereload' to disable livereload - grunt.registerTask('serve', 'serve files without "dist" build', ['test', 'connect:server', 'watch:contrib']); - grunt.registerTask('servedist', 'test, build "dist", serve files w/ watch', ['test', 'dist', 'connect:server', 'watch:full']); + //Fastest serve command for freely slinging code (you won't get interrupted by tests, etc). + grunt.registerTask('servefast', 'Serve the files. pass --test to run tests.', function () { + grunt.task.run(['connect:server']); + + if (grunt.option('test')) { + grunt.task.run(['qunit:simple', 'watch:simple']); + } else { + grunt.task.run(['watch:lite']); + } + }); + + //Fastest serve command when you're working on LESS + grunt.registerTask('serveless', 'Compile LESS and serve the files. pass --tests to run test.', function () { + grunt.task.run(['distcss']); + + if (grunt.option('test')) { + //add qunit:simple as a watch task for watch:less since they want tests + grunt.config.merge({ + watch: { + less: { + tasks: ['qunit:simple'] + } + } + }); + grunt.task.run(['qunit:simple']); + } + + grunt.task.run(['connect:server', 'watch:less']); + }); + //basically just `grunt serve` but tests default to being off + grunt.registerTask('servedist', 'Compile and serve everything, pass --test to run tests.', function () { + grunt.task.run(['dist']); + + //start up the server here so we can run tests if appropriate + grunt.task.run(['connect:server']); + + if (grunt.option('test')) { + grunt.task.run(['qunit:dist', 'watch:full']); + } else { + grunt.task.run(['watch:dist']); + } + }); };