]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/cache/add-local-tarball.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / lib / cache / add-local-tarball.js
1 var mkdir = require("mkdirp")
2   , assert = require("assert")
3   , fs = require("graceful-fs")
4   , writeFileAtomic = require("write-file-atomic")
5   , path = require("path")
6   , sha = require("sha")
7   , npm = require("../npm.js")
8   , log = require("npmlog")
9   , tar = require("../utils/tar.js")
10   , pathIsInside = require("path-is-inside")
11   , getCacheStat = require("./get-stat.js")
12   , cachedPackageRoot = require("./cached-package-root.js")
13   , chownr = require("chownr")
14   , inflight = require("inflight")
15   , once = require("once")
16   , writeStreamAtomic = require("fs-write-stream-atomic")
17   , randomBytes = require("crypto").pseudoRandomBytes // only need uniqueness
18
19 module.exports = addLocalTarball
20
21 function addLocalTarball (p, pkgData, shasum, cb) {
22   assert(typeof p === "string", "must have path")
23   assert(typeof cb === "function", "must have callback")
24
25   if (!pkgData) pkgData = {}
26
27   // If we don't have a shasum yet, compute it.
28   if (!shasum) {
29     return sha.get(p, function (er, shasum) {
30       if (er) return cb(er)
31       log.silly("addLocalTarball", "shasum (computed)", shasum)
32       addLocalTarball(p, pkgData, shasum, cb)
33     })
34   }
35
36   if (pathIsInside(p, npm.cache)) {
37     if (path.basename(p) !== "package.tgz") {
38       return cb(new Error("Not a valid cache tarball name: "+p))
39     }
40     log.verbose("addLocalTarball", "adding from inside cache", p)
41     return addPlacedTarball(p, pkgData, shasum, cb)
42   }
43
44   addTmpTarball(p, pkgData, shasum, function (er, data) {
45     if (data) {
46       data._resolved = p
47       data._shasum = data._shasum || shasum
48     }
49     return cb(er, data)
50   })
51 }
52
53 function addPlacedTarball (p, pkgData, shasum, cb) {
54   assert(pkgData, "should have package data by now")
55   assert(typeof cb === "function", "cb function required")
56
57   getCacheStat(function (er, cs) {
58     if (er) return cb(er)
59     return addPlacedTarball_(p, pkgData, cs.uid, cs.gid, shasum, cb)
60   })
61 }
62
63 function addPlacedTarball_ (p, pkgData, uid, gid, resolvedSum, cb) {
64   var folder = path.join(cachedPackageRoot(pkgData), "package")
65
66   // First, make sure we have the shasum, if we don't already.
67   if (!resolvedSum) {
68     sha.get(p, function (er, shasum) {
69       if (er) return cb(er)
70       addPlacedTarball_(p, pkgData, uid, gid, shasum, cb)
71     })
72     return
73   }
74
75   mkdir(folder, function (er) {
76     if (er) return cb(er)
77     var pj = path.join(folder, "package.json")
78     var json = JSON.stringify(pkgData, null, 2)
79     writeFileAtomic(pj, json, function (er) {
80       cb(er, pkgData)
81     })
82   })
83 }
84
85 function addTmpTarball (tgz, pkgData, shasum, cb) {
86   assert(typeof cb === "function", "must have callback function")
87   assert(shasum, "must have shasum by now")
88
89   cb = inflight("addTmpTarball:" + tgz, cb)
90   if (!cb) return log.verbose("addTmpTarball", tgz, "already in flight; not adding")
91   log.verbose("addTmpTarball", tgz, "not in flight; adding")
92
93   // we already have the package info, so just move into place
94   if (pkgData && pkgData.name && pkgData.version) {
95     log.verbose(
96       "addTmpTarball",
97       "already have metadata; skipping unpack for",
98       pkgData.name + "@" + pkgData.version
99     )
100     return addTmpTarball_(tgz, pkgData, shasum, cb)
101   }
102
103   // This is a tarball we probably downloaded from the internet.  The shasum's
104   // already been checked, but we haven't ever had a peek inside, so we unpack
105   // it here just to make sure it is what it says it is.
106   //
107   // NOTE: we might not have any clue what we think it is, for example if the
108   // user just did `npm install ./foo.tgz`
109
110   // generate a unique filename
111   randomBytes(6, function (er, random) {
112     if (er) return cb(er)
113
114     var target = path.join(npm.tmp, "unpack-" + random.toString("hex"))
115     getCacheStat(function (er, cs) {
116       if (er) return cb(er)
117
118       log.verbose("addTmpTarball", "validating metadata from", tgz)
119       tar.unpack(tgz, target, null, null, cs.uid, cs.gid, function (er, data) {
120         if (er) return cb(er)
121
122         // check that this is what we expected.
123         if (!data.name) {
124           return cb(new Error("No name provided"))
125         }
126         else if (pkgData.name && data.name !== pkgData.name) {
127           return cb(new Error("Invalid Package: expected " + pkgData.name +
128                               " but found " + data.name))
129         }
130
131         if (!data.version) {
132           return cb(new Error("No version provided"))
133         }
134         else if (pkgData.version && data.version !== pkgData.version) {
135           return cb(new Error("Invalid Package: expected " +
136                               pkgData.name + "@" + pkgData.version +
137                               " but found " + data.name + "@" + data.version))
138         }
139
140         addTmpTarball_(tgz, data, shasum, cb)
141       })
142     })
143   })
144 }
145
146 function addTmpTarball_ (tgz, data, shasum, cb) {
147   assert(typeof cb === "function", "must have callback function")
148   cb = once(cb)
149
150   assert(data.name, "should have package name by now")
151   assert(data.version, "should have package version by now")
152
153   var root = cachedPackageRoot(data)
154   var pkg = path.resolve(root, "package")
155   var target = path.resolve(root, "package.tgz")
156   getCacheStat(function (er, cs) {
157     if (er) return cb(er)
158     mkdir(pkg, function (er, created) {
159
160       // chown starting from the first dir created by mkdirp,
161       // or the root dir, if none had to be created, so that
162       // we know that we get all the children.
163       function chown () {
164         chownr(created || root, cs.uid, cs.gid, done)
165       }
166
167       if (er) return cb(er)
168       var read = fs.createReadStream(tgz)
169       var write = writeStreamAtomic(target, { mode: npm.modes.file })
170       var fin = cs.uid && cs.gid ? chown : done
171       read.on("error", cb).pipe(write).on("error", cb).on("close", fin)
172     })
173
174   })
175
176   function done() {
177     data._shasum = data._shasum || shasum
178     cb(null, data)
179   }
180 }