| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- 'use strict'
- const Minipass = require('minipass')
- const path = require('path')
- const tar = require('tar')
- module.exports = extractStream
- module.exports._computeMode = computeMode
- class Transformer extends Minipass {
- constructor (spec, opts) {
- super()
- this.spec = spec
- this.opts = opts
- this.str = ''
- }
- write (data) {
- this.str += data
- return true
- }
- end () {
- const replaced = this.str.replace(
- /}\s*$/,
- `\n,"_resolved": ${
- JSON.stringify(this.opts.resolved || '')
- }\n,"_integrity": ${
- JSON.stringify(this.opts.integrity || '')
- }\n,"_from": ${
- JSON.stringify(this.spec.toString())
- }\n}`
- )
- super.write(replaced)
- return super.end()
- }
- }
- function computeMode (fileMode, optMode, umask) {
- return (fileMode | optMode) & ~(umask || 0)
- }
- function pkgJsonTransform (spec, opts) {
- return entry => {
- if (entry.path === 'package.json') {
- const transformed = new Transformer(spec, opts)
- return transformed
- }
- }
- }
- function extractStream (spec, dest, opts) {
- opts = opts || {}
- const sawIgnores = new Set()
- return tar.x({
- cwd: dest,
- filter: (name, entry) => !entry.header.type.match(/^.*link$/i),
- strip: 1,
- onwarn: msg => opts.log && opts.log.warn('tar', msg),
- uid: opts.uid,
- gid: opts.gid,
- umask: opts.umask,
- transform: opts.resolved && pkgJsonTransform(spec, opts),
- onentry (entry) {
- if (entry.type.toLowerCase() === 'file') {
- entry.mode = computeMode(entry.mode, opts.fmode, opts.umask)
- } else if (entry.type.toLowerCase() === 'directory') {
- entry.mode = computeMode(entry.mode, opts.dmode, opts.umask)
- } else {
- entry.mode = computeMode(entry.mode, 0, opts.umask)
- }
- // Note: This mirrors logic in the fs read operations that are
- // employed during tarball creation, in the fstream-npm module.
- // It is duplicated here to handle tarballs that are created
- // using other means, such as system tar or git archive.
- if (entry.type.toLowerCase() === 'file') {
- const base = path.basename(entry.path)
- if (base === '.npmignore') {
- sawIgnores.add(entry.path)
- } else if (base === '.gitignore') {
- const npmignore = entry.path.replace(/\.gitignore$/, '.npmignore')
- if (!sawIgnores.has(npmignore)) {
- // Rename, may be clobbered later.
- entry.path = npmignore
- }
- }
- }
- }
- })
- }
|