Skip to content

Commit

Permalink
Merge cee70f3 into 4335f31
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp committed Feb 19, 2018
2 parents 4335f31 + cee70f3 commit 03d2471
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 0 deletions.
118 changes: 118 additions & 0 deletions lib/cli/cmd-upgrade.js
@@ -0,0 +1,118 @@
var utils = require("../utils");
var spawn = require('cross-spawn-async');
var donejsVersion = require('../../package.json').version;
var path = require("path");

// Maps donejs versions to canjs versions
var canjsVersionMap = {
"2": "4"
};

module.exports = function(version, options) {
var requestedVersion = version || utils.versionRange(donejsVersion);

var packageJsonPromise = rootPackageJson();
var donejscliPackageJsonPromise = getDonejsCliPackageForRange(requestedVersion);

return Promise.all([ donejscliPackageJsonPromise, packageJsonPromise ])
.then(function(results){
var cliPkg = results[0];
var handle = results[1];

var donejs = cliPkg.donejs;
var projectRoot = handle.root;

var pkg = handle.get();

Object.assign(pkg.dependencies, donejs.dependencies);
Object.assign(pkg.devDependencies, donejs.devDependencies);

handle.write(pkg);

// Run npm install to get the newest versions
return utils.spawn("npm", ["install"]).then(function(){
return projectRoot;
});
})
.then(function(projectRoot){
if(options.canmigrate) {
return installCanMigrate()
.then(function(){
return runCanMigrate(projectRoot, requestedVersion);
});
}
});
};

function rootPackageJson() {
return utils.projectRoot().then(function(root){
var packagePath = path.join(root, "package.json");
return {
root: root,
get: function(){
return require(packagePath);
},
write: function(newPackage){
var json = JSON.stringify(newPackage, null, " ");
require("fs").writeFileSync(packagePath, json, "utf8");
}
};
});
}

function getDonejsCliPackageForRange(versionRange) {
return new Promise(function(resolve, reject){
var child = spawn("npm", ["info", "--json", "donejs-cli@" + versionRange]);
var json = "";
child.stdout.on("data", function(data){
json += data.toString();
});
child.on("exit", function(status){
if(status === 1) {
reject();
} else {
try {
var data = JSON.parse(json);
resolve(data[data.length - 1] || data);
} catch(err) {
reject(err);
}
}
});
});
}

function installCanMigrate() {
return utils.spawn("npm", ["install", "--no-save", "can-migrate"]);
}

function runCanMigrate(projectRoot, requestedDonejsVersion) {
var donejsMajor = getMajorVersion(requestedDonejsVersion) ||
getMajorVersion(donejsVersion);
var canjsVersion = canjsVersionMap[donejsMajor];
if(canjsVersion) {
var canMigratePath = path.join(projectRoot, 'node_modules', '.bin', "can-migrate");
var args = [canMigratePath, "**/*.*", "--apply", "--can-version",
canjsVersion.toString(), "--force"];
return utils.spawn("node", args);
}
return Promise.resolve();
}

function getMajorVersion(versionRange) {
var index = 0, len = versionRange.length;
var numExp = /[1-9]/;
var vers = "";
while(index < len) {
var char = versionRange[index];
if(numExp.test(char)) {
vers += char;
}
// Break the first time we get a non-number after having gotten at least one
else if(vers.length) {
break;
}
index++;
}
return vers;
}
8 changes: 8 additions & 0 deletions lib/cli/index.js
Expand Up @@ -6,6 +6,7 @@ var runBinary = require('./run-binary');
// commands
var add = require('./cmd-add');
var help = require('./cmd-help');
var upgrade = require('./cmd-upgrade');

program.version(require('../../package.json').version);

Expand All @@ -17,6 +18,13 @@ program.command('add <type> [params...]')
log(add(type, params, options));
});

program.command('upgrade [version]')
.description('Upgrade the current project to the latest DoneJS version')
.option('--no-canmigrate', 'Skip running can-migrate')
.action(function(version, options) {
log(upgrade(version, options));
});

program.command('help')
.description('Show all DoneJS commands available for this application')
.action(function() {
Expand Down
137 changes: 137 additions & 0 deletions test/cmd-upgrade-test.js
@@ -0,0 +1,137 @@
var Q = require('q');
var fs = require('fs');
var path = require('path');
var rimraf = require('rimraf');
var assert = require('assert');
var mockery = require('mockery');
var utils = require('../lib/utils');

describe('cli upgrade cmd', function() {
var cwd;
var upgrade;
var spawnCalls;
var writeCalls;
var folder = 'test-project';
var cmdUpgradePath = '../lib/cli/cmd-upgrade';
var pkgJsonPath = path.join(__dirname, "..", folder, "package.json");

beforeEach(function() {
spawnCalls = [];
writeCalls = [];
cwd = process.cwd();

deleteFolder();

mockery.enable({
useCleanCache: true,
warnOnUnregistered: false
});

mockery.registerAllowable(cmdUpgradePath);

mockery.registerMock('../utils', {
mkdirp: utils.mkdirp,
versionRange: function() { return 'latest'; },
projectRoot: function(){
return Promise.resolve(__dirname + '/../' + folder);
},
spawn: function() {
spawnCalls.push({
binary: arguments[0],
args: arguments[1],
options: arguments[2]
});
return Q(true);
}
});

mockery.registerMock(pkgJsonPath, {
dependencies: {
foo: "1.0.0"
},
devDependencies: {
bar: "1.0.0"
}
});

mockery.registerMock('fs', {
writeFileSync: function(path, data, enc){
writeCalls.push({ path, data, enc });
}
});

mockery.registerMock('cross-spawn-async', function(){
spawnCalls.push({
binary: arguments[0],
args: arguments[1],
options: arguments[2]
});
var makeOn = function() {
var fn = function(ev, cb) {
fn.cb = cb;
};
return fn;
};
var onData = makeOn();
var onExit = makeOn();
var mock = {stdout: { on: onData }, on: onExit};

setTimeout(function(){
var pkg = {donejs: {dependencies: {foo: "2.0.0"}, devDependencies: {bar: "2.0.0"}}};
onData.cb(JSON.stringify(pkg));
setTimeout(function() { onExit.cb(0); }, 20);
}, 20);

return mock;
});

upgrade = require(cmdUpgradePath);
});

afterEach(function() {
//deleteFolder();
mockery.disable();
mockery.deregisterAll();
});

it('updates the package.json', function(done){
upgrade(null, {canmigrate: false})
.then(function(){
assert.equal(writeCalls.length, 1);
assert.equal(writeCalls[0].path, pkgJsonPath);

var json = JSON.parse(writeCalls[0].data);
assert.equal(json.dependencies.foo, "2.0.0", "dependency is upgraded");
assert.equal(json.devDependencies.bar, "2.0.0", "devDependency is upgraded");

done();
})
.catch(done);
});

it('runs can-migrate', function(done){
upgrade(null, {canmigrate: true})
.then(function(){
var lastCall = spawnCalls[spawnCalls.length - 1];
assert.ok(/can-migrate/.test(lastCall.args[0]), "ran can-migrate");
done();
})
.catch(done);
});

it('Does not run can-migrate when --no-canmigrate flag is passed', function(done){
upgrade(null, {canmigrate: false})
.then(function(){
var lastCall = spawnCalls[spawnCalls.length - 1];
assert.ok(!/can-migrate/.test(lastCall.args[0]), "did not run can-migrate");
done();
})
.catch(done);
});

function deleteFolder() {
if (fs.existsSync(folder)) {
rimraf.sync(folder);
}
}
});

0 comments on commit 03d2471

Please sign in to comment.