From 782c92885d137c696439673ababd8eb16151b585 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Tue, 24 Mar 2015 08:44:02 -0400 Subject: [PATCH] Use child_process to trigger self update Using the NPM API led to weird issues. See https://github.com/npm/npm/issues/7723. --- build/actions/update.js | 21 +++++++++++++++++---- build/npm.js | 25 ------------------------- lib/actions/update.coffee | 19 ++++++++++++++++--- lib/npm.coffee | 28 ---------------------------- 4 files changed, 33 insertions(+), 60 deletions(-) diff --git a/build/actions/update.js b/build/actions/update.js index 66b3b004..8ff4fd51 100644 --- a/build/actions/update.js +++ b/build/actions/update.js @@ -1,5 +1,7 @@ (function() { - var npm, packageJSON; + var child_process, npm, packageJSON; + + child_process = require('child_process'); npm = require('../npm'); @@ -10,12 +12,23 @@ description: 'update the resin cli', help: 'Use this command to update the Resin CLI\n\nThis command outputs information about the update process.\nUse `--quiet` to remove that output.\n\nThe Resin CLI checks for updates once per day.\n\nMajor updates require a manual update with this update command,\nwhile minor updates are applied automatically.\n\nExamples:\n\n $ resin update', action: function(params, options, done) { - return npm.update(packageJSON.name, function(error, version) { + return npm.isUpdated(packageJSON.name, packageJSON.version, function(error, isUpdated) { if (error != null) { return done(error); } - console.info("Upgraded " + packageJSON.name + " to v" + version + "."); - return done(null, version); + if (isUpdated) { + return done(new Error('You\'re already running the latest version.')); + } + return child_process.exec("npm install -g " + packageJSON.name, function(error, stdout, stderr) { + if (error != null) { + return done(error); + } + if (!_.isEmpty(stderr)) { + return done(new Error(stderr)); + } + console.info("Upgraded " + packageJSON.name + "."); + return done(); + }); }); } }; diff --git a/build/npm.js b/build/npm.js index a23f5361..94b0ad9d 100644 --- a/build/npm.js +++ b/build/npm.js @@ -7,31 +7,6 @@ _ = require('lodash-contrib'); - exports.update = function(name, callback) { - return async.waterfall([ - function(callback) { - var options; - options = { - loglevel: 'silent', - global: true - }; - return npm.load(options, _.unary(callback)); - }, function(callback) { - return npm.commands.update([name], function(error, data) { - return callback(error, data); - }); - }, function(data, callback) { - var error, newVersion; - if (_.isEmpty(data)) { - error = new Error('You are already running the latest version'); - return callback(error); - } - newVersion = _.last(_.first(_.last(data)).split('@')); - return callback(null, newVersion); - } - ], callback); - }; - exports.getLatestVersion = function(name, callback) { return async.waterfall([ function(callback) { diff --git a/lib/actions/update.coffee b/lib/actions/update.coffee index 05f187db..d4469440 100644 --- a/lib/actions/update.coffee +++ b/lib/actions/update.coffee @@ -1,3 +1,4 @@ +child_process = require('child_process') npm = require('../npm') packageJSON = require('../../package.json') @@ -20,7 +21,19 @@ exports.update = $ resin update ''' action: (params, options, done) -> - npm.update packageJSON.name, (error, version) -> + npm.isUpdated packageJSON.name, packageJSON.version, (error, isUpdated) -> return done(error) if error? - console.info("Upgraded #{packageJSON.name} to v#{version}.") - return done(null, version) + + if isUpdated + return done(new Error('You\'re already running the latest version.')) + + # Attempting to self update using the NPM API was not considered safe. + # A safer thing to do is to call npm as a child process + # https://github.com/npm/npm/issues/7723 + child_process.exec "npm install -g #{packageJSON.name}", (error, stdout, stderr) -> + return done(error) if error? + return done(new Error(stderr)) if not _.isEmpty(stderr) + + console.info("Upgraded #{packageJSON.name}.") + + return done() diff --git a/lib/npm.coffee b/lib/npm.coffee index 4e7466c7..3a7d429b 100644 --- a/lib/npm.coffee +++ b/lib/npm.coffee @@ -2,34 +2,6 @@ npm = require('npm') async = require('async') _ = require('lodash-contrib') -exports.update = (name, callback) -> - async.waterfall([ - - (callback) -> - options = - - # TODO: There is no way to quiet npm install completely. - # Some output is still shown once the module is updated - # https://github.com/npm/npm/issues/2040 - loglevel: 'silent' - global: true - - npm.load(options, _.unary(callback)) - - (callback) -> - npm.commands.update [ name ], (error, data) -> - return callback(error, data) - - (data, callback) -> - if _.isEmpty(data) - error = new Error('You are already running the latest version') - return callback(error) - - newVersion = _.last(_.first(_.last(data)).split('@')) - return callback(null, newVersion) - - ], callback) - exports.getLatestVersion = (name, callback) -> async.waterfall([