116 lines
3.2 KiB
JavaScript
116 lines
3.2 KiB
JavaScript
var mout = require('mout');
|
|
var Q = require('q');
|
|
var Project = require('../core/Project');
|
|
var defaultConfig = require('../config');
|
|
|
|
function uninstall(logger, names, options, config) {
|
|
if (!names.length) {
|
|
return new Q();
|
|
}
|
|
|
|
var project;
|
|
|
|
options = options || {};
|
|
config = defaultConfig(config);
|
|
project = new Project(config, logger);
|
|
|
|
return project.getTree(options)
|
|
.spread(function (tree, flattened) {
|
|
// Uninstall nodes
|
|
return project.uninstall(names, options)
|
|
// Clean out non-shared uninstalled dependencies
|
|
.then(function (uninstalled) {
|
|
var names = Object.keys(uninstalled);
|
|
var children = [];
|
|
|
|
// Grab the dependencies of packages that were uninstalled
|
|
mout.object.forOwn(flattened, function (node) {
|
|
if (names.indexOf(node.endpoint.name) !== -1) {
|
|
children.push.apply(children, mout.object.keys(node.dependencies));
|
|
}
|
|
});
|
|
|
|
// Clean them!
|
|
return clean(project, children, uninstalled);
|
|
});
|
|
});
|
|
}
|
|
|
|
function clean(project, names, removed) {
|
|
removed = removed || {};
|
|
|
|
return project.getTree()
|
|
.spread(function (tree, flattened) {
|
|
var nodes = [];
|
|
var dependantsCounter = {};
|
|
|
|
// Grab the nodes of each specified name
|
|
mout.object.forOwn(flattened, function (node) {
|
|
if (names.indexOf(node.endpoint.name) !== -1) {
|
|
nodes.push(node);
|
|
}
|
|
});
|
|
|
|
// Walk the down the tree, gathering dependants of the packages
|
|
project.walkTree(tree, function (node, nodeName) {
|
|
if (names.indexOf(nodeName) !== -1) {
|
|
dependantsCounter[nodeName] = dependantsCounter[nodeName] || 0;
|
|
dependantsCounter[nodeName] += node.nrDependants;
|
|
}
|
|
}, true);
|
|
|
|
|
|
// Filter out those that have no dependants
|
|
nodes = nodes.filter(function (node) {
|
|
return !dependantsCounter[node.endpoint.name];
|
|
});
|
|
|
|
// Are we done?
|
|
if (!nodes.length) {
|
|
return Q.resolve(removed);
|
|
}
|
|
|
|
// Grab the nodes after filtering
|
|
names = nodes.map(function (node) {
|
|
return node.endpoint.name;
|
|
});
|
|
|
|
// Uninstall them
|
|
return project.uninstall(names)
|
|
// Clean out non-shared uninstalled dependencies
|
|
.then(function (uninstalled) {
|
|
var children;
|
|
|
|
mout.object.mixIn(removed, uninstalled);
|
|
|
|
// Grab the dependencies of packages that were uninstalled
|
|
children = [];
|
|
nodes.forEach(function (node) {
|
|
children.push.apply(children, mout.object.keys(node.dependencies));
|
|
});
|
|
|
|
// Recurse!
|
|
return clean(project, children, removed);
|
|
});
|
|
});
|
|
}
|
|
|
|
// -------------------
|
|
|
|
uninstall.readOptions = function (argv) {
|
|
var cli = require('../util/cli');
|
|
|
|
var options = cli.readOptions({
|
|
'save': { type: Boolean, shorthand: 'S' },
|
|
'save-dev': { type: Boolean, shorthand: 'D' }
|
|
}, argv);
|
|
|
|
var names = options.argv.remain.slice(1);
|
|
|
|
delete options.argv;
|
|
|
|
return [names, options];
|
|
};
|
|
|
|
module.exports = uninstall;
|