Comparing version 3.0.1 to 3.1.0
@@ -8,2 +8,4 @@ 'use strict' | ||
const fs = require('fs') | ||
const t = require('./list.js') | ||
const path = require('path') | ||
@@ -43,4 +45,3 @@ const c = module.exports = (opt_, files, cb) => { | ||
p.on('end', _ => fs.closeSync(fd)) | ||
files.forEach(file => p.add(file)) | ||
p.end() | ||
addFilesSync(p, files) | ||
threw = false | ||
@@ -64,4 +65,3 @@ } finally { | ||
files.forEach(file => p.add(file)) | ||
p.end() | ||
addFilesAsync(p, files) | ||
@@ -71,6 +71,36 @@ return cb ? promise.then(cb, cb) : promise | ||
const addFilesSync = (p, files) => { | ||
files.forEach(file => { | ||
if (file.charAt(0) === '@') | ||
t({ | ||
file: path.resolve(p.cwd, file.substr(1)), | ||
sync: true, | ||
noResume: true, | ||
onentry: entry => p.add(entry) | ||
}) | ||
else | ||
p.add(file) | ||
}) | ||
p.end() | ||
} | ||
const addFilesAsync = (p, files) => { | ||
while (files.length) { | ||
const file = files.shift() | ||
if (file.charAt(0) === '@') | ||
return t({ | ||
file: path.resolve(p.cwd, file.substr(1)), | ||
noResume: true, | ||
onentry: entry => p.add(entry) | ||
}).then(_ => addFilesAsync(p, files)) | ||
else | ||
p.add(file) | ||
} | ||
p.end() | ||
} | ||
const createSync = (opt, files) => { | ||
const p = new Pack.Sync(opt) | ||
files.forEach(file => p.add(file)) | ||
return p.end() | ||
addFilesSync(p, files) | ||
return p | ||
} | ||
@@ -80,4 +110,4 @@ | ||
const p = new Pack(opt) | ||
files.forEach(file => p.add(file)) | ||
return p.end() | ||
addFilesAsync(p, files) | ||
return p | ||
} |
@@ -35,3 +35,4 @@ 'use strict' | ||
onentryFunction(opt) | ||
if (!opt.noResume) | ||
onentryFunction(opt) | ||
@@ -38,0 +39,0 @@ return opt.file && opt.sync ? listFileSync(opt) |
105
lib/pack.js
@@ -16,2 +16,3 @@ 'use strict' | ||
this.absolute = absolute | ||
this.entry = null | ||
this.stat = null | ||
@@ -27,4 +28,6 @@ this.readdir = null | ||
const zlib = require('minizlib') | ||
const ReadEntry = require('./read-entry.js') | ||
const WriteEntry = require('./write-entry.js') | ||
const WriteEntrySync = WriteEntry.Sync | ||
const WriteEntryTar = WriteEntry.Tar | ||
const Yallist = require('yallist') | ||
@@ -41,3 +44,4 @@ const EOF = Buffer.alloc(1024) | ||
const JOBDONE = Symbol('jobDone') | ||
const ADDENTRY = Symbol('addEntry') | ||
const ADDFSENTRY = Symbol('addFSEntry') | ||
const ADDTARENTRY = Symbol('addTarEntry') | ||
const STAT = Symbol('stat') | ||
@@ -48,2 +52,3 @@ const READDIR = Symbol('readdir') | ||
const ENTRY = Symbol('entry') | ||
const ENTRYOPT = Symbol('entryOpt') | ||
const WRITEENTRYCLASS = Symbol('writeEntryClass') | ||
@@ -55,4 +60,5 @@ const WRITE = Symbol('write') | ||
const path = require('path') | ||
const warner = require('./warn-mixin.js') | ||
class Pack extends MiniPass { | ||
const Pack = warner(class Pack extends MiniPass { | ||
constructor (opt) { | ||
@@ -66,2 +72,3 @@ super(opt) | ||
this.strict = !!opt.strict | ||
this.noPax = !!opt.noPax | ||
this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '') | ||
@@ -121,7 +128,29 @@ this.linkCache = opt.linkCache || new Map() | ||
this[ADDENTRY](path) | ||
if (path instanceof ReadEntry) | ||
this[ADDTARENTRY](path) | ||
else | ||
this[ADDFSENTRY](path) | ||
return this.flowing | ||
} | ||
[ADDENTRY] (p) { | ||
[ADDTARENTRY] (p) { | ||
const absolute = path.resolve(this.cwd, p.path) | ||
if (this.prefix) | ||
p.path = this.prefix + '/' + p.path | ||
// in this case, we don't have to wait for the stat | ||
if (!this.filter(p.path, p)) | ||
p.resume() | ||
else { | ||
const job = new PackJob(p.path, absolute, false) | ||
job.entry = new WriteEntryTar(p, this[ENTRYOPT](job)) | ||
job.entry.on('end', _ => this[JOBDONE](job)) | ||
this[JOBS] += 1 | ||
this[QUEUE].push(job) | ||
} | ||
this[PROCESS]() | ||
} | ||
[ADDFSENTRY] (p) { | ||
const absolute = path.resolve(this.cwd, p) | ||
@@ -142,4 +171,5 @@ if (this.prefix) | ||
if (er) | ||
return this.emit('error', er) | ||
this[ONSTAT](job, stat) | ||
this.emit('error', er) | ||
else | ||
this[ONSTAT](job, stat) | ||
}) | ||
@@ -186,3 +216,9 @@ } | ||
this[PROCESSJOB](w.value) | ||
if (w.value.ignore) { | ||
const p = w.next | ||
this[QUEUE].removeNode(w) | ||
w.next = p | ||
} | ||
} | ||
this[PROCESSING] = false | ||
@@ -214,2 +250,8 @@ | ||
if (job.entry) { | ||
if (job === this[CURRENT] && !job.piped) | ||
this[PIPE](job) | ||
return | ||
} | ||
if (!job.stat) { | ||
@@ -225,7 +267,4 @@ if (this.statCache.has(job.absolute)) | ||
// filtered out! | ||
if (job.ignore) { | ||
if (job === this[CURRENT]) | ||
this[QUEUE].shift() | ||
if (job.ignore) | ||
return | ||
} | ||
@@ -241,8 +280,7 @@ if (!this.noDirRecurse && job.stat.isDirectory() && !job.readdir) { | ||
// we know it doesn't have an entry, because that got checked above | ||
job.entry = this[ENTRY](job) | ||
if (!job.entry) { | ||
job.entry = this[ENTRY](job) | ||
if (!job.entry) { | ||
job.ignore = true | ||
return | ||
} | ||
job.ignore = true | ||
return | ||
} | ||
@@ -254,4 +292,17 @@ | ||
warn (msg, data) { | ||
return this.emit('warn', msg, data) | ||
[ENTRYOPT] (job) { | ||
return { | ||
onwarn: (msg, data) => { | ||
this.warn(msg, data) | ||
}, | ||
noPax: this.noPax, | ||
cwd: this.cwd, | ||
absolute: job.absolute, | ||
preservePaths: this.preservePaths, | ||
maxReadSize: this.maxReadSize, | ||
strict: this.strict, | ||
portable: this.portable, | ||
linkCache: this.linkCache, | ||
statCache: this.statCache | ||
} | ||
} | ||
@@ -262,15 +313,3 @@ | ||
try { | ||
return new this[WRITEENTRYCLASS](job.path, { | ||
onwarn: (msg, data) => { | ||
this.warn(msg, data) | ||
}, | ||
cwd: this.cwd, | ||
absolute: job.absolute, | ||
preservePaths: this.preservePaths, | ||
maxReadSize: this.maxReadSize, | ||
strict: this.strict, | ||
portable: this.portable, | ||
linkCache: this.linkCache, | ||
statCache: this.statCache | ||
}).on('end', _ => { | ||
return new this[WRITEENTRYCLASS](job.path, this[ENTRYOPT](job)).on('end', _ => { | ||
this[JOBDONE](job) | ||
@@ -295,3 +334,3 @@ }) | ||
const base = job.path === './' ? '' : job.path.replace(/\/*$/, '/') | ||
this[ADDENTRY](base + entry) | ||
this[ADDFSENTRY](base + entry) | ||
}) | ||
@@ -319,3 +358,3 @@ | ||
} | ||
} | ||
}) | ||
@@ -348,3 +387,3 @@ class PackSync extends Pack { | ||
job.readdir.forEach(entry => { | ||
this[ADDENTRY](job.path + '/' + entry) | ||
this[ADDFSENTRY](job.path + '/' + entry) | ||
}) | ||
@@ -351,0 +390,0 @@ |
@@ -23,2 +23,3 @@ 'use strict' | ||
const warner = require('./warn-mixin.js') | ||
const path = require('path') | ||
@@ -62,3 +63,3 @@ const Header = require('./header.js') | ||
module.exports = class Parser extends EE { | ||
module.exports = warner(class Parser extends EE { | ||
constructor (opt) { | ||
@@ -392,14 +393,2 @@ const start = process.hrtime() | ||
warn (msg, data) { | ||
if (!this.strict) | ||
this.emit('warn', msg, data) | ||
else if (data instanceof Error) | ||
this.emit('error', data) | ||
else { | ||
const er = new Error(msg) | ||
er.data = data | ||
this[EMIT]('error', er) | ||
} | ||
} | ||
end (chunk) { | ||
@@ -415,2 +404,2 @@ if (!this[ABORTED]) { | ||
} | ||
} | ||
}) |
@@ -8,2 +8,4 @@ 'use strict' | ||
const fs = require('fs') | ||
const t = require('./list.js') | ||
const path = require('path') | ||
@@ -34,3 +36,2 @@ // starting at the head of the file, read a Header | ||
const replaceSync = (opt, files) => { | ||
@@ -87,4 +88,3 @@ const p = new Pack.Sync(opt) | ||
files.forEach(file => p.add(file)) | ||
p.end() | ||
addFilesSync(p, files) | ||
threw = false | ||
@@ -173,4 +173,3 @@ } finally { | ||
stream.on('close', resolve) | ||
files.forEach(file => p.add(file)) | ||
p.end() | ||
addFilesAsync(p, files) | ||
}) | ||
@@ -184,1 +183,31 @@ }) | ||
} | ||
const addFilesSync = (p, files) => { | ||
files.forEach(file => { | ||
if (file.charAt(0) === '@') | ||
t({ | ||
file: path.resolve(p.cwd, file.substr(1)), | ||
sync: true, | ||
noResume: true, | ||
onentry: entry => p.add(entry) | ||
}) | ||
else | ||
p.add(file) | ||
}) | ||
p.end() | ||
} | ||
const addFilesAsync = (p, files) => { | ||
while (files.length) { | ||
const file = files.shift() | ||
if (file.charAt(0) === '@') | ||
return t({ | ||
file: path.resolve(p.cwd, file.substr(1)), | ||
noResume: true, | ||
onentry: entry => p.add(entry) | ||
}).then(_ => addFilesAsync(p, files)) | ||
else | ||
p.add(file) | ||
} | ||
p.end() | ||
} |
@@ -5,2 +5,3 @@ 'use strict' | ||
const Header = require('./header.js') | ||
const ReadEntry = require('./read-entry.js') | ||
const fs = require('fs') | ||
@@ -25,4 +26,5 @@ const path = require('path') | ||
const CLOSE = Symbol('close') | ||
const warner = require('./warn-mixin.js') | ||
class WriteEntry extends MiniPass { | ||
const WriteEntry = warner(class WriteEntry extends MiniPass { | ||
constructor (p, opt) { | ||
@@ -45,2 +47,3 @@ opt = opt || {} | ||
this.strict = !!opt.strict | ||
this.noPax = !!opt.noPax | ||
if (typeof opt.onwarn === 'function') | ||
@@ -72,11 +75,2 @@ this.on('warn', opt.onwarn) | ||
warn (msg, data) { | ||
if (!this.strict) | ||
return this.emit('warn', msg, data) | ||
const er = new Error(msg) | ||
er.data = data | ||
this.emit('error', er) | ||
} | ||
[LSTAT] () { | ||
@@ -128,3 +122,3 @@ fs.lstat(this.absolute, (er, stat) => { | ||
if (this.header.encode()) | ||
if (this.header.encode() && !this.noPax) | ||
this.write(new Pax({ | ||
@@ -264,3 +258,3 @@ atime: this.portable ? null : this.header.atime, | ||
} | ||
} | ||
}) | ||
@@ -301,3 +295,96 @@ class WriteEntrySync extends WriteEntry { | ||
const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { | ||
constructor (readEntry, opt) { | ||
opt = opt || {} | ||
super(opt) | ||
this.readEntry = readEntry | ||
this.path = readEntry.path | ||
this.mode = readEntry.mode | ||
if (this.mode) | ||
this.mode = this.mode & 0o7777 | ||
this.uid = readEntry.uid | ||
this.gid = readEntry.gid | ||
this.uname = readEntry.uname | ||
this.gname = readEntry.gname | ||
this.size = readEntry.size | ||
this.mtime = readEntry.mtime | ||
this.atime = readEntry.atime | ||
this.ctime = readEntry.ctime | ||
this.linkpath = readEntry.linkpath | ||
this.uname = readEntry.uname | ||
this.gname = readEntry.gname | ||
this.preservePaths = !!opt.preservePaths | ||
this.portable = !!opt.portable | ||
this.strict = !!opt.strict | ||
this.noPax = !!opt.noPax | ||
if (typeof opt.onwarn === 'function') | ||
this.on('warn', opt.onwarn) | ||
if (path.isAbsolute(this.path) && !this.preservePaths) { | ||
const parsed = path.parse(this.path) | ||
this.warn( | ||
'stripping ' + parsed.root + ' from absolute path', | ||
this.path | ||
) | ||
this.path = this.path.substr(parsed.root.length) | ||
} | ||
this.remain = readEntry.size | ||
this.blockRemain = readEntry.blockRemain | ||
this.header = new Header({ | ||
path: this.path, | ||
linkpath: this.linkpath, | ||
// only the permissions and setuid/setgid/sticky bitflags | ||
// not the higher-order bits that specify file type | ||
mode: this.mode, | ||
uid: this.portable ? null : this.uid, | ||
gid: this.portable ? null : this.gid, | ||
size: this.size, | ||
mtime: this.mtime, | ||
type: this.type, | ||
uname: this.portable ? null : this.uname, | ||
atime: this.portable ? null : this.atime, | ||
ctime: this.portable ? null : this.ctime | ||
}) | ||
if (this.header.encode() && !this.noPax) | ||
super.write(new Pax({ | ||
atime: this.portable ? null : this.atime, | ||
ctime: this.portable ? null : this.ctime, | ||
gid: this.portable ? null : this.gid, | ||
mtime: this.mtime, | ||
path: this.path, | ||
linkpath: this.linkpath, | ||
size: this.size, | ||
uid: this.portable ? null : this.uid, | ||
uname: this.portable ? null : this.uname, | ||
dev: this.portable ? null : this.readEntry.dev, | ||
ino: this.portable ? null : this.readEntry.ino, | ||
nlink: this.portable ? null : this.readEntry.nlink | ||
}).encode()) | ||
super.write(this.header.block) | ||
readEntry.pipe(this) | ||
} | ||
write (data) { | ||
const writeLen = data.length | ||
if (writeLen > this.blockRemain) | ||
throw new Error('writing more to entry than is appropriate') | ||
this.blockRemain -= writeLen | ||
return super.write(data) | ||
} | ||
end () { | ||
if (this.blockRemain) | ||
this.write(Buffer.alloc(this.blockRemain)) | ||
return super.end() | ||
} | ||
}) | ||
WriteEntry.Sync = WriteEntrySync | ||
WriteEntry.Tar = WriteEntryTar | ||
@@ -304,0 +391,0 @@ const getType = stat => |
@@ -5,3 +5,3 @@ { | ||
"description": "tar for node", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -186,2 +186,6 @@ # node-tar | ||
An entry in `fileList` that starts with an `@` symbol is a tar archive | ||
whose entries will be added. To add a file that starts with `@`, | ||
prepend it with `./`. | ||
The following options are supported: | ||
@@ -214,5 +218,4 @@ | ||
time-based operations. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. [Alias: `P`] | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. [Alias: `P`] | ||
- `mode` The mode to set on the created file archive | ||
@@ -223,2 +226,5 @@ - `noDirRecurse` Do not recursively archive the contents of | ||
this option, symbolic links are archived as such. [Alias: `L`, `h`] | ||
- `noPax` Suppress pax extended headers. Note that this means that | ||
long paths and linkpaths will be truncated, and large or negative | ||
numeric values may be interpreted incorrectly. | ||
@@ -235,3 +241,3 @@ The following options are mostly internal, but can be modified in some | ||
- `maxReadSize` The maximum buffer size for `fs.read()` operations. | ||
Defaults to 1 MB. | ||
Defaults to 16 MB. | ||
@@ -340,2 +346,6 @@ ### tar.x(options, fileList, callback) [alias: tar.extract] | ||
Defaults to 16 MB. | ||
- `noResume` By default, `entry` streams are resumed immediately after | ||
the call to `onentry`. Set `noResume: true` to suppress this | ||
behavior. Note that by opting into this, the stream will never | ||
complete until the entry data is consumed. | ||
@@ -350,2 +360,6 @@ ### tar.u(options, fileList, callback) [alias: tar.update] | ||
An entry in `fileList` that starts with an `@` symbol is a tar archive | ||
whose entries will be added. To add a file that starts with `@`, | ||
prepend it with `./`. | ||
The following options are supported: | ||
@@ -372,5 +386,4 @@ | ||
time-based operations. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. [Alias: `P`] | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. [Alias: `P`] | ||
- `maxReadSize` The maximum buffer size for `fs.read()` operations. | ||
@@ -382,2 +395,5 @@ Defaults to 16 MB. | ||
this option, symbolic links are archived as such. [Alias: `L`, `h`] | ||
- `noPax` Suppress pax extended headers. Note that this means that | ||
long paths and linkpaths will be truncated, and large or negative | ||
numeric values may be interpreted incorrectly. | ||
@@ -392,2 +408,6 @@ ### tar.r(options, fileList, callback) [alias: tar.replace] | ||
An entry in `fileList` that starts with an `@` symbol is a tar archive | ||
whose entries will be added. To add a file that starts with `@`, | ||
prepend it with `./`. | ||
The following options are supported: | ||
@@ -414,5 +434,4 @@ | ||
time-based operations. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. [Alias: `P`] | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. [Alias: `P`] | ||
- `maxReadSize` The maximum buffer size for `fs.read()` operations. | ||
@@ -424,2 +443,5 @@ Defaults to 16 MB. | ||
this option, symbolic links are archived as such. [Alias: `L`, `h`] | ||
- `noPax` Suppress pax extended headers. Note that this means that | ||
long paths and linkpaths will be truncated, and large or negative | ||
numeric values may be interpreted incorrectly. | ||
@@ -454,5 +476,4 @@ ## Low-Level API | ||
time-based operations. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. | ||
- `linkCache` A Map object containing the device and inode value for | ||
@@ -470,2 +491,5 @@ any file whose nlink is > 1, to identify hard links. | ||
this option, symbolic links are archived as such. | ||
- `noPax` Suppress pax extended headers. Note that this means that | ||
long paths and linkpaths will be truncated, and large or negative | ||
numeric values may be interpreted incorrectly. | ||
@@ -636,5 +660,4 @@ #### add(path) | ||
- `statCache` A Map object that caches calls `lstat`. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. | ||
- `cwd` The current working directory for creating the archive. | ||
@@ -648,2 +671,5 @@ Defaults to `process.cwd()`. | ||
replace `\` with `/`. | ||
- `noPax` Suppress pax extended headers. Note that this means that | ||
long paths and linkpaths will be truncated, and large or negative | ||
numeric values may be interpreted incorrectly. | ||
@@ -665,5 +691,4 @@ #### constructor(path, options) | ||
- `statCache` A Map object that caches calls `lstat`. | ||
- `preservePaths` Allow absolute paths and paths containing `..`. By | ||
default, `/` is stripped from absolute paths, `..` paths are not | ||
added to the archive. | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. | ||
- `cwd` The current working directory for creating the archive. | ||
@@ -690,2 +715,23 @@ Defaults to `process.cwd()`. | ||
### class tar.WriteEntry.Tar | ||
A version of tar.WriteEntry that gets its data from a tar.ReadEntry | ||
instead of from the filesystem. | ||
#### constructor(readEntry, options) | ||
`readEntry` is the entry being read out of another archive. | ||
The following options are supported: | ||
- `portable` Omit metadata that is system-specific: `ctime`, `atime`, | ||
`uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note | ||
that `mtime` is still included, because this is necessary other | ||
time-based operations. | ||
- `preservePaths` Allow absolute paths. By default, `/` is stripped | ||
from absolute paths. | ||
- `strict` Treat warnings as crash-worthy errors. Default false. | ||
- `onwarn` A function that will get called with `(message, data)` for | ||
any warnings encountered. | ||
### class tar.Header | ||
@@ -692,0 +738,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
114371
21
2588
848