diff --git a/README.md b/README.md index 0001a8a..726691d 100755 --- a/README.md +++ b/README.md @@ -109,6 +109,27 @@ provide the name of the project you would like to deploy to. $ modulus deploy -p "Lizard Locator" my/project/directory +You can specify the node and npm version that your Node.js/Meteor application will use. +For Node.js projects, you can specify this within the engines block in the `package.json`. + +```json +{ + "engines": { + "node": "4.4.7", + "npm": "3.10.5" + } +} +``` + +To specify the node and npm versions on Meteor projects you can deploy with the +--node-version and --npm-version flags + + $ modulus deploy -p "Lizard Locator" --node-version 4.4.3 --npm-version 3.10.5 + +Meteor projects can set the --debug flag on deploys. + + $ modulus deploy -p "Lizard Locator" --debug + To start, stop, or restart a project, use: $ modulus project start diff --git a/lib/commands/project.js b/lib/commands/project.js index 0d23e37..ce93cb6 100755 --- a/lib/commands/project.js +++ b/lib/commands/project.js @@ -566,10 +566,15 @@ project.create = function (projectName, servoSize, runtime, projectOwner, cb) { * @param {boolean} includeModules Whether or not to include node_modules directory in upload. * @param {string} registry npm registry url. * @param {boolean} withTests Value indicating whether to run tests for the project on deploy. + * @param {string} nodeVersion Version of node to use when running application + * @param {string} npmVersion Version of npm to use when building application + * @param {boolean} debug Value indicating whether to pass debug flag to demeteorizer * @param {function} cb The callback. */ //----------------------------------------------------------------------------- -project.deploy = function (projectName, dir, includeModules, registry, withTests, cb) { +project.deploy = function (projectName, dir, includeModules, registry, withTests, nodeVersion, npmVersion, debug, cb) { + var options; + if (typeof dir !== 'string') { dir = process.cwd(); } @@ -668,10 +673,17 @@ project.deploy = function (projectName, dir, includeModules, registry, withTests }); }, function deployProject (selectedProject, fn) { - if (!selectedProject) { - return fn('You must deploy to a project.'); - } - projectController.deploy(selectedProject.id, dir, includeModules, registry, withTests, function (err, domain) { + if (!selectedProject) return fn('You must deploy to a project.'); + + options = { + registry: registry, + withTests: !!withTests, + nodeVersion: nodeVersion, + npmVersion: npmVersion, + debug: !!debug + }; + + projectController.deploy(selectedProject.id, dir, includeModules, options, function (err, domain) { if (!err) { modulus.io.success(selectedProject.name + ' running at ' + domain); fn(); diff --git a/lib/controllers/project.js b/lib/controllers/project.js index 771066c..630c450 100755 --- a/lib/controllers/project.js +++ b/lib/controllers/project.js @@ -216,7 +216,7 @@ Project.prototype.saveVars = function(projectId, vars, callback) { }; //----------------------------------------------------------------------------- -Project.prototype.deploy = function(projectId, dir, includeModules, registry, withTests, callback) { +Project.prototype.deploy = function (projectId, dir, includeModules, options, callback) { var projectController = this, errMessage, projectType; async.waterfall([ @@ -272,7 +272,7 @@ Project.prototype.deploy = function(projectId, dir, includeModules, registry, wi }); }, function(path, zipFile, cb) { - projectController._deploy(projectId, zipFile, registry, withTests, function(err, domain) { + projectController._deploy(projectId, zipFile, options, function (err, domain) { fs.unlinkSync(zipFile); if (err) { @@ -292,7 +292,7 @@ Project.prototype.deploy = function(projectId, dir, includeModules, registry, wi }; //----------------------------------------------------------------------------- -Project.prototype._deploy = function(projectId, file, registry, withTests, callback) { +Project.prototype._deploy = function (projectId, file, options, callback) { modulus.io.print('Uploading project...'); var status = Project.status.uploading; @@ -306,12 +306,7 @@ Project.prototype._deploy = function(projectId, file, registry, withTests, callb }); if (process.stdout.isTTY) { ubar.tick(); } - var client = new Uploader(), - options = { - registry: registry, - withTests: !!withTests - }; - + var client = new Uploader(); client.upload(projectId, file, options); client.on('progress', function(progress) { diff --git a/lib/controllers/uploader.js b/lib/controllers/uploader.js index ee0e8af..2d2571f 100644 --- a/lib/controllers/uploader.js +++ b/lib/controllers/uploader.js @@ -48,81 +48,69 @@ util.inherits(Uploader, EventEmitter); * Uploads a file. */ //----------------------------------------------------------------------------- -Uploader.prototype.upload = function(projectId, file, options) { - +Uploader.prototype.upload = function (projectId, file, options) { + var endpoint, reqOptions; var self = this; + var apiKey = userConfig.data.apiKey; self.uploading = true; - var endpoint = util.format( - '%s://%s:%s/project/deploy/%s?authToken=%s&forceNpmInstall=%s®istry=%s&withTests=%s', + endpoint = util.format( + '%s://%s:%s/project/deploy/%s', librarian._http._ssl ? 'https' : 'http', librarian._http._host, librarian._http._port, - projectId, - userConfig.data.apiKey, - options.forceNpmInstall, - options.registry, - options.withTests + projectId ); fs.stat(file, function(err, stat) { + if (err) return self.emit('error', err); - if(err) { - return self.emit('error', err); - } + reqOptions = { + method: 'PUT', + uri: endpoint, + timeout: 60 * 60 * 1000, // 1 hour + qs: Object.assign({ authToken: apiKey }, options), + headers: { 'content-length': stat.size } + }; // Read the file and pipe the contents directly. fs.createReadStream(file).pipe( - request.put( - { - method: 'PUT', - uri : endpoint, - timeout: 60 * 60 * 1000, // 1 hour - headers : { - 'content-length' : stat.size - } - }, - function(err, res, b) { - - self.uploading = false; - - if(err) { - return self.emit('error', err); - } - - //convert the response to an object - if(typeof b === 'string') { - try { - var tmp = JSON.parse(b); - b = tmp; - } catch(e) { - //console out the response body for debugging - console.log('Unknown body type.'); - console.log(b); - } + request(reqOptions, function(err, res, body) { + self.uploading = false; + + if (err) return self.emit('error', err); + + //convert the response to an object + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch(e) { + //console out the response body for debugging + console.log('Unknown body type.'); + console.log(body); } + } - //check for errors - if(typeof b === 'object') { - if(b.error) { - console.log(b.error); - return (self.emit('error', 'There was an error uploading.')); - } else if(b.errors) { - return self.emit('error', b.errors[0].message); - } + //check for errors + if (typeof body === 'object') { + if (body.error) { + console.log(body.error); + return (self.emit('error', 'There was an error uploading.')); + } else if (body.errors) { + return self.emit('error', body.errors[0].message); } + } - // Send a final progress emit so the user always sees 100%. - self.emit('progress', 1); + // Send a final progress emit so the user always sees 100%. + self.emit('progress', 1); - // Do next tick so the UI can actually update to 100% before - // continuing. - process.nextTick(function() { - self.emit('end'); - }); - } - ) + // Do next tick so the UI can actually update to 100% before + // continuing. + process.nextTick(function() { + self.emit('end'); + }); + }) ); }); diff --git a/lib/routes/project.js b/lib/routes/project.js index 3450b76..3e08829 100755 --- a/lib/routes/project.js +++ b/lib/routes/project.js @@ -164,6 +164,9 @@ module.exports = function (modulus) { this.line(' -m, --include-modules Flag that indicates whether or not to include the node_modules folder in the bundle.'.input); this.line(' -r, --registry Specify a registry to install modules from.'.input); this.line(' -w, --with-tests Specifies that tests should be run before deploying this project.'.input); + this.line(' --node-version Specified version of node to use when running application.'.input); + this.line(' --npm-version Specified version of npm to use when building application.'.input); + this.line(' -d, --debug Specifies to pass the debug flag to demeteorizer.'.input); }); modulus.program @@ -173,6 +176,9 @@ module.exports = function (modulus) { .option('-m, --include-modules', 'Flag that indicates whether or not to include the node_modules folder in the bundle.') .option('-r, --registry [value]', 'Specify a registry to install modules from', '') .option('-w, --with-tests', 'Specifies that tests should be run before deploying this project.') + .option('--node-version [value]', 'Specified version of node to use when running application..') + .option('--npm-version [value]', 'Specified version of npm to use when building application.') + .option('-d, --debug', 'Specifies to pass the debug flag to demeteorizer.') .option('-n, --node-env [value]', 'Specifies node version when running application using `modulus run`.'); modulus.program @@ -187,7 +193,10 @@ module.exports = function (modulus) { dir, modulus.program.includeModules, modulus.program.registry, - modulus.program.withTests + modulus.program.withTests, + modulus.program.nodeVersion, + modulus.program.npmVersion, + modulus.program.debug ], true); }); @@ -204,7 +213,10 @@ module.exports = function (modulus) { dir, modulus.program.includeModules, modulus.program.registry, - modulus.program.withTests + modulus.program.withTests, + modulus.program.nodeVersion, + modulus.program.npmVersion, + modulus.program.debug ], true); });