var semver = require('semver'), fs = require('fs'), currentVersion = JSON.parse(fs.readFileSync('./package.json', 'utf8')).version, env = require('./config/environment'); // Globals var PROMPT_CONFIRM_CONFIG = 'confirmation', GIT_BRANCH = env.get('FILER_UPSTREAM_BRANCH'), GIT_REMOTE = env.get('FILER_UPSTREAM_REMOTE_NAME'), GIT_FULL_REMOTE = env.get('FILER_UPSTREAM_URI') + ' ' + GIT_BRANCH; module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), clean: ['dist/filer-test.js', 'dist/filer-issue225.js', 'dist/filer-perf.js'], uglify: { options: { banner: '/*! <%= pkg.name %> <%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n' }, develop: { src: 'dist/filer.js', dest: 'dist/filer.min.js' }, path: { src: 'dist/path.js', dest: 'dist/path.min.js' }, buffer: { src: 'dist/buffer.js', dest: 'dist/buffer.min.js' } }, jshint: { // Don't bother with src/path.js all: [ 'gruntfile.js', 'config/environment.js', 'src/constants.js', 'src/errors.js', 'src/fs.js', 'src/index.js', 'src/shared.js', 'src/shell.js', 'src/fswatcher.js', 'src/environment.js', 'src/providers/**/*.js', 'src/adapters/**/*.js', 'src/directory-entry.js', 'src/open-file-description.js', 'src/super-node.js', 'src/node.js', 'src/stats.js', 'src/filesystem/**/*.js' ] }, browserify: { filerDist: { src: "./src/index.js", dest: "./dist/filer.js", options: { browserifyOptions: { commondir: false, builtins: ["buffer", "path", "url", "punycode", "querystring"], insertGlobalVars: { // This ensures that process won't be defined, since // browserify will do so automatically if any globals // are requested by us or detected by browserify. process: function() { return undefined; } }, standalone: 'Filer' }, exclude: ["./node_modules/request/index.js"] } }, filerPerf: { src: "./perf/index.js", dest: "./dist/filer-perf.js", options: { browserifyOptions: { commondir: false, builtins: ["buffer", "path", "url", "punycode", "querystring"], insertGlobalVars: { // This ensures that process won't be defined, since // browserify will do so automatically if any globals // are requested by us or detected by browserify. process: function() { return undefined; } }, standalone: 'Filer' } } }, filerTest: { src: "./tests/index.js", dest: "./dist/filer-test.js", options: { browserifyOptions: { commondir: false, builtins: ["buffer", "path", "url", "punycode", "querystring"], insertGlobalVars: { // This ensures that process won't be defined, since // browserify will do so automatically if any globals // are requested by us or detected by browserify. process: function() { return undefined; } } } } }, // See tests/bugs/issue225.js filerIssue225: { src: "./src/index.js", dest: "./dist/filer-issue225.js", options: { browserifyOptions: { commondir: false, builtins: ["buffer", "path", "url", "punycode", "querystring"], insertGlobalVars: { // This ensures that process won't be defined, since // browserify will do so automatically if any globals // are requested by us or detected by browserify. process: function() { return undefined; } }, standalone: 'Filer' } } }, // For low-cost access to filer's `Path` and `buffer` modules filerPath: { src: "./src/path.js", dest: "./dist/path.js", options: { browserifyOptions: { standalone: 'Path' } } }, filerBuffer: { src: "./src/buffer.js", dest: "./dist/buffer.js", options: { browserifyOptions: { standalone: 'FilerBuffer' } } } }, shell: { mocha: { // Run all tests (e.g., tests require()'ed in tests/index.js) and also tests/bugs/issue225.js // separately, since it can't be included in a browserify build. command: '"./node_modules/.bin/mocha" --reporter list tests/index.js && "./node_modules/.bin/mocha" --reporter list tests/bugs/issue225.js' } }, bump: { options: { files: ['package.json', 'bower.json'], commit: true, commitMessage: 'v%VERSION%', commitFiles: [ 'package.json', 'bower.json', './dist/filer.js', './dist/filer.min.js', './dist/buffer.js', './dist/buffer.min.js', './dist/path.js', './dist/path.min.js' ], createTag: true, tagName: 'v%VERSION%', tagMessage: 'v%VERSION%', push: true, pushTo: GIT_FULL_REMOTE } }, 'npm-checkBranch': { options: { branch: GIT_BRANCH } }, 'npm-publish': { options: { abortIfDirty: false } }, prompt: { confirm: { options: { questions: [ { config: PROMPT_CONFIRM_CONFIG, type: 'confirm', message: 'Bump version from ' + (currentVersion).cyan + ' to ' + semver.inc(currentVersion, "patch").yellow + '?', default: false } ], then: function(results) { if (!results[PROMPT_CONFIRM_CONFIG]) { return grunt.fatal('User aborted...'); } } } } }, gitcheckout: { publish: { options: { branch: 'gh-pages', force: true } }, revert: { options: { branch: GIT_BRANCH } } }, gitpush: { publish: { options: { remote: GIT_REMOTE, branch: 'gh-pages', force: true }, } }, gitcommit: { publish: { options: { noStatus: true } } }, gitadd: { publish: { files: { src: ['./dist/filer-test.js', './dist/filer-perf.js'] } } }, gitstash: { publish: { }, pop: { options: { command: "pop" } } }, gitrm: { publish: { options: { force: true }, files: { src: ['./dist/filer-test.js', './dist/filer-perf.js'] } } }, connect: { serverForBrowser: { options: { port: 1234, base: './', keepalive: true } } }, usebanner: { publish: { options: { position: "top" }, files: { src: ['./dist/filer-test.js', './dist/filer-perf.js'] } } } }); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-bump'); grunt.loadNpmTasks('grunt-npm'); grunt.loadNpmTasks('grunt-git'); grunt.loadNpmTasks('grunt-prompt'); grunt.loadNpmTasks('grunt-shell'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-banner'); grunt.registerTask('develop', [ 'browserify:filerDist', 'browserify:filerPath', 'browserify:filerBuffer', 'uglify:develop', 'uglify:path', 'uglify:buffer' ]); grunt.registerTask('build-tests', ['clean', 'browserify:filerTest', 'browserify:filerPerf', 'browserify:filerIssue225']); grunt.registerTask('release', ['test', 'develop']); grunt.registerTask('publish', 'Publish filer as a new version to NPM, bower and github.', function(patchLevel) { var allLevels = ['patch', 'minor', 'major']; // No level specified defaults to 'patch' patchLevel = (patchLevel || 'patch').toLowerCase(); // Fail out if the patch level isn't recognized if (allLevels.filter(function(el) { return el == patchLevel; }).length === 0) { return grunt.fatal('Patch level not recognized! "Patch", "minor" or "major" only.'); } // Set prompt message var promptOpts = grunt.config('prompt.confirm.options'); promptOpts.questions[0].message = 'Bump version from ' + (currentVersion).cyan + ' to ' + semver.inc(currentVersion, patchLevel).yellow + '?'; grunt.config('prompt.confirm.options', promptOpts); // Store the new version in the gh-pages commit message var ghPagesMessage = 'Tests for Filer v' + semver.inc(currentVersion, patchLevel); grunt.config('gitcommit.publish.options.message', ghPagesMessage); // Store the new version as a banner in the test file // NOTE: This is a hack intended to ensure that this build process // succeeds even if no changes were made to the tests // before publishing a new version. Otherwise, the automatic // commit + push to github pages would break a normal build var bannerMsg = "/* Test file for filerjs v" + semver.inc(currentVersion, patchLevel) + "*/"; grunt.config('usebanner.publish.options.banner', bannerMsg); grunt.task.run([ 'prompt:confirm', 'checkBranch', 'release', 'bump:' + patchLevel, 'build-tests', 'usebanner:publish', 'gitadd:publish', 'gitstash:publish', 'gitcheckout:publish', 'gitrm:publish', 'gitstash:pop', 'gitcommit:publish', 'gitpush:publish', 'gitcheckout:revert', 'npm-publish' ]); }); grunt.registerTask('test-node', ['jshint', 'browserify:filerIssue225', 'shell:mocha']); grunt.registerTask('test-browser', ['jshint', 'build-tests', 'connect:serverForBrowser']); grunt.registerTask('test', ['test-node']); grunt.registerTask('default', ['test']); };