diff --git a/Gruntfile.js b/Gruntfile.js index 8e0950d94e1a8..e3b4940e12153 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,6 +5,7 @@ var jsxTask = require('./grunt/tasks/jsx'); var browserifyTask = require('./grunt/tasks/browserify'); var wrapupTask = require('./grunt/tasks/wrapup'); var phantomTask = require('./grunt/tasks/phantom'); +var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); module.exports = function(grunt) { @@ -16,6 +17,7 @@ module.exports = function(grunt) { browserify: require('./grunt/config/browserify'), wrapup: require('./grunt/config/wrapup'), phantom: require('./grunt/config/phantom'), + npm: require('./grunt/config/npm'), clean: ['./build', './*.gem', './docs/_site', './examples/shared/*.js'], jshint: require('./grunt/config/jshint'), compare_size: require('./grunt/config/compare_size') @@ -44,6 +46,8 @@ module.exports = function(grunt) { grunt.registerMultiTask('phantom', phantomTask); + grunt.registerMultiTask('npm', npmTask); + grunt.registerTask('build:basic', ['jsx:debug', 'browserify:basic']); grunt.registerTask('build:transformer', ['jsx:debug', 'browserify:transformer']); grunt.registerTask('build:min', ['jsx:release', 'browserify:min']); @@ -54,6 +58,7 @@ module.exports = function(grunt) { ]); grunt.registerTask('test', ['build:test', 'phantom:run']); + grunt.registerTask('npm:test', ['build', 'npm:pack']); // Optimized build task that does all of our builds. The subtasks will be run // in order so we can take advantage of that and only run jsx:debug once. diff --git a/grunt/config/npm.js b/grunt/config/npm.js new file mode 100644 index 0000000000000..5586aee786745 --- /dev/null +++ b/grunt/config/npm.js @@ -0,0 +1 @@ +exports.pack = {}; diff --git a/grunt/tasks/npm.js b/grunt/tasks/npm.js new file mode 100644 index 0000000000000..becc96a8942de --- /dev/null +++ b/grunt/tasks/npm.js @@ -0,0 +1,102 @@ +'use strict'; + +var assert = require("assert"); +var path = require("path"); +var fs = require("fs"); +var tmp = require("tmp"); +var grunt = require("grunt"); +var spawn = grunt.util.spawn; + +module.exports = function() { + var config = this.data; + var done = this.async(); + + function run(cmd, args, opts, callback) { + assert.strictEqual(typeof cmd, "string"); + assert.ok(args instanceof Array); + + if (typeof opts === "function" && !callback) { + callback = opts; + opts = {}; + } + + assert.strictEqual(typeof opts, "object"); + assert.strictEqual(typeof callback, "function"); + + grunt.log.writeln("> " + cmd + " " + args.join(" ")); + + var proc = spawn({ + cmd: cmd, + args: args, + opts: opts + }, function(error, result, code) { + if (error) { + grunt.log.error(error); + done(false); + } else { + callback(result, code); + } + }); + + // Uncomment these to see the output of the commands. + // proc.stdout.pipe(process.stdout); + // proc.stderr.pipe(process.stderr); + } + + var pkg = grunt.config.data.pkg; + var tgz = pkg.name + "-" + pkg.version + ".tgz"; + + grunt.log.writeln("Packing " + tgz + " (this could take a while)..."); + + run("npm", ["pack", "--verbose", "."], function() { + tmp.dir(function(err, dir) { + if (err) { + grunt.log.error(err); + done(false); + return; + } + + run("cp", [tgz, dir], function() { + run("npm", [ + "install", + "--production", + tgz + ], { cwd: dir }, function() { + var nodePath = path.join(dir, "node_modules"); + var pkgDir = path.join(nodePath, pkg.name); + var doneCount = 2; + + // Make sure that bin/jsx is runnable by echoing main.js. + run("bin/jsx", ["main.js"], { + cwd: pkgDir + }, function(result) { + assert.ok(result.stdout.indexOf("transform") >= 0, result.stdout); + + if (--doneCount === 0) { + done(); + } + }); + + // Make sure the .transform package method works. + run("node", [ + "--print", + 'require("react-tools").transform(' + + JSON.stringify( + "/** @jsx React.DOM */