Blame view

node_modules/bower/lib/commands/uninstall.js 3.23 KB
2dda2e10   Administrator   generator ignore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
  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;