tar-fs
Advanced tools
Comparing version 2.1.1 to 3.0.0
370
index.js
@@ -1,77 +0,26 @@ | ||
var chownr = require('chownr') | ||
var tar = require('tar-stream') | ||
var pump = require('pump') | ||
var mkdirp = require('mkdirp-classic') | ||
var fs = require('fs') | ||
var path = require('path') | ||
var os = require('os') | ||
const tar = require('tar-stream') | ||
const pump = require('pump') | ||
const mkdirp = require('mkdirp-classic') | ||
const fs = require('fs') | ||
const path = require('path') | ||
var win32 = os.platform() === 'win32' | ||
const win32 = process.platform === 'win32' | ||
var noop = function () {} | ||
var echo = function (name) { | ||
return name | ||
} | ||
var normalize = !win32 ? echo : function (name) { | ||
return name.replace(/\\/g, '/').replace(/[:?<>|]/g, '_') | ||
} | ||
var statAll = function (fs, stat, cwd, ignore, entries, sort) { | ||
var queue = entries || ['.'] | ||
return function loop (callback) { | ||
if (!queue.length) return callback() | ||
var next = queue.shift() | ||
var nextAbs = path.join(cwd, next) | ||
stat.call(fs, nextAbs, function (err, stat) { | ||
if (err) return callback(err) | ||
if (!stat.isDirectory()) return callback(null, next, stat) | ||
fs.readdir(nextAbs, function (err, files) { | ||
if (err) return callback(err) | ||
if (sort) files.sort() | ||
for (var i = 0; i < files.length; i++) { | ||
if (!ignore(path.join(cwd, next, files[i]))) queue.push(path.join(next, files[i])) | ||
} | ||
callback(null, next, stat) | ||
}) | ||
}) | ||
} | ||
} | ||
var strip = function (map, level) { | ||
return function (header) { | ||
header.name = header.name.split('/').slice(level).join('/') | ||
var linkname = header.linkname | ||
if (linkname && (header.type === 'link' || path.isAbsolute(linkname))) { | ||
header.linkname = linkname.split('/').slice(level).join('/') | ||
} | ||
return map(header) | ||
} | ||
} | ||
exports.pack = function (cwd, opts) { | ||
exports.pack = function pack (cwd, opts) { | ||
if (!cwd) cwd = '.' | ||
if (!opts) opts = {} | ||
var xfs = opts.fs || fs | ||
var ignore = opts.ignore || opts.filter || noop | ||
var map = opts.map || noop | ||
var mapStream = opts.mapStream || echo | ||
var statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort) | ||
var strict = opts.strict !== false | ||
var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask() | ||
var dmode = typeof opts.dmode === 'number' ? opts.dmode : 0 | ||
var fmode = typeof opts.fmode === 'number' ? opts.fmode : 0 | ||
var pack = opts.pack || tar.pack() | ||
var finish = opts.finish || noop | ||
const xfs = opts.fs || fs | ||
const ignore = opts.ignore || opts.filter || noop | ||
const mapStream = opts.mapStream || echo | ||
const statNext = statAll(xfs, opts.dereference ? xfs.stat : xfs.lstat, cwd, ignore, opts.entries, opts.sort) | ||
const strict = opts.strict !== false | ||
const umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask() | ||
const pack = opts.pack || tar.pack() | ||
const finish = opts.finish || noop | ||
let map = opts.map || noop | ||
let dmode = typeof opts.dmode === 'number' ? opts.dmode : 0 | ||
let fmode = typeof opts.fmode === 'number' ? opts.fmode : 0 | ||
if (opts.strip) map = strip(map, opts.strip) | ||
@@ -88,3 +37,5 @@ | ||
var onsymlink = function (filename, header) { | ||
onnextentry() | ||
function onsymlink (filename, header) { | ||
xfs.readlink(path.join(cwd, filename), function (err, linkname) { | ||
@@ -97,3 +48,3 @@ if (err) return pack.destroy(err) | ||
var onstat = function (err, filename, stat) { | ||
function onstat (err, filename, stat) { | ||
if (err) return pack.destroy(err) | ||
@@ -107,3 +58,3 @@ if (!filename) { | ||
var header = { | ||
let header = { | ||
name: normalize(filename), | ||
@@ -141,7 +92,5 @@ mode: (stat.mode | (stat.isDirectory() ? dmode : fmode)) & umask, | ||
var entry = pack.entry(header, onnextentry) | ||
if (!entry) return | ||
const entry = pack.entry(header, onnextentry) | ||
const rs = mapStream(xfs.createReadStream(path.join(cwd, filename), { start: 0, end: header.size > 0 ? header.size - 1 : header.size }), header) | ||
var rs = mapStream(xfs.createReadStream(path.join(cwd, filename), { start: 0, end: header.size > 0 ? header.size - 1 : header.size }), header) | ||
rs.on('error', function (err) { // always forward errors on destroy | ||
@@ -154,3 +103,3 @@ entry.destroy(err) | ||
var onnextentry = function (err) { | ||
function onnextentry (err) { | ||
if (err) return pack.destroy(err) | ||
@@ -160,36 +109,35 @@ statNext(onstat) | ||
onnextentry() | ||
return pack | ||
} | ||
var head = function (list) { | ||
function head (list) { | ||
return list.length ? list[list.length - 1] : null | ||
} | ||
var processGetuid = function () { | ||
function processGetuid () { | ||
return process.getuid ? process.getuid() : -1 | ||
} | ||
var processUmask = function () { | ||
function processUmask () { | ||
return process.umask ? process.umask() : 0 | ||
} | ||
exports.extract = function (cwd, opts) { | ||
exports.extract = function extract (cwd, opts) { | ||
if (!cwd) cwd = '.' | ||
if (!opts) opts = {} | ||
var xfs = opts.fs || fs | ||
var ignore = opts.ignore || opts.filter || noop | ||
var map = opts.map || noop | ||
var mapStream = opts.mapStream || echo | ||
var own = opts.chown !== false && !win32 && processGetuid() === 0 | ||
var extract = opts.extract || tar.extract() | ||
var stack = [] | ||
var now = new Date() | ||
var umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask() | ||
var dmode = typeof opts.dmode === 'number' ? opts.dmode : 0 | ||
var fmode = typeof opts.fmode === 'number' ? opts.fmode : 0 | ||
var strict = opts.strict !== false | ||
const xfs = opts.fs || fs | ||
const ignore = opts.ignore || opts.filter || noop | ||
const mapStream = opts.mapStream || echo | ||
const own = opts.chown !== false && !win32 && processGetuid() === 0 | ||
const extract = opts.extract || tar.extract() | ||
const stack = [] | ||
const now = new Date() | ||
const umask = typeof opts.umask === 'number' ? ~opts.umask : ~processUmask() | ||
const strict = opts.strict !== false | ||
let map = opts.map || noop | ||
let dmode = typeof opts.dmode === 'number' ? opts.dmode : 0 | ||
let fmode = typeof opts.fmode === 'number' ? opts.fmode : 0 | ||
if (opts.strip) map = strip(map, opts.strip) | ||
@@ -206,54 +154,62 @@ | ||
var utimesParent = function (name, cb) { // we just set the mtime on the parent dir again everytime we write an entry | ||
var top | ||
while ((top = head(stack)) && name.slice(0, top[0].length) !== top[0]) stack.pop() | ||
if (!top) return cb() | ||
xfs.utimes(top[0], now, top[1], cb) | ||
} | ||
extract.on('entry', onentry) | ||
var utimes = function (name, header, cb) { | ||
if (opts.utimes === false) return cb() | ||
if (opts.finish) extract.on('finish', opts.finish) | ||
if (header.type === 'directory') return xfs.utimes(name, now, header.mtime, cb) | ||
if (header.type === 'symlink') return utimesParent(name, cb) // TODO: how to set mtime on link? | ||
return extract | ||
xfs.utimes(name, now, header.mtime, function (err) { | ||
if (err) return cb(err) | ||
utimesParent(name, cb) | ||
}) | ||
} | ||
function onentry (header, stream, next) { | ||
header = map(header) || header | ||
header.name = normalize(header.name) | ||
var chperm = function (name, header, cb) { | ||
var link = header.type === 'symlink' | ||
const name = path.join(cwd, path.join('/', header.name)) | ||
/* eslint-disable node/no-deprecated-api */ | ||
var chmod = link ? xfs.lchmod : xfs.chmod | ||
var chown = link ? xfs.lchown : xfs.chown | ||
/* eslint-enable node/no-deprecated-api */ | ||
if (ignore(name, header)) { | ||
stream.resume() | ||
return next() | ||
} | ||
if (!chmod) return cb() | ||
if (header.type === 'directory') { | ||
stack.push([name, header.mtime]) | ||
return mkdirfix(name, { | ||
fs: xfs, | ||
own, | ||
uid: header.uid, | ||
gid: header.gid, | ||
mode: header.mode | ||
}, stat) | ||
} | ||
var mode = (header.mode | (header.type === 'directory' ? dmode : fmode)) & umask | ||
const dir = path.dirname(name) | ||
if (chown && own) chown.call(xfs, name, header.uid, header.gid, onchown) | ||
else onchown(null) | ||
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) { | ||
if (err) return next(err) | ||
if (!valid) return next(new Error(dir + ' is not a valid path')) | ||
function onchown (err) { | ||
if (err) return cb(err) | ||
if (!chmod) return cb() | ||
chmod.call(xfs, name, mode, cb) | ||
} | ||
} | ||
mkdirfix(dir, { | ||
fs: xfs, | ||
own, | ||
uid: header.uid, | ||
gid: header.gid, | ||
// normally, the folders with rights and owner should be part of the TAR file | ||
// if this is not the case, create folder for same user as file and with | ||
// standard permissions of 0o755 (rwxr-xr-x) | ||
mode: 0o755 | ||
}, function (err) { | ||
if (err) return next(err) | ||
extract.on('entry', function (header, stream, next) { | ||
header = map(header) || header | ||
header.name = normalize(header.name) | ||
var name = path.join(cwd, path.join('/', header.name)) | ||
switch (header.type) { | ||
case 'file': return onfile() | ||
case 'link': return onlink() | ||
case 'symlink': return onsymlink() | ||
} | ||
if (ignore(name, header)) { | ||
stream.resume() | ||
return next() | ||
} | ||
if (strict) return next(new Error('unsupported type for ' + name + ' (' + header.type + ')')) | ||
var stat = function (err) { | ||
stream.resume() | ||
next() | ||
}) | ||
}) | ||
function stat (err) { | ||
if (err) return next(err) | ||
@@ -267,3 +223,3 @@ utimes(name, header, function (err) { | ||
var onsymlink = function () { | ||
function onsymlink () { | ||
if (win32) return next() // skip symlinks on win for now before it can be tested | ||
@@ -275,6 +231,6 @@ xfs.unlink(name, function () { | ||
var onlink = function () { | ||
function onlink () { | ||
if (win32) return next() // skip links on win for now before it can be tested | ||
xfs.unlink(name, function () { | ||
var srcpath = path.join(cwd, path.join('/', header.linkname)) | ||
const srcpath = path.join(cwd, path.join('/', header.linkname)) | ||
@@ -292,5 +248,5 @@ xfs.link(srcpath, name, function (err) { | ||
var onfile = function () { | ||
var ws = xfs.createWriteStream(name) | ||
var rs = mapStream(stream, header) | ||
function onfile () { | ||
const ws = xfs.createWriteStream(name) | ||
const rs = mapStream(stream, header) | ||
@@ -306,38 +262,57 @@ ws.on('error', function (err) { // always forward errors on destroy | ||
} | ||
} | ||
if (header.type === 'directory') { | ||
stack.push([name, header.mtime]) | ||
return mkdirfix(name, { | ||
fs: xfs, own: own, uid: header.uid, gid: header.gid | ||
}, stat) | ||
} | ||
function utimesParent (name, cb) { // we just set the mtime on the parent dir again everytime we write an entry | ||
let top | ||
while ((top = head(stack)) && name.slice(0, top[0].length) !== top[0]) stack.pop() | ||
if (!top) return cb() | ||
xfs.utimes(top[0], now, top[1], cb) | ||
} | ||
var dir = path.dirname(name) | ||
function utimes (name, header, cb) { | ||
if (opts.utimes === false) return cb() | ||
validate(xfs, dir, path.join(cwd, '.'), function (err, valid) { | ||
if (err) return next(err) | ||
if (!valid) return next(new Error(dir + ' is not a valid path')) | ||
if (header.type === 'directory') return xfs.utimes(name, now, header.mtime, cb) | ||
if (header.type === 'symlink') return utimesParent(name, cb) // TODO: how to set mtime on link? | ||
mkdirfix(dir, { | ||
fs: xfs, own: own, uid: header.uid, gid: header.gid | ||
}, function (err) { | ||
if (err) return next(err) | ||
xfs.utimes(name, now, header.mtime, function (err) { | ||
if (err) return cb(err) | ||
utimesParent(name, cb) | ||
}) | ||
} | ||
switch (header.type) { | ||
case 'file': return onfile() | ||
case 'link': return onlink() | ||
case 'symlink': return onsymlink() | ||
} | ||
function chperm (name, header, cb) { | ||
const link = header.type === 'symlink' | ||
if (strict) return next(new Error('unsupported type for ' + name + ' (' + header.type + ')')) | ||
/* eslint-disable n/no-deprecated-api */ | ||
const chmod = link ? xfs.lchmod : xfs.chmod | ||
const chown = link ? xfs.lchown : xfs.chown | ||
/* eslint-enable n/no-deprecated-api */ | ||
stream.resume() | ||
next() | ||
if (!chmod) return cb() | ||
const mode = (header.mode | (header.type === 'directory' ? dmode : fmode)) & umask | ||
if (chown && own) chown.call(xfs, name, header.uid, header.gid, onchown) | ||
else onchown(null) | ||
function onchown (err) { | ||
if (err) return cb(err) | ||
if (!chmod) return cb() | ||
chmod.call(xfs, name, mode, cb) | ||
} | ||
} | ||
function mkdirfix (name, opts, cb) { | ||
// when mkdir is called on an existing directory, the permissions | ||
// will be overwritten (?), to avoid this we check for its existance first | ||
xfs.stat(name, function (err) { | ||
if (!err) return cb(null) | ||
if (err.code !== 'ENOENT') return cb(err) | ||
mkdirp(name, { fs: opts.fs, mode: opts.mode }, function (err, made) { | ||
if (err) return cb(err) | ||
chperm(name, opts, cb) | ||
}) | ||
}) | ||
}) | ||
if (opts.finish) extract.on('finish', opts.finish) | ||
return extract | ||
} | ||
} | ||
@@ -354,10 +329,53 @@ | ||
function mkdirfix (name, opts, cb) { | ||
mkdirp(name, { fs: opts.fs }, function (err, made) { | ||
if (!err && made && opts.own) { | ||
chownr(made, opts.uid, opts.gid, cb) | ||
} else { | ||
cb(err) | ||
function noop () {} | ||
function echo (name) { | ||
return name | ||
} | ||
function normalize (name) { | ||
return win32 ? name.replace(/\\/g, '/').replace(/[:?<>|]/g, '_') : name | ||
} | ||
function statAll (fs, stat, cwd, ignore, entries, sort) { | ||
const queue = (entries || ['.']).slice(0) | ||
return function loop (callback) { | ||
if (!queue.length) return callback(null) | ||
const next = queue.shift() | ||
const nextAbs = path.join(cwd, next) | ||
stat.call(fs, nextAbs, function (err, stat) { | ||
// ignore errors if the files were deleted while buffering | ||
if (err) return callback(err.code === 'ENOENT' ? null : err) | ||
if (!stat.isDirectory()) return callback(null, next, stat) | ||
fs.readdir(nextAbs, function (err, files) { | ||
if (err) return callback(err) | ||
if (sort) files.sort() | ||
for (let i = 0; i < files.length; i++) { | ||
if (!ignore(path.join(cwd, next, files[i]))) queue.push(path.join(next, files[i])) | ||
} | ||
callback(null, next, stat) | ||
}) | ||
}) | ||
} | ||
} | ||
function strip (map, level) { | ||
return function (header) { | ||
header.name = header.name.split('/').slice(level).join('/') | ||
const linkname = header.linkname | ||
if (linkname && (header.type === 'link' || path.isAbsolute(linkname))) { | ||
header.linkname = linkname.split('/').slice(level).join('/') | ||
} | ||
}) | ||
return map(header) | ||
} | ||
} |
{ | ||
"name": "tar-fs", | ||
"version": "2.1.1", | ||
"version": "3.0.0", | ||
"description": "filesystem bindings for tar-stream", | ||
"dependencies": { | ||
"chownr": "^1.1.1", | ||
"mkdirp-classic": "^0.5.2", | ||
"pump": "^3.0.0", | ||
"tar-stream": "^2.1.4" | ||
"tar-stream": "^3.1.0" | ||
}, | ||
"files": [ | ||
"index.js" | ||
], | ||
"standard": { | ||
"ignore": [ | ||
"test/fixtures/**" | ||
] | ||
}, | ||
"keywords": [ | ||
@@ -20,8 +27,8 @@ "tar", | ||
"devDependencies": { | ||
"brittle": "^3.1.3", | ||
"rimraf": "^2.6.3", | ||
"standard": "^13.0.1", | ||
"tape": "^4.9.2" | ||
"standard": "^17.0.1" | ||
}, | ||
"scripts": { | ||
"test": "standard && tape test/index.js" | ||
"test": "standard && brittle test/index.js" | ||
}, | ||
@@ -28,0 +35,0 @@ "bugs": { |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
3
1
17065
4
292
1
+ Addedb4a@1.6.6(transitive)
+ Addedbare-events@2.2.2(transitive)
+ Addedfast-fifo@1.3.2(transitive)
+ Addedqueue-tick@1.0.1(transitive)
+ Addedstreamx@2.16.1(transitive)
+ Addedtar-stream@3.1.7(transitive)
- Removedchownr@^1.1.1
- Removedbase64-js@1.5.1(transitive)
- Removedbl@4.1.0(transitive)
- Removedbuffer@5.7.1(transitive)
- Removedchownr@1.1.4(transitive)
- Removedfs-constants@1.0.0(transitive)
- Removedieee754@1.2.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedtar-stream@2.2.0(transitive)
- Removedutil-deprecate@1.0.2(transitive)
Updatedtar-stream@^3.1.0