From a7b2fe14b928ada5ced3d89311694ac810f35b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 10:29:50 +0100 Subject: [PATCH] Fix some minor issues with * endpoints and prevent some semver errors due to module upgrade. --- lib/core/Manager.js | 38 ++++++++++++++++++++++++++++++++------ lib/core/Project.js | 38 ++++++++++++++++++++++---------------- lib/core/ResolveCache.js | 3 ++- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 201ab6f2..0b6e6f71 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -22,10 +22,15 @@ function Manager(config, logger) { // ----------------- Manager.prototype.configure = function (setup) { + var targetsHash = {}; + + this._conflicted = {}; + // Targets - this._targets = this._uniquify(setup.targets || []); + this._targets = setup.targets || []; this._targets.forEach(function (decEndpoint) { decEndpoint.dependants = mout.object.values(decEndpoint.dependants); + targetsHash[decEndpoint.name] = true; }); // Resolved & installed @@ -41,7 +46,6 @@ Manager.prototype.configure = function (setup) { mout.object.mixIn(this._installed, setup.installed); // Incompatibles - this._conflicted = {}; this._incompatibles = {}; setup.incompatibles = this._uniquify(setup.incompatibles || []); setup.incompatibles.forEach(function (decEndpoint) { @@ -51,12 +55,22 @@ Manager.prototype.configure = function (setup) { this._incompatibles[name].push(decEndpoint); decEndpoint.dependants = mout.object.values(decEndpoint.dependants); + // Mark as conflicted so that the resolution is not removed this._conflicted[name] = true; + + // If not a target/resolved, add as target + if (!targetsHash[name] && !this._resolved[name]) { + this._targets.push(decEndpoint); + targetsHash[name] = true; + } }, this); // Resolutions this._resolutions = setup.resolutions || {}; + // Uniquify targets + this._targets = this._uniquify(this._targets); + return this; }; @@ -124,11 +138,16 @@ Manager.prototype.install = function () { decEndpoint.canonicalDir = dst; - // Store _target in bower.json + // Store additional metadata in bower.json return Q.nfcall(fs.readFile, jsonFile) .then(function (contents) { var json = JSON.parse(contents.toString()); + json._target = decEndpoint.target; + if (decEndpoint.target === '*' || decEndpoint.originalTarget === '*') { + json._wildcard = true; + } + json = JSON.stringify(json, null, ' '); return Q.nfcall(fs.writeFile, jsonFile, json); @@ -452,6 +471,7 @@ Manager.prototype._dissect = function () { semvers.forEach(function (decEndpoint) { if (decEndpoint.target === '*') { decEndpoint.target = '~' + decEndpoint.pkgMeta.version; + decEndpoint.originalTarget = '*'; } }); @@ -491,8 +511,8 @@ Manager.prototype._dissect = function () { var installedMeta = this._installed[name]; return !installedMeta || - installedMeta._release !== decEndpoint.pkgMeta._release || - installedMeta._target !== decEndpoint.pkgMeta._target; + installedMeta._target !== decEndpoint.target || + installedMeta._release !== decEndpoint.pkgMeta._release; }, this); // Resolve with meaningful data @@ -598,7 +618,8 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { if (resolution && !unresolvable) { if (semver.validRange(resolution)) { suitable = mout.array.findIndex(picks, function (pick) { - return semver.satisfies(pick.pkgMeta.version, resolution); + return pick.pkgMeta.version && + semver.satisfies(pick.pkgMeta.version, resolution); }); } else { suitable = mout.array.findIndex(picks, function (pick) { @@ -716,6 +737,11 @@ Manager.prototype._uniquify = function (decEndpoints) { for (x = index + 1; x < length; ++x) { current = decEndpoints[x]; + + if (current === decEndpoint) { + return false; + } + if (current.name === decEndpoint.name && current.target === decEndpoint.target) { return false; } diff --git a/lib/core/Project.js b/lib/core/Project.js index 4d6db94a..967ed2cd 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -141,6 +141,21 @@ Project.prototype.update = function (names, options) { } }); + // Add packages whose names are specified to be updated + that.walkTree(tree, function (node, name) { + if (names.indexOf(name) !== -1) { + targets.push(node); + return false; + } + }, true); + + // Add extraneous whose names are specified to be updated + mout.object.forOwn(flattened, function (decEndpoint, name) { + if (decEndpoint.extraneous && names.indexOf(name) !== -1) { + targets.push(decEndpoint); + } + }); + // Walk down the tree adding missing, incompatible // and resolved that.walkTree(tree, function (node, name) { @@ -152,20 +167,6 @@ Project.prototype.update = function (names, options) { resolved[name] = node; } }, true); - - // Add root packages whose names are specified to be updated - that.walkTree(tree, function (node, name) { - if (!node.missing && !node.linked && names.indexOf(name) !== -1) { - targets.push(node); - } - }, true); - - // Mark extraneous whose names are specified to be updated - mout.object.forOwn(flattened, function (decEndpoint, name) { - if (decEndpoint.extraneous && names.indexOf(name) !== -1) { - targets.push(decEndpoint); - } - }); } // Bootstrap the process @@ -306,7 +307,7 @@ Project.prototype.getTree = function () { var version; var target = node.endpoint.target; - if (target !== '*' && node.pkgMeta && semver.validRange(target)) { + if (node.pkgMeta && semver.validRange(target)) { version = node.pkgMeta.version; if (!version || !semver.satisfies(version, target)) { node.incompatible = true; @@ -693,7 +694,12 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { restored.missing = true; // Even if it is installed, check if it's compatible } else { - compatible = json.target === '*' || this._manager.areCompatible(json, local); + if (json.target === '*') { + compatible = !!local.pkgMeta._wildcard; + } else { + compatible = json.target === local.pkgMeta._target; + } + if (!compatible) { restored = json; restored.incompatible = true; diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index eafea802..65652e03 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -49,7 +49,8 @@ ResolveCache.prototype.retrieve = function (source, target) { // If target is a semver, find a suitable version if (semver.validRange(target)) { suitable = mout.array.find(versions, function (version) { - return semver.satisfies(version, target); + return semver.valid(version) && + semver.satisfies(version, target); }); if (suitable) {