]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/lib/build.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / lib / build.js
1 // npm build command
2
3 // everything about the installation after the creation of
4 // the .npm/{name}/{version}/package folder.
5 // linking the modules into the npm.root,
6 // resolving dependencies, etc.
7
8 // This runs AFTER install or link are completed.
9
10 var npm = require("./npm.js")
11   , log = require("npmlog")
12   , chain = require("slide").chain
13   , fs = require("graceful-fs")
14   , path = require("path")
15   , lifecycle = require("./utils/lifecycle.js")
16   , readJson = require("read-package-json")
17   , link = require("./utils/link.js")
18   , linkIfExists = link.ifExists
19   , cmdShim = require("cmd-shim")
20   , cmdShimIfExists = cmdShim.ifExists
21   , asyncMap = require("slide").asyncMap
22   , ini = require("ini")
23   , writeFile = require("write-file-atomic")
24
25 module.exports = build
26 build.usage = "npm build <folder>\n(this is plumbing)"
27
28 build._didBuild = {}
29 build._noLC = {}
30 function build (args, global, didPre, didRB, cb) {
31   if (typeof cb !== "function") cb = didRB, didRB = false
32   if (typeof cb !== "function") cb = didPre, didPre = false
33   if (typeof cb !== "function") {
34     cb = global, global = npm.config.get("global")
35   }
36   // it'd be nice to asyncMap these, but actually, doing them
37   // in parallel generally munges up the output from node-waf
38   var builder = build_(global, didPre, didRB)
39   chain(args.map(function (arg) { return function (cb) {
40     builder(arg, cb)
41   }}), cb)
42 }
43
44 function build_ (global, didPre, didRB) { return function (folder, cb) {
45   folder = path.resolve(folder)
46   if (build._didBuild[folder]) log.info("build", "already built", folder)
47   build._didBuild[folder] = true
48   log.info("build", folder)
49   readJson(path.resolve(folder, "package.json"), function (er, pkg) {
50     if (er) return cb(er)
51     chain
52       ( [ !didPre && [lifecycle, pkg, "preinstall", folder]
53         , [linkStuff, pkg, folder, global, didRB]
54         , [writeBuiltinConf, pkg, folder]
55         , didPre !== build._noLC && [lifecycle, pkg, "install", folder]
56         , didPre !== build._noLC && [lifecycle, pkg, "postinstall", folder]
57         , didPre !== build._noLC
58           && npm.config.get("npat")
59           && [lifecycle, pkg, "test", folder] ]
60       , cb )
61   })
62 }}
63
64 function writeBuiltinConf (pkg, folder, cb) {
65   // the builtin config is "sticky". Any time npm installs
66   // itself globally, it puts its builtin config file there
67   var parent = path.dirname(folder)
68   var dir = npm.globalDir
69
70   if (pkg.name !== "npm" ||
71       !npm.config.get("global") ||
72       !npm.config.usingBuiltin ||
73       dir !== parent) {
74     return cb()
75   }
76
77   var data = ini.stringify(npm.config.sources.builtin.data)
78   writeFile(path.resolve(folder, "npmrc"), data, cb)
79 }
80
81 function linkStuff (pkg, folder, global, didRB, cb) {
82   // allow to opt out of linking binaries.
83   if (npm.config.get("bin-links") === false) return cb()
84
85   // if it's global, and folder is in {prefix}/node_modules,
86   // then bins are in {prefix}/bin
87   // otherwise, then bins are in folder/../.bin
88   var parent = pkg.name[0] === '@' ? path.dirname(path.dirname(folder)) : path.dirname(folder)
89   var gnm = global && npm.globalDir
90   var gtop = parent === gnm
91
92   log.info('linkStuff', pkg._id)
93   log.silly('linkStuff', pkg._id, 'has', parent, 'as its parent node_modules')
94   if (global) log.silly('linkStuff', pkg._id, 'is part of a global install')
95   if (gnm) log.silly('linkStuff', pkg._id, 'is installed into a global node_modules')
96   if (gtop) log.silly('linkStuff', pkg._id, 'is installed into the top-level global node_modules')
97
98   shouldWarn(pkg, folder, global, function () {
99     asyncMap(
100       [linkBins, linkMans, !didRB && rebuildBundles],
101       function (fn, cb) {
102         if (!fn) return cb()
103         log.verbose(fn.name, pkg._id)
104         fn(pkg, folder, parent, gtop, cb)
105       },
106       cb
107     )
108   })
109 }
110
111 function shouldWarn(pkg, folder, global, cb) {
112   var parent = path.dirname(folder)
113     , top = parent === npm.dir
114     , cwd = npm.localPrefix
115
116   readJson(path.resolve(cwd, "package.json"), function(er, topPkg) {
117     if (er) return cb(er)
118
119     var linkedPkg = path.basename(cwd)
120       , currentPkg = path.basename(folder)
121
122     // current searched package is the linked package on first call
123     if (linkedPkg !== currentPkg) {
124
125       // don't generate a warning if it's listed in dependencies
126       if (Object.keys(topPkg.dependencies || {})
127           .concat(Object.keys(topPkg.devDependencies || {}))
128           .indexOf(currentPkg) === -1) {
129
130         if (top && pkg.preferGlobal && !global) {
131           log.warn("prefer global", pkg._id + " should be installed with -g")
132         }
133       }
134     }
135
136     cb()
137   })
138 }
139
140 function rebuildBundles (pkg, folder, parent, gtop, cb) {
141   if (!npm.config.get("rebuild-bundle")) return cb()
142
143   var deps = Object.keys(pkg.dependencies || {})
144              .concat(Object.keys(pkg.devDependencies || {}))
145     , bundles = pkg.bundleDependencies || pkg.bundledDependencies || []
146
147   fs.readdir(path.resolve(folder, "node_modules"), function (er, files) {
148     // error means no bundles
149     if (er) return cb()
150
151     log.verbose("rebuildBundles", files)
152     // don't asyncMap these, because otherwise build script output
153     // gets interleaved and is impossible to read
154     chain(files.filter(function (file) {
155       // rebuild if:
156       // not a .folder, like .bin or .hooks
157       return !file.match(/^[\._-]/)
158           // not some old 0.x style bundle
159           && file.indexOf("@") === -1
160           // either not a dep, or explicitly bundled
161           && (deps.indexOf(file) === -1 || bundles.indexOf(file) !== -1)
162     }).map(function (file) {
163       file = path.resolve(folder, "node_modules", file)
164       return function (cb) {
165         if (build._didBuild[file]) return cb()
166         log.verbose("rebuild bundle", file)
167         // if file is not a package dir, then don't do it.
168         fs.lstat(path.resolve(file, "package.json"), function (er) {
169           if (er) return cb()
170           build_(false)(file, cb)
171         })
172     }}), cb)
173   })
174 }
175
176 function linkBins (pkg, folder, parent, gtop, cb) {
177   if (!pkg.bin || !gtop && path.basename(parent) !== "node_modules") {
178     return cb()
179   }
180   var binRoot = gtop ? npm.globalBin
181                      : path.resolve(parent, ".bin")
182   log.verbose("link bins", [pkg.bin, binRoot, gtop])
183
184   asyncMap(Object.keys(pkg.bin), function (b, cb) {
185     linkBin( path.resolve(folder, pkg.bin[b])
186            , path.resolve(binRoot, b)
187            , gtop && folder
188            , function (er) {
189       if (er) return cb(er)
190       // bins should always be executable.
191       // XXX skip chmod on windows?
192       var src = path.resolve(folder, pkg.bin[b])
193       fs.chmod(src, npm.modes.exec, function (er) {
194         if (er && er.code === "ENOENT" && npm.config.get("ignore-scripts")) {
195           return cb()
196         }
197         if (er || !gtop) return cb(er)
198         var dest = path.resolve(binRoot, b)
199           , out = npm.config.get("parseable")
200                 ? dest + "::" + src + ":BINFILE"
201                 : dest + " -> " + src
202         console.log(out)
203         cb()
204       })
205     })
206   }, cb)
207 }
208
209 function linkBin (from, to, gently, cb) {
210   if (process.platform !== "win32") {
211     return linkIfExists(from, to, gently, cb)
212   } else {
213     return cmdShimIfExists(from, to, cb)
214   }
215 }
216
217 function linkMans (pkg, folder, parent, gtop, cb) {
218   if (!pkg.man || !gtop || process.platform === "win32") return cb()
219
220   var manRoot = path.resolve(npm.config.get("prefix"), "share", "man")
221   log.verbose("linkMans", "man files are", pkg.man, "in", manRoot)
222
223   // make sure that the mans are unique.
224   // otherwise, if there are dupes, it'll fail with EEXIST
225   var set = pkg.man.reduce(function (acc, man) {
226     acc[path.basename(man)] = man
227     return acc
228   }, {})
229   pkg.man = pkg.man.filter(function (man) {
230     return set[path.basename(man)] === man
231   })
232
233   asyncMap(pkg.man, function (man, cb) {
234     if (typeof man !== "string") return cb()
235     log.silly("linkMans", "preparing to link", man)
236     var parseMan = man.match(/(.*\.([0-9]+)(\.gz)?)$/)
237     if (!parseMan) {
238       return cb(new Error(
239         man+" is not a valid name for a man file.  " +
240         "Man files must end with a number, " +
241         "and optionally a .gz suffix if they are compressed."
242       ))
243     }
244
245     var stem = parseMan[1]
246     var sxn = parseMan[2]
247     var bn = path.basename(stem)
248     var manSrc = path.resolve(folder, man)
249     var manDest = path.join(manRoot, "man" + sxn, bn)
250
251     linkIfExists(manSrc, manDest, gtop && folder, cb)
252   }, cb)
253 }