mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
133 lines
3.8 KiB
JavaScript
133 lines
3.8 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;
|