diff options
Diffstat (limited to 'deps/npm/lib/pack.js')
-rw-r--r-- | deps/npm/lib/pack.js | 134 |
1 files changed, 89 insertions, 45 deletions
diff --git a/deps/npm/lib/pack.js b/deps/npm/lib/pack.js index ede59dd12c..68c6030ee8 100644 --- a/deps/npm/lib/pack.js +++ b/deps/npm/lib/pack.js @@ -1,25 +1,39 @@ +'use strict' + // npm pack <pkg> // Packs the specified package into a .tgz file, which can then // be installed. -module.exports = pack +const BB = require('bluebird') -var install = require('./install.js') -var cache = require('./cache.js') -var fs = require('graceful-fs') -var chain = require('slide').chain -var path = require('path') -var cwd = process.cwd() -var writeStreamAtomic = require('fs-write-stream-atomic') -var cachedPackageRoot = require('./cache/cached-package-root.js') -var output = require('./utils/output.js') +const cache = require('./cache') +const cacache = require('cacache') +const deprCheck = require('./utils/depr-check') +const fpm = BB.promisify(require('./fetch-package-metadata')) +const fs = require('graceful-fs') +const install = require('./install') +const lifecycle = BB.promisify(require('./utils/lifecycle')) +const move = require('move-concurrently') +const npm = require('./npm') +const output = require('./utils/output') +const pacoteOpts = require('./config/pacote') +const path = require('path') +const pathIsInside = require('path-is-inside') +const pipe = BB.promisify(require('mississippi').pipe) +const prepublishWarning = require('./utils/warn-deprecated')('prepublish-on-install') +const pinflight = require('promise-inflight') +const readJson = BB.promisify(require('read-package-json')) +const tarPack = BB.promisify(require('./utils/tar').pack) +const writeStreamAtomic = require('fs-write-stream-atomic') pack.usage = 'npm pack [[<@scope>/]<pkg>...]' // if it can be installed, it can be packed. pack.completion = install.completion +module.exports = pack function pack (args, silent, cb) { + const cwd = process.cwd() if (typeof cb !== 'function') { cb = silent silent = false @@ -27,47 +41,77 @@ function pack (args, silent, cb) { if (args.length === 0) args = ['.'] - chain( - args.map(function (arg) { return function (cb) { pack_(arg, cb) } }), - function (er, files) { - if (er || silent) return cb(er, files) - printFiles(files, cb) + BB.all( + args.map((arg) => pack_(arg, cwd)) + ).then((files) => { + if (!silent) { + output(files.map((f) => path.relative(cwd, f)).join('\n')) } - ) -} - -function printFiles (files, cb) { - files = files.map(function (file) { - return path.relative(cwd, file) - }) - output(files.join('\n')) - cb() + cb(null, files) + }, cb) } // add to cache, then cp to the cwd -function pack_ (pkg, cb) { - cache.add(pkg, null, null, false, function (er, data) { - if (er) return cb(er) - +function pack_ (pkg, dir) { + return fpm(pkg, dir).then((mani) => { + let name = mani.name[0] === '@' // scoped packages get special treatment - var name = data.name - if (name[0] === '@') name = name.substr(1).replace(/\//g, '-') - var fname = name + '-' + data.version + '.tgz' - - var cached = path.join(cachedPackageRoot(data), 'package.tgz') - var from = fs.createReadStream(cached) - var to = writeStreamAtomic(fname) - var errState = null - - from.on('error', cb_) - to.on('error', cb_) - to.on('close', cb_) - from.pipe(to) + ? mani.name.substr(1).replace(/\//g, '-') + : mani.name + const target = `${name}-${mani.version}.tgz` + return pinflight(target, () => { + if (mani._requested.type === 'directory') { + return prepareDirectory(mani._resolved).then(() => { + return packDirectory(mani, mani._resolved, target) + }) + } else { + return cache.add(pkg).then((info) => { + return pipe( + cacache.get.stream.byDigest(pacoteOpts().cache, info.integrity || mani._integrity), + writeStreamAtomic(target) + ) + }).then(() => target) + } + }) + }) +} - function cb_ (er) { - if (errState) return - if (er) return cb(errState = er) - cb(null, fname) +module.exports.prepareDirectory = prepareDirectory +function prepareDirectory (dir) { + return readJson(path.join(dir, 'package.json')).then((pkg) => { + if (!pkg.name) { + throw new Error('package.json requires a "name" field') + } + if (!pkg.version) { + throw new Error('package.json requires a valid "version" field') } + if (!pathIsInside(dir, npm.tmp)) { + if (pkg.scripts && pkg.scripts.prepublish) { + prepublishWarning([ + 'As of npm@5, `prepublish` scripts are deprecated.', + 'Use `prepare` for build steps and `prepublishOnly` for upload-only', + 'See the deprecation note in `npm help scripts` for more information' + ]) + } + if (npm.config.get('ignore-prepublish')) { + return lifecycle(pkg, 'prepare', dir).then(() => pkg) + } else { + return lifecycle(pkg, 'prepublish', dir).then(() => { + return lifecycle(pkg, 'prepare', dir) + }).then(() => pkg) + } + } + return pkg + }) +} + +module.exports.packDirectory = packDirectory +function packDirectory (mani, dir, target) { + deprCheck(mani) + return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'packing'}, (tmp) => { + const tmpTarget = path.join(tmp, path.basename(target)) + return tarPack(tmpTarget, dir, mani).then(() => { + return move(tmpTarget, target, {Promise: BB, fs}) + }).then(() => target) }) } |