mirror of
https://github.com/bower/bower.git
synced 2026-04-24 03:00:19 -04:00
They caused more issues than useful they were. Instead, we'll focus on fetching statistics from NPM registry to watch Bower's popularity, and GitHub stars over time to watch packages' popularity.
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;
|