Welcome to mirror list, hosted at ThFree Co, Russian Federation.

uninstall.js « lib - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e3c89d8d0783f416a2fb3099de2a73b73aefb654 (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

// remove a package.  if it has dependents, then fail, and demand that they be
// uninstalled first.  If activee, then fail, and depand that it be deactivated
// first.

module.exports = uninstall

var rm = require("./utils/rm-rf")
  , fs = require("fs")
  , log = require("./utils/log")
  , readJson = require("./utils/read-json")
  , path = require("path")
  , npm = require("../npm")
  , chain = require("./utils/chain")
  , lifecycle = require("./utils/lifecycle")
  , semver = require("./utils/semver")
  , readInstalled = require("./utils/read-installed")

function uninstall (args, cb) {
  var name = args.shift()
    , version = args.shift()
  
  if (name && !version) {
    // remove ALL versions.
    readInstalled([name], function (er, installed) {
      if (er) return log.er(cb,
        "Could not read installed data")(er)
      if (!installed || !installed[name]) return log(
        "Not installed ", "uninstall", cb)
      var versions = Object.keys(installed[name])
      log("removing all versions of "+name, "uninstall")
      ;(function R (ver) {
        log(ver, "multiremove")
        if (!ver) return cb()
        uninstall([name, ver], function (er) {
          if (er) return log.er(cb,
            "Couldn't remove version "+ver)(er)
          return R(versions.pop())
        })
      })(versions.pop())
    })
    return
  }
  var pkgdir = path.join(npm.dir, name, version)
    , jsonFile = path.join(pkgdir, "package", "package.json")
    , active = path.join(npm.dir, name, "active")
    , libdir = path.join(npm.root, name+"-"+version)
    , mainjs = libdir + ".js"
    , dependents = path.join(pkgdir, "dependents")

  chain
    ( [log, "about to remove: " + pkgdir, "uninstall"]
    , function (cb) {
        fs.readlink(active, function (er, active) {
          if (er) cb()
          if (path.basename(active||"") !== version) return cb()
          else if (!npm.config.get("auto-deactivate")) return cb(new Error(
            "cannot remove active package.\n"+
            "      npm deactivate "+name+" "+version+"\n"+
            "and then retry."))
          else return log
            ( "removing active version: "+active, "uninstall"
            , function () { npm.commands.deactivate([name], log.er(cb,
                "Failed to deactivate"))}
            )
        })
      }
    // if has dependents, then fail
    , function (cb) {
        fs.readdir(dependents, function (er, children) {
        if (children && children.length) return cb(new Error(
          name+"-"+version+" depended upon by \n"+
          "      " + require("sys").inspect(children)+"\n"+
          "remove them first."))
        return cb()
      })}
    , [log, "checked deps", "uninstall"]
    // remove the whole thing.
    , function (cb) { readJson(jsonFile, function (er, data) {
        if (er) {
          log("Couldn't read json. Probably not installed", "uninstall")
          log(er, "uninstall")
          return cb()
        }
        data.version = version
        chain
          ( [lifecycle, data, "preuninstall"]
          , [lifecycle, data, "uninstall"]
          // clean out any dependent links, since this is going away.
          , [removeDependent, pkgdir, data]
          // clean out anything that's been linked in.  This is an ugly kludgey
          // awful artifact that is caused by linking stuff into the pkgdir
          , [removeLinkedDeps, pkgdir, data]
          , [rm, pkgdir]
          , [removeBins, data]
          , [rm, mainjs]
          , [rm, libdir]
          // if that was the last one, then remove the whole thing.
          , function (cb) { pkgdir = path.dirname(pkgdir); cb() }
          , function (cb) { fs.readdir(pkgdir, function (er, versions) {
              if (er) return log.er(cb, "failed to read " +pkgdir)(er)
              log(versions, "remaining")
              if (versions && versions.length) return cb()
              rm(pkgdir, cb)
            })}
          , [lifecycle, data, "postuninstall"]
          , cb
          )
      })}
    , cb
    )
}

function removeBins (data, cb) {
  log(data.bin, "remove bins")
  if (!data.bin) return cb()
  var binroot = npm.config.get("binroot")
  ;(function R (bins) {
    if (!bins.length) return cb()
    chain
      ( [rm, binroot + "/" + bins.pop()+"-"+data.version]
      , [rm, binroot + "/" + bins.pop()]
      , cb
      )
  })(Object.getOwnPropertyNames(data.bin))
}

function removeDependent (pkgdir, data, cb) {
  var dependencies = path.join(pkgdir, "dependencies")
  fs.readdir(dependencies, function (er, deps) {
    if (er) return cb(er)
    ;(function R () {
      var dep = deps.pop()
      if (!dep) return cb()
      dep = path.join(dependencies, dep)
      fs.readlink(dep, function (er, realdep) {
        if (er) return cb(er)
        var p = semver.parsePackage(path.basename(realdep, ".js"))
          , depPath = path.join(
              npm.dir, p[1], p[2], "dependents", data.name+"-"+data.version)
        log(depPath, "removeDependent")
        rm(depPath, R)
      })
    })()
  })
}

function removeLinkedDeps (pkgdir, data, cb) {
  if (!data.link) return cb()
  var depLinks = []
  for (var i in data.link) {
    depLinks.push(path.join(pkgdir, "package", data.link[i]))
  }
  ;(function R () {
    var dep = depLinks.pop()
    if (!dep) return cb()
    chain
      ( [rm, dep]
      , [rm, dep+".js"]
      , function (er, ok) {
          if (er) return cb(er)
          R()
        }
      )
  })()
}