diff --git a/lib/core/Project.js b/lib/core/Project.js index 33fb4f2b..ee884441 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -47,10 +47,6 @@ Project.prototype.install = function (endpoints, options) { // Analyse the project .then(that.analyse.bind(this)) .spread(function (json, tree, flattened) { - var targets = {}; - var resolved = {}; - var installed; - // Mark targets endpoints.forEach(function (endpoint) { var decEndpoint = endpointParser.decompose(endpoint); @@ -65,6 +61,7 @@ Project.prototype.install = function (endpoints, options) { if (targets[name]) { return false; // Abort traversal } + resolved[name] = node.pkgMeta; }); @@ -78,19 +75,26 @@ Project.prototype.install = function (endpoints, options) { }) // Handle save and saveDev options .then(function (installed) { - var jsonKey; - if (!options.save && !options.saveDev) { return; } - jsonKey = options.save ? 'dependencies' : 'devDependencies'; - that._json[jsonKey] = that._json[jsonKey] || {}; - + // Cycle through the initial targets and not the installed + // ones because some targets could already be installed mout.object.forOwn(targets, function (decEndpoint) { var source = decEndpoint.registry ? '' : decEndpoint.source; var target = decEndpoint.pkgMeta.version ? '~' + decEndpoint.pkgMeta.version : decEndpoint.target; - that._json[jsonKey][decEndpoint.name] = mout.string.ltrim(source + '#' + target, ['#']); + var endpoint = mout.string.ltrim(source + '#' + target, ['#']); + + if (options.save) { + that._json.dependencies = that._json.dependencies || {}; + that._json.dependencies[decEndpoint.name] = endpoint; + } + + if (options.saveDev) { + that._json.devDependencies = that._json.devDependencies || {}; + that._json.devDependencies[decEndpoint.name] = endpoint; + } }); return that._saveJson() @@ -164,8 +168,7 @@ Project.prototype.update = function (names, options) { return; } - // Use json entry if available, - // fallbacking to the installed one + // Use json entry if available, fallbacking to the installed one jsonEntry = json.dependencies && json.dependencies[name]; if (jsonEntry) { targets[name] = endpointParser.json2decomposed(name, jsonEntry); @@ -180,6 +183,7 @@ Project.prototype.update = function (names, options) { if (targets[name]) { return false; // Abort traversal } + resolved[name] = node.pkgMeta; }); @@ -307,7 +311,6 @@ Project.prototype.analyse = function () { name: json.name, source: this._config.cwd, target: json.version, - dir: this._config.cwd, pkgMeta: json, root: true }; @@ -334,6 +337,12 @@ Project.prototype.analyse = function () { } }, this); + // The package meta set above is not really a package meta + // so we delete it from the root + // Also remove it from the flattened tree + delete root.pkgMeta; + delete flattened[json.name]; + return [json, root, flattened]; }.bind(this)); }; @@ -481,8 +490,8 @@ Project.prototype._readInstalled = function () { decEndpoints[name] = { name: name, source: pkgMeta._source, - target: pkgMeta.version, - dir: path.dirname(jsonFile), + target: pkgMeta.version || '*', + canonicalPkg: path.dirname(jsonFile), pkgMeta: pkgMeta }; }); @@ -501,7 +510,6 @@ Project.prototype._readInstalled = function () { Project.prototype._removePackages = function (packages, options) { var promises = []; - var jsonKey = options.save ? 'dependencies' : (options.saveDev ? 'devDependencies' : null); var deferred = Q.defer(); mout.object.forOwn(packages, function (dir, name) { @@ -536,10 +544,17 @@ Project.prototype._removePackages = function (packages, options) { } // Remove from json only if successfully deleted - if (jsonKey && this._json[jsonKey]) { + if (options.save && this._json.dependencies) { promise = promise .then(function () { - delete this._json[jsonKey][name]; + delete this._json.dependencies[name]; + }.bind(this)); + } + + if (options.saveDev && this._json.devDependencies) { + promise = promise + .then(function () { + delete this._json.devDependencies[name]; }.bind(this)); } @@ -559,7 +574,7 @@ Project.prototype._removePackages = function (packages, options) { }; Project.prototype._walkTree = function (node, fn) { - var queue = [node]; + var queue = mout.object.values(node.dependencies); var result; while (queue.length) {