"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/npm/lib/build.js" (8 Mar 2017, 8707 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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