Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
}); |