From 5d89de44daa636dc151eaefcafabb357540d35ce Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 11 Aug 2021 09:03:12 -0700 Subject: [PATCH 01/14] tar@6.1.7 * fix: normalize paths on Windows systems --- node_modules/tar/lib/mkdir.js | 97 +++---- .../tar/lib/normalize-windows-path.js | 8 + node_modules/tar/lib/pack.js | 7 +- node_modules/tar/lib/path-reservations.js | 6 +- node_modules/tar/lib/read-entry.js | 7 +- node_modules/tar/lib/replace.js | 3 +- node_modules/tar/lib/unpack.js | 244 ++++++++++++------ node_modules/tar/lib/write-entry.js | 38 ++- node_modules/tar/package.json | 6 +- package-lock.json | 14 +- package.json | 2 +- 11 files changed, 274 insertions(+), 158 deletions(-) create mode 100644 node_modules/tar/lib/normalize-windows-path.js diff --git a/node_modules/tar/lib/mkdir.js b/node_modules/tar/lib/mkdir.js index aed398fcdcd44..a0719e6c36ed3 100644 --- a/node_modules/tar/lib/mkdir.js +++ b/node_modules/tar/lib/mkdir.js @@ -8,6 +8,7 @@ const mkdirp = require('mkdirp') const fs = require('fs') const path = require('path') const chownr = require('chownr') +const normPath = require('./normalize-windows-path.js') class SymlinkError extends Error { constructor (symlink, path) { @@ -33,7 +34,20 @@ class CwdError extends Error { } } +const cGet = (cache, key) => cache.get(normPath(key)) +const cSet = (cache, key, val) => cache.set(normPath(key), val) + +const checkCwd = (dir, cb) => { + fs.stat(dir, (er, st) => { + if (er || !st.isDirectory()) + er = new CwdError(dir, er && er.code || 'ENOTDIR') + cb(er) + }) +} + module.exports = (dir, opt, cb) => { + dir = normPath(dir) + // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -49,13 +63,13 @@ module.exports = (dir, opt, cb) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (er, created) => { if (er) cb(er) else { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr(created, uid, gid, er => done(er)) else if (needChmod) @@ -65,22 +79,17 @@ module.exports = (dir, opt, cb) => { } } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() - if (dir === cwd) { - return fs.stat(dir, (er, st) => { - if (er || !st.isDirectory()) - er = new CwdError(dir, er && er.code || 'ENOTDIR') - done(er) - }) - } + if (dir === cwd) + return checkCwd(dir, done) if (preserve) return mkdirp(dir, {mode}).then(made => done(null, made), done) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) } @@ -88,22 +97,19 @@ const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { if (!parts.length) return cb(null, created) const p = parts.shift() - const part = base + '/' + p - if (cache.get(part)) + const part = normPath(path.resolve(base + '/' + p)) + if (cGet(cache, part)) return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) } const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { if (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return cb(new CwdError(cwd, er.code)) - fs.lstat(part, (statEr, st) => { - if (statEr) + if (statEr) { + statEr.path = statEr.path && normPath(statEr.path) cb(statEr) - else if (st.isDirectory()) + } else if (st.isDirectory()) mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) else if (unlink) { fs.unlink(part, er => { @@ -122,7 +128,21 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { } } +const checkCwdSync = dir => { + let ok = false + let code = 'ENOTDIR' + try { + ok = fs.statSync(dir).isDirectory() + } catch (er) { + code = er.code + } finally { + if (!ok) + throw new CwdError(dir, code) + } +} + module.exports.sync = (dir, opt) => { + dir = normPath(dir) // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -138,64 +158,51 @@ module.exports.sync = (dir, opt) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (created) => { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr.sync(created, uid, gid) if (needChmod) fs.chmodSync(dir, mode) } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() if (dir === cwd) { - let ok = false - let code = 'ENOTDIR' - try { - ok = fs.statSync(dir).isDirectory() - } catch (er) { - code = er.code - } finally { - if (!ok) - throw new CwdError(dir, code) - } - done() - return + checkCwdSync(cwd) + return done() } if (preserve) return done(mkdirp.sync(dir, mode)) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') let created = null for (let p = parts.shift(), part = cwd; p && (part += '/' + p); p = parts.shift()) { - if (cache.get(part)) + part = normPath(path.resolve(part)) + if (cGet(cache, part)) continue try { fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) } catch (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return new CwdError(cwd, er.code) - const st = fs.lstatSync(part) if (st.isDirectory()) { - cache.set(part, true) + cSet(cache, part, true) continue } else if (unlink) { fs.unlinkSync(part) fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) continue } else if (st.isSymbolicLink()) return new SymlinkError(part, part + '/' + parts.join('/')) diff --git a/node_modules/tar/lib/normalize-windows-path.js b/node_modules/tar/lib/normalize-windows-path.js new file mode 100644 index 0000000000000..eb13ba01b7b04 --- /dev/null +++ b/node_modules/tar/lib/normalize-windows-path.js @@ -0,0 +1,8 @@ +// on windows, either \ or / are valid directory separators. +// on unix, \ is a valid character in filenames. +// so, on windows, and only on windows, we replace all \ chars with /, +// so that we can use / as our one and only directory separator char. + +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform +module.exports = platform !== 'win32' ? p => p + : p => p && p.replace(/\\/g, '/') diff --git a/node_modules/tar/lib/pack.js b/node_modules/tar/lib/pack.js index df7f9f1c8df5b..9522c10bfe4a4 100644 --- a/node_modules/tar/lib/pack.js +++ b/node_modules/tar/lib/pack.js @@ -54,6 +54,7 @@ const ONDRAIN = Symbol('ondrain') const fs = require('fs') const path = require('path') const warner = require('./warn-mixin.js') +const normPath = require('./normalize-windows-path.js') const Pack = warner(class Pack extends MiniPass { constructor (opt) { @@ -66,7 +67,7 @@ const Pack = warner(class Pack extends MiniPass { this.preservePaths = !!opt.preservePaths this.strict = !!opt.strict this.noPax = !!opt.noPax - this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '') + this.prefix = normPath(opt.prefix || '') this.linkCache = opt.linkCache || new Map() this.statCache = opt.statCache || new Map() this.readdirCache = opt.readdirCache || new Map() @@ -133,7 +134,7 @@ const Pack = warner(class Pack extends MiniPass { } [ADDTARENTRY] (p) { - const absolute = path.resolve(this.cwd, p.path) + const absolute = normPath(path.resolve(this.cwd, p.path)) // in this case, we don't have to wait for the stat if (!this.filter(p.path, p)) p.resume() @@ -149,7 +150,7 @@ const Pack = warner(class Pack extends MiniPass { } [ADDFSENTRY] (p) { - const absolute = path.resolve(this.cwd, p) + const absolute = normPath(path.resolve(this.cwd, p)) this[QUEUE].push(new PackJob(p, absolute)) this[PROCESS]() } diff --git a/node_modules/tar/lib/path-reservations.js b/node_modules/tar/lib/path-reservations.js index c0a16b0a1f901..1929ac9c2099f 100644 --- a/node_modules/tar/lib/path-reservations.js +++ b/node_modules/tar/lib/path-reservations.js @@ -7,6 +7,7 @@ // while still allowing maximal safe parallelization. const assert = require('assert') +const normPath = require('./normalize-windows-path.js') module.exports = () => { // path => [function or Set] @@ -20,8 +21,9 @@ module.exports = () => { // return a set of parent dirs for a given path const { join } = require('path') const getDirs = path => - join(path).split(/[\\/]/).slice(0, -1).reduce((set, path) => - set.length ? set.concat(join(set[set.length - 1], path)) : [path], []) + normPath(join(path)).split('/').slice(0, -1).reduce((set, path) => + set.length ? set.concat(normPath(join(set[set.length - 1], path))) + : [path], []) // functions currently running const running = new Set() diff --git a/node_modules/tar/lib/read-entry.js b/node_modules/tar/lib/read-entry.js index 6661cba5ff9ef..183a6050ba0d2 100644 --- a/node_modules/tar/lib/read-entry.js +++ b/node_modules/tar/lib/read-entry.js @@ -1,5 +1,6 @@ 'use strict' const MiniPass = require('minipass') +const normPath = require('./normalize-windows-path.js') const SLURP = Symbol('slurp') module.exports = class ReadEntry extends MiniPass { @@ -46,7 +47,7 @@ module.exports = class ReadEntry extends MiniPass { this.ignore = true } - this.path = header.path + this.path = normPath(header.path) this.mode = header.mode if (this.mode) this.mode = this.mode & 0o7777 @@ -58,7 +59,7 @@ module.exports = class ReadEntry extends MiniPass { this.mtime = header.mtime this.atime = header.atime this.ctime = header.ctime - this.linkpath = header.linkpath + this.linkpath = normPath(header.linkpath) this.uname = header.uname this.gname = header.gname @@ -93,7 +94,7 @@ module.exports = class ReadEntry extends MiniPass { // a global extended header, because that's weird. if (ex[k] !== null && ex[k] !== undefined && !(global && k === 'path')) - this[k] = ex[k] + this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k] } } } diff --git a/node_modules/tar/lib/replace.js b/node_modules/tar/lib/replace.js index e5e2a425536d6..1374f3f29c619 100644 --- a/node_modules/tar/lib/replace.js +++ b/node_modules/tar/lib/replace.js @@ -170,7 +170,8 @@ const replace = (opt, files, cb) => { fs.fstat(fd, (er, st) => { if (er) - return reject(er) + return fs.close(fd, () => reject(er)) + getPos(fd, st.size, (er, position) => { if (er) return reject(er) diff --git a/node_modules/tar/lib/unpack.js b/node_modules/tar/lib/unpack.js index 282e04f945c50..3295015952fa1 100644 --- a/node_modules/tar/lib/unpack.js +++ b/node_modules/tar/lib/unpack.js @@ -15,6 +15,7 @@ const mkdir = require('./mkdir.js') const wc = require('./winchars.js') const pathReservations = require('./path-reservations.js') const stripAbsolutePath = require('./strip-absolute-path.js') +const normPath = require('./normalize-windows-path.js') const ONENTRY = Symbol('onEntry') const CHECKFS = Symbol('checkFs') @@ -39,14 +40,10 @@ const SKIP = Symbol('skip') const DOCHOWN = Symbol('doChown') const UID = Symbol('uid') const GID = Symbol('gid') +const CHECKED_CWD = Symbol('checkedCwd') const crypto = require('crypto') const getFlag = require('./get-write-flag.js') -/* istanbul ignore next */ -const neverCalled = () => { - throw new Error('sync function called cb somehow?!?') -} - // Unlinks on Windows are not atomic. // // This means that if you have a file entry, followed by another @@ -91,6 +88,17 @@ const uint32 = (a, b, c) => : b === b >>> 0 ? b : c +const pruneCache = (cache, abs) => { + // clear the cache if it's a case-insensitive match, since we can't + // know if the current file system is case-sensitive or not. + abs = normPath(abs).toLowerCase() + for (const path of cache.keys()) { + const plower = path.toLowerCase() + if (plower === abs || plower.toLowerCase().indexOf(abs + '/') === 0) + cache.delete(path) + } +} + class Unpack extends Parser { constructor (opt) { if (!opt) @@ -103,6 +111,8 @@ class Unpack extends Parser { super(opt) + this[CHECKED_CWD] = false + this.reservations = pathReservations() this.transform = typeof opt.transform === 'function' ? opt.transform : null @@ -168,7 +178,7 @@ class Unpack extends Parser { // links, and removes symlink directories rather than erroring this.unlink = !!opt.unlink - this.cwd = path.resolve(opt.cwd || process.cwd()) + this.cwd = normPath(path.resolve(opt.cwd || process.cwd())) this.strip = +opt.strip || 0 // if we're not chmodding, then we don't need the process umask this.processUmask = opt.noChmod ? 0 : process.umask() @@ -201,23 +211,21 @@ class Unpack extends Parser { [CHECKPATH] (entry) { if (this.strip) { - const parts = entry.path.split(/\/|\\/) + const parts = normPath(entry.path).split('/') if (parts.length < this.strip) return false entry.path = parts.slice(this.strip).join('/') - if (entry.path === '' && entry.type !== 'Directory' && entry.type !== 'GNUDumpDir') - return false if (entry.type === 'Link') { - const linkparts = entry.linkpath.split(/\/|\\/) + const linkparts = normPath(entry.linkpath).split('/') if (linkparts.length >= this.strip) entry.linkpath = linkparts.slice(this.strip).join('/') } } if (!this.preservePaths) { - const p = entry.path - if (p.match(/(^|\/|\\)\.\.(\\|\/|$)/)) { + const p = normPath(entry.path) + if (p.split('/').includes('..')) { this.warn('TAR_ENTRY_ERROR', `path contains '..'`, { entry, path: p, @@ -237,18 +245,26 @@ class Unpack extends Parser { } } + if (path.isAbsolute(entry.path)) + entry.absolute = normPath(path.resolve(entry.path)) + else + entry.absolute = normPath(path.resolve(this.cwd, entry.path)) + + // an archive can set properties on the extraction directory, but it + // may not replace the cwd with a different kind of thing entirely. + if (entry.absolute === this.cwd && + entry.type !== 'Directory' && + entry.type !== 'GNUDumpDir') + return false + // only encode : chars that aren't drive letter indicators if (this.win32) { - const parsed = path.win32.parse(entry.path) - entry.path = parsed.root === '' ? wc.encode(entry.path) - : parsed.root + wc.encode(entry.path.substr(parsed.root.length)) + const { root: aRoot } = path.win32.parse(entry.absolute) + entry.absolute = aRoot + wc.encode(entry.absolute.substr(aRoot.length)) + const { root: pRoot } = path.win32.parse(entry.path) + entry.path = pRoot + wc.encode(entry.path.substr(pRoot.length)) } - if (path.isAbsolute(entry.path)) - entry.absolute = entry.path - else - entry.absolute = path.resolve(this.cwd, entry.path) - return true } @@ -293,7 +309,7 @@ class Unpack extends Parser { } [MKDIR] (dir, mode, cb) { - mkdir(dir, { + mkdir(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, @@ -338,6 +354,7 @@ class Unpack extends Parser { stream.on('error', er => { if (stream.fd) fs.close(stream.fd, () => {}) + // flush all the data out so that we aren't left hanging // if the error wasn't actually fatal. otherwise the parse // is blocked, and we never proceed. @@ -352,6 +369,7 @@ class Unpack extends Parser { /* istanbul ignore else - we should always have a fd by now */ if (stream.fd) fs.close(stream.fd, () => {}) + this[ONERROR](er, entry) fullyDone() return @@ -451,7 +469,8 @@ class Unpack extends Parser { } [HARDLINK] (entry, done) { - this[LINK](entry, path.resolve(this.cwd, entry.linkpath), 'link', done) + const linkpath = normPath(path.resolve(this.cwd, entry.linkpath)) + this[LINK](entry, linkpath, 'link', done) } [PEND] () { @@ -493,41 +512,79 @@ class Unpack extends Parser { // then that means we are about to delete the directory we created // previously, and it is no longer going to be a directory, and neither // is any of its children. - if (entry.type !== 'Directory') { - for (const path of this.dirCache.keys()) { - if (path === entry.absolute || - path.indexOf(entry.absolute + '/') === 0 || - path.indexOf(entry.absolute + '\\') === 0) - this.dirCache.delete(path) - } + if (entry.type !== 'Directory') + pruneCache(this.dirCache, entry.absolute) + + const checkCwd = () => { + this[MKDIR](this.cwd, this.dmode, er => { + if (er) { + this[ONERROR](er, entry) + done() + return + } + this[CHECKED_CWD] = true + start() + }) } - this[MKDIR](path.dirname(entry.absolute), this.dmode, er => { - if (er) { - this[ONERROR](er, entry) - done() - return + const start = () => { + if (entry.absolute !== this.cwd) { + const parent = normPath(path.dirname(entry.absolute)) + if (parent !== this.cwd) { + return this[MKDIR](parent, this.dmode, er => { + if (er) { + this[ONERROR](er, entry) + done() + return + } + afterMakeParent() + }) + } } - fs.lstat(entry.absolute, (er, st) => { + afterMakeParent() + } + + const afterMakeParent = () => { + fs.lstat(entry.absolute, (lstatEr, st) => { if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { this[SKIP](entry) done() - } else if (er || this[ISREUSABLE](entry, st)) - this[MAKEFS](null, entry, done) - else if (st.isDirectory()) { + return + } + if (lstatEr || this[ISREUSABLE](entry, st)) + return this[MAKEFS](null, entry, done) + + if (st.isDirectory()) { if (entry.type === 'Directory') { - if (!this.noChmod && (!entry.mode || (st.mode & 0o7777) === entry.mode)) - this[MAKEFS](null, entry, done) - else { - fs.chmod(entry.absolute, entry.mode, - er => this[MAKEFS](er, entry, done)) - } - } else - fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry, done)) - } else - unlinkFile(entry.absolute, er => this[MAKEFS](er, entry, done)) + const needChmod = !this.noChmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode + const afterChmod = er => this[MAKEFS](er, entry, done) + if (!needChmod) + return afterChmod() + return fs.chmod(entry.absolute, entry.mode, afterChmod) + } + // not a dir entry, have to remove it. + if (entry.absolute !== this.cwd) { + return fs.rmdir(entry.absolute, er => + this[MAKEFS](er, entry, done)) + } + } + + // not a dir, and not reusable + // don't remove if the cwd, we want that error + if (entry.absolute === this.cwd) + return this[MAKEFS](null, entry, done) + + unlinkFile(entry.absolute, er => + this[MAKEFS](er, entry, done)) }) - }) + } + + if (this[CHECKED_CWD]) + start() + else + checkCwd() } [MAKEFS] (er, entry, done) { @@ -556,7 +613,7 @@ class Unpack extends Parser { } [LINK] (entry, linkpath, link, done) { - // XXX: get the type ('file' or 'dir') for windows + // XXX: get the type ('symlink' or 'junction') for windows fs[link](linkpath, entry.absolute, er => { if (er) this[ONERROR](er, entry) @@ -569,44 +626,67 @@ class Unpack extends Parser { } } +const callSync = fn => { + try { + return [null, fn()] + } catch (er) { + return [er, null] + } +} class UnpackSync extends Unpack { + [MAKEFS] (er, entry) { + return super[MAKEFS](er, entry, () => {}) + } + [CHECKFS] (entry) { - if (entry.type !== 'Directory') { - for (const path of this.dirCache.keys()) { - if (path === entry.absolute || - path.indexOf(entry.absolute + '/') === 0 || - path.indexOf(entry.absolute + '\\') === 0) - this.dirCache.delete(path) + if (entry.type !== 'Directory') + pruneCache(this.dirCache, entry.absolute) + + if (!this[CHECKED_CWD]) { + const er = this[MKDIR](this.cwd, this.dmode) + if (er) + return this[ONERROR](er, entry) + this[CHECKED_CWD] = true + } + + // don't bother to make the parent if the current entry is the cwd, + // we've already checked it. + if (entry.absolute !== this.cwd) { + const parent = normPath(path.dirname(entry.absolute)) + if (parent !== this.cwd) { + const mkParent = this[MKDIR](parent, this.dmode) + if (mkParent) + return this[ONERROR](mkParent, entry) } } - const er = this[MKDIR](path.dirname(entry.absolute), this.dmode, neverCalled) - if (er) - return this[ONERROR](er, entry) - try { - const st = fs.lstatSync(entry.absolute) - if (this.keep || this.newer && st.mtime > entry.mtime) - return this[SKIP](entry) - else if (this[ISREUSABLE](entry, st)) - return this[MAKEFS](null, entry, neverCalled) - else { - try { - if (st.isDirectory()) { - if (entry.type === 'Directory') { - if (!this.noChmod && entry.mode && (st.mode & 0o7777) !== entry.mode) - fs.chmodSync(entry.absolute, entry.mode) - } else - fs.rmdirSync(entry.absolute) - } else - unlinkFileSync(entry.absolute) - return this[MAKEFS](null, entry, neverCalled) - } catch (er) { - return this[ONERROR](er, entry) - } + const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute)) + if (st && (this.keep || this.newer && st.mtime > entry.mtime)) + return this[SKIP](entry) + + if (lstatEr || this[ISREUSABLE](entry, st)) + return this[MAKEFS](null, entry) + + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = !this.noChmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode + const [er] = needChmod ? callSync(() => { + fs.chmodSync(entry.absolute, entry.mode) + }) : [] + return this[MAKEFS](er, entry) } - } catch (er) { - return this[MAKEFS](null, entry, neverCalled) + // not a dir entry, have to remove it + const [er] = callSync(() => fs.rmdirSync(entry.absolute)) + this[MAKEFS](er, entry) } + + // not a dir, and not reusable. + // don't remove if it's the cwd, since we want that error. + const [er] = entry.absolute === this.cwd ? [] + : callSync(() => unlinkFileSync(entry.absolute)) + this[MAKEFS](er, entry) } [FILE] (entry, _) { @@ -700,7 +780,7 @@ class UnpackSync extends Unpack { [MKDIR] (dir, mode) { try { - return mkdir.sync(dir, { + return mkdir.sync(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, diff --git a/node_modules/tar/lib/write-entry.js b/node_modules/tar/lib/write-entry.js index 0457f3aefe2a8..3702f2ae51979 100644 --- a/node_modules/tar/lib/write-entry.js +++ b/node_modules/tar/lib/write-entry.js @@ -4,12 +4,14 @@ const Pax = require('./pax.js') const Header = require('./header.js') const fs = require('fs') const path = require('path') +const normPath = require('./normalize-windows-path.js') +const stripSlash = require('./strip-trailing-slashes.js') const prefixPath = (path, prefix) => { if (!prefix) - return path - path = path.replace(/^\.([/\\]|$)/, '') - return prefix + '/' + path + return normPath(path) + path = normPath(path).replace(/^\.(\/|$)/, '') + return stripSlash(prefix) + '/' + path } const maxReadSize = 16 * 1024 * 1024 @@ -31,6 +33,7 @@ const MODE = Symbol('mode') const AWAITDRAIN = Symbol('awaitDrain') const ONDRAIN = Symbol('ondrain') const PREFIX = Symbol('prefix') +const HAD_ERROR = Symbol('hadError') const warner = require('./warn-mixin.js') const winchars = require('./winchars.js') const stripAbsolutePath = require('./strip-absolute-path.js') @@ -43,22 +46,22 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { super(opt) if (typeof p !== 'string') throw new TypeError('path is required') - this.path = p + this.path = normPath(p) // suppress atime, ctime, uid, gid, uname, gname this.portable = !!opt.portable // until node has builtin pwnam functions, this'll have to do - this.myuid = process.getuid && process.getuid() + this.myuid = process.getuid && process.getuid() || 0 this.myuser = process.env.USER || '' this.maxReadSize = opt.maxReadSize || maxReadSize this.linkCache = opt.linkCache || new Map() this.statCache = opt.statCache || new Map() this.preservePaths = !!opt.preservePaths - this.cwd = opt.cwd || process.cwd() + this.cwd = normPath(opt.cwd || process.cwd()) this.strict = !!opt.strict this.noPax = !!opt.noPax this.noMtime = !!opt.noMtime this.mtime = opt.mtime || null - this.prefix = opt.prefix || null + this.prefix = opt.prefix ? normPath(opt.prefix) : null this.fd = null this.blockLen = null @@ -83,11 +86,13 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { this.win32 = !!opt.win32 || process.platform === 'win32' if (this.win32) { + // force the \ to / normalization, since we might not *actually* + // be on windows, but want \ to be considered a path separator. this.path = winchars.decode(this.path.replace(/\\/g, '/')) p = p.replace(/\\/g, '/') } - this.absolute = opt.absolute || path.resolve(this.cwd, p) + this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p)) if (this.path === '') this.path = './' @@ -105,6 +110,12 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { this[LSTAT]() } + emit (ev, ...data) { + if (ev === 'error') + this[HAD_ERROR] = true + return super.emit(ev, ...data) + } + [LSTAT] () { fs.lstat(this.absolute, (er, stat) => { if (er) @@ -201,14 +212,14 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { } [ONREADLINK] (linkpath) { - this.linkpath = linkpath.replace(/\\/g, '/') + this.linkpath = normPath(linkpath) this[HEADER]() this.end() } [HARDLINK] (linkpath) { this.type = 'Link' - this.linkpath = path.relative(this.cwd, linkpath).replace(/\\/g, '/') + this.linkpath = normPath(path.relative(this.cwd, linkpath)) this.stat.size = 0 this[HEADER]() this.end() @@ -242,6 +253,9 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { [ONOPENFILE] (fd) { this.fd = fd + if (this[HAD_ERROR]) + return this[CLOSE]() + this.blockLen = 512 * Math.ceil(this.stat.size / 512) this.blockRemain = this.blockLen const bufLen = Math.min(this.blockLen, this.maxReadSize) @@ -403,7 +417,7 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { this.prefix = opt.prefix || null - this.path = readEntry.path + this.path = normPath(readEntry.path) this.mode = this[MODE](readEntry.mode) this.uid = this.portable ? null : readEntry.uid this.gid = this.portable ? null : readEntry.gid @@ -413,7 +427,7 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime this.atime = this.portable ? null : readEntry.atime this.ctime = this.portable ? null : readEntry.ctime - this.linkpath = readEntry.linkpath + this.linkpath = normPath(readEntry.linkpath) if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json index fbde61edcc51e..c95b771b3bf7c 100644 --- a/node_modules/tar/package.json +++ b/node_modules/tar/package.json @@ -2,13 +2,15 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "tar", "description": "tar for node", - "version": "6.1.6", + "version": "6.1.7", "repository": { "type": "git", "url": "https://github.com/npm/node-tar.git" }, "scripts": { - "test": "tap", + "test:posix": "tap", + "test:win32": "tap --lines=98 --branches=98 --statements=98 --functions=98", + "test": "node test/fixtures/test.js", "posttest": "npm run lint", "eslint": "eslint", "lint": "npm run eslint -- test lib", diff --git a/package-lock.json b/package-lock.json index a7fbf4624c30a..cba9ca968a759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -144,7 +144,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "ssri": "^8.0.1", - "tar": "^6.1.6", + "tar": "^6.1.7", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^1.0.4", @@ -9466,9 +9466,9 @@ } }, "node_modules/tar": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", - "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.7.tgz", + "integrity": "sha512-PBoRkOJU0X3lejJ8GaRCsobjXTgFofRDSPdSUhRSdlwJfifRlQBwGXitDItdGFu0/h0XDMCkig0RN1iT7DBxhA==", "inBundle": true, "dependencies": { "chownr": "^2.0.0", @@ -17412,9 +17412,9 @@ } }, "tar": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", - "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.7.tgz", + "integrity": "sha512-PBoRkOJU0X3lejJ8GaRCsobjXTgFofRDSPdSUhRSdlwJfifRlQBwGXitDItdGFu0/h0XDMCkig0RN1iT7DBxhA==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", diff --git a/package.json b/package.json index 357e066a5efa1..635a275826830 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "ssri": "^8.0.1", - "tar": "^6.1.6", + "tar": "^6.1.7", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^1.0.4", From 9a4753a2b73ea051c5df1e34a9d8c0eaec970996 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 11 Aug 2021 09:07:37 -0700 Subject: [PATCH 02/14] chore(deps): update jsdom eslint-plugin-import eslint All dev deps --- package-lock.json | 108 +++++++++++++++++++++------------------------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/package-lock.json b/package-lock.json index cba9ca968a759..17f4439eee6a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2551,9 +2551,9 @@ } }, "node_modules/eslint": { - "version": "7.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.31.0.tgz", - "integrity": "sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "dependencies": { "@babel/code-frame": "7.12.11", @@ -2608,34 +2608,28 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz", + "integrity": "sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg==", "dev": true, "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "node_modules/eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "dependencies": { "debug": "^3.2.7", @@ -2674,17 +2668,17 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.23.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", - "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz", + "integrity": "sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg==", "dev": true, "dependencies": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.1", + "eslint-import-resolver-node": "^0.3.5", + "eslint-module-utils": "^2.6.2", "find-up": "^2.0.0", "has": "^1.0.3", "is-core-module": "^2.4.0", @@ -4422,9 +4416,9 @@ "inBundle": true }, "node_modules/jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { "abab": "^2.0.5", @@ -4452,7 +4446,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "engines": { @@ -12357,9 +12351,9 @@ } }, "eslint": { - "version": "7.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.31.0.tgz", - "integrity": "sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", @@ -12446,36 +12440,30 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz", + "integrity": "sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "requires": { "debug": "^3.2.7", @@ -12504,17 +12492,17 @@ } }, "eslint-plugin-import": { - "version": "2.23.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", - "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.0.tgz", + "integrity": "sha512-Kc6xqT9hiYi2cgybOc0I2vC9OgAYga5o/rAFinam/yF/t5uBqxQbauNPMC6fgb640T/89P0gFoO27FOilJ/Cqg==", "dev": true, "requires": { "array-includes": "^3.1.3", "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.4", - "eslint-module-utils": "^2.6.1", + "eslint-import-resolver-node": "^0.3.5", + "eslint-module-utils": "^2.6.2", "find-up": "^2.0.0", "has": "^1.0.3", "is-core-module": "^2.4.0", @@ -13700,9 +13688,9 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { "abab": "^2.0.5", @@ -13730,7 +13718,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "dependencies": { From 001f2c1b7e9474049a45709f0e80ee3c474a4ba9 Mon Sep 17 00:00:00 2001 From: AkiJoey Date: Sat, 7 Aug 2021 21:36:25 +0800 Subject: [PATCH 03/14] fix(docs): do not include certain files PR-URL: https://github.com/npm/cli/pull/3621 Credit: @AkiJoey Close: #3621 Reviewed-by: @wraithgar --- docs/content/configuring-npm/package-json.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/content/configuring-npm/package-json.md b/docs/content/configuring-npm/package-json.md index 0fc5dc5075ee3..856adb3366cb0 100644 --- a/docs/content/configuring-npm/package-json.md +++ b/docs/content/configuring-npm/package-json.md @@ -286,12 +286,10 @@ Certain files are always included, regardless of settings: * `package.json` * `README` -* `CHANGES` / `CHANGELOG` / `HISTORY` * `LICENSE` / `LICENCE` -* `NOTICE` * The file in the "main" field -`README`, `CHANGES`, `LICENSE` & `NOTICE` can have any case and extension. +`README` & `LICENSE` can have any case and extension. Conversely, some files are always ignored: From d1812f1a627d6a4d4cb6d07d7735d2d2cc2cf264 Mon Sep 17 00:00:00 2001 From: austincho Date: Sun, 8 Aug 2021 10:40:52 -0700 Subject: [PATCH 04/14] fix(docs): update npm-publish access flag info PR-URL: https://github.com/npm/cli/pull/3630 Credit: @austincho Close: #3630 Reviewed-by: @wraithgar --- docs/content/commands/npm-publish.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/content/commands/npm-publish.md b/docs/content/commands/npm-publish.md index 0d25d7d29da8d..9eb060a78be29 100644 --- a/docs/content/commands/npm-publish.md +++ b/docs/content/commands/npm-publish.md @@ -132,6 +132,11 @@ If you want your scoped package to be publicly viewable (and installable) set `--access=public`. The only valid values for `access` are `public` and `restricted`. Unscoped packages _always_ have an access level of `public`. +Note: Using the `--access` flag on the `npm publish` command will only set +the package access level on the initial publish of the package. Any subsequent `npm publish` +commands using the `--access` flag will not have an effect to the access level. +To make changes to the access level after the initial publish use `npm access`. + #### `dry-run` * Default: false From a1bdbea974ebfc6694b4c8ad5da86215c2924dde Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 22 Jul 2021 07:49:40 -0700 Subject: [PATCH 05/14] deps: remove byte-size In its latest release, byte-size dropped support for node versions lower than 14. The cli currently supports node 10 and up. The actual functionality we needed and was using was extremely limited in scope, and didn't warrant an external module. It's just pretty printing a file size, and the files we are dealing with are limited in size so we don't need to support so many suffixes. PR-URL: https://github.com/npm/cli/pull/3569 Credit: @wraithgar Close: #3569 Reviewed-by: @isaacs --- lib/utils/format-bytes.js | 22 +++++ lib/utils/tar.js | 10 +- lib/view.js | 6 +- node_modules/byte-size/LICENSE | 21 ---- node_modules/byte-size/dist/index.js | 123 ------------------------ node_modules/byte-size/index.mjs | 115 ---------------------- node_modules/byte-size/package.json | 55 ----------- package-lock.json | 16 --- package.json | 2 - tap-snapshots/test/lib/view.js.test.cjs | 26 ++--- test/lib/utils/tar.js | 4 + 11 files changed, 47 insertions(+), 353 deletions(-) create mode 100644 lib/utils/format-bytes.js delete mode 100644 node_modules/byte-size/LICENSE delete mode 100644 node_modules/byte-size/dist/index.js delete mode 100644 node_modules/byte-size/index.mjs delete mode 100644 node_modules/byte-size/package.json diff --git a/lib/utils/format-bytes.js b/lib/utils/format-bytes.js new file mode 100644 index 0000000000000..87fb561aabef1 --- /dev/null +++ b/lib/utils/format-bytes.js @@ -0,0 +1,22 @@ +// Convert bytes to printable output, for file reporting in tarballs +// Only supports up to GB because that's way larger than anything the registry +// supports anyways. + +const formatBytes = (bytes, space = true) => { + let spacer = '' + if (space) + spacer = ' ' + + if (bytes < 1000) // B + return `${bytes}${spacer}B` + + if (bytes < 1000000) // kB + return `${(bytes / 1000).toFixed(1)}${spacer}kB` + + if (bytes < 1000000000) // MB + return `${(bytes / 1000000).toFixed(1)}${spacer}MB` + + return `${(bytes / 1000000000).toFixed(1)}${spacer}GB` +} + +module.exports = formatBytes diff --git a/lib/utils/tar.js b/lib/utils/tar.js index 9e7c3329530ee..c3071c1bd47a5 100644 --- a/lib/utils/tar.js +++ b/lib/utils/tar.js @@ -1,7 +1,7 @@ const tar = require('tar') const ssri = require('ssri') const npmlog = require('npmlog') -const byteSize = require('byte-size') +const formatBytes = require('./format-bytes.js') const columnify = require('columnify') const logTar = (tarball, opts = {}) => { @@ -11,9 +11,9 @@ const logTar = (tarball, opts = {}) => { log.notice('=== Tarball Contents ===') if (tarball.files.length) { log.notice('', columnify(tarball.files.map((f) => { - const bytes = byteSize(f.size) + const bytes = formatBytes(f.size, false) return (/^node_modules\//.test(f.path)) ? null - : { path: f.path, size: `${bytes.value}${bytes.unit}` } + : { path: f.path, size: `${bytes}` } }).filter(f => f), { include: ['size', 'path'], showHeaders: false, @@ -28,8 +28,8 @@ const logTar = (tarball, opts = {}) => { { name: 'name:', value: tarball.name }, { name: 'version:', value: tarball.version }, tarball.filename && { name: 'filename:', value: tarball.filename }, - { name: 'package size:', value: byteSize(tarball.size) }, - { name: 'unpacked size:', value: byteSize(tarball.unpackedSize) }, + { name: 'package size:', value: formatBytes(tarball.size) }, + { name: 'unpacked size:', value: formatBytes(tarball.unpackedSize) }, { name: 'shasum:', value: tarball.shasum }, { name: 'integrity:', diff --git a/lib/view.js b/lib/view.js index 47e631f5565c0..f4fc5974eeeca 100644 --- a/lib/view.js +++ b/lib/view.js @@ -1,6 +1,5 @@ // npm view [pkg [pkg ...]] -const byteSize = require('byte-size') const color = require('ansicolors') const columns = require('cli-columns') const fs = require('fs') @@ -8,6 +7,7 @@ const jsonParse = require('json-parse-even-better-errors') const log = require('npmlog') const npa = require('npm-package-arg') const { resolve } = require('path') +const formatBytes = require('./utils/format-bytes.js') const relativeDate = require('tiny-relative-date') const semver = require('semver') const style = require('ansistyles') @@ -315,7 +315,7 @@ class View extends BaseCommand { tags.push(`${style.bright(color.green(t))}: ${version}`) }) const unpackedSize = manifest.dist.unpackedSize && - byteSize(manifest.dist.unpackedSize) + formatBytes(manifest.dist.unpackedSize, true) const licenseField = manifest.license || 'Proprietary' const info = { name: color.green(manifest.name), @@ -356,7 +356,7 @@ class View extends BaseCommand { manifest.dist.integrity && color.yellow(manifest.dist.integrity), fileCount: manifest.dist.fileCount && color.yellow(manifest.dist.fileCount), - unpackedSize: unpackedSize && color.yellow(unpackedSize.value) + ' ' + unpackedSize.unit, + unpackedSize: unpackedSize && color.yellow(unpackedSize), } if (info.license.toLowerCase().trim() === 'proprietary') info.license = style.bright(color.red(info.license)) diff --git a/node_modules/byte-size/LICENSE b/node_modules/byte-size/LICENSE deleted file mode 100644 index 5699dfbe51830..0000000000000 --- a/node_modules/byte-size/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-21 Lloyd Brookes <75pound@gmail.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/node_modules/byte-size/dist/index.js b/node_modules/byte-size/dist/index.js deleted file mode 100644 index dd1debda59abd..0000000000000 --- a/node_modules/byte-size/dist/index.js +++ /dev/null @@ -1,123 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.byteSize = factory()); -}(this, (function () { 'use strict'; - - /** - * @module byte-size - */ - - let defaultOptions = {}; - const _options = new WeakMap(); - - class ByteSize { - constructor (bytes, options) { - options = Object.assign({ - units: 'metric', - precision: 1 - }, defaultOptions, options); - _options.set(this, options); - - const tables = { - metric: [ - { from: 0 , to: 1e3 , unit: 'B' , long: 'bytes' }, - { from: 1e3 , to: 1e6 , unit: 'kB', long: 'kilobytes' }, - { from: 1e6 , to: 1e9 , unit: 'MB', long: 'megabytes' }, - { from: 1e9 , to: 1e12, unit: 'GB', long: 'gigabytes' }, - { from: 1e12, to: 1e15, unit: 'TB', long: 'terabytes' }, - { from: 1e15, to: 1e18, unit: 'PB', long: 'petabytes' }, - { from: 1e18, to: 1e21, unit: 'EB', long: 'exabytes' }, - { from: 1e21, to: 1e24, unit: 'ZB', long: 'zettabytes' }, - { from: 1e24, to: 1e27, unit: 'YB', long: 'yottabytes' }, - ], - metric_octet: [ - { from: 0 , to: 1e3 , unit: 'o' , long: 'octets' }, - { from: 1e3 , to: 1e6 , unit: 'ko', long: 'kilooctets' }, - { from: 1e6 , to: 1e9 , unit: 'Mo', long: 'megaoctets' }, - { from: 1e9 , to: 1e12, unit: 'Go', long: 'gigaoctets' }, - { from: 1e12, to: 1e15, unit: 'To', long: 'teraoctets' }, - { from: 1e15, to: 1e18, unit: 'Po', long: 'petaoctets' }, - { from: 1e18, to: 1e21, unit: 'Eo', long: 'exaoctets' }, - { from: 1e21, to: 1e24, unit: 'Zo', long: 'zettaoctets' }, - { from: 1e24, to: 1e27, unit: 'Yo', long: 'yottaoctets' }, - ], - iec: [ - { from: 0 , to: Math.pow(1024, 1), unit: 'B' , long: 'bytes' }, - { from: Math.pow(1024, 1), to: Math.pow(1024, 2), unit: 'KiB', long: 'kibibytes' }, - { from: Math.pow(1024, 2), to: Math.pow(1024, 3), unit: 'MiB', long: 'mebibytes' }, - { from: Math.pow(1024, 3), to: Math.pow(1024, 4), unit: 'GiB', long: 'gibibytes' }, - { from: Math.pow(1024, 4), to: Math.pow(1024, 5), unit: 'TiB', long: 'tebibytes' }, - { from: Math.pow(1024, 5), to: Math.pow(1024, 6), unit: 'PiB', long: 'pebibytes' }, - { from: Math.pow(1024, 6), to: Math.pow(1024, 7), unit: 'EiB', long: 'exbibytes' }, - { from: Math.pow(1024, 7), to: Math.pow(1024, 8), unit: 'ZiB', long: 'zebibytes' }, - { from: Math.pow(1024, 8), to: Math.pow(1024, 9), unit: 'YiB', long: 'yobibytes' }, - ], - iec_octet: [ - { from: 0 , to: Math.pow(1024, 1), unit: 'o' , long: 'octets' }, - { from: Math.pow(1024, 1), to: Math.pow(1024, 2), unit: 'Kio', long: 'kibioctets' }, - { from: Math.pow(1024, 2), to: Math.pow(1024, 3), unit: 'Mio', long: 'mebioctets' }, - { from: Math.pow(1024, 3), to: Math.pow(1024, 4), unit: 'Gio', long: 'gibioctets' }, - { from: Math.pow(1024, 4), to: Math.pow(1024, 5), unit: 'Tio', long: 'tebioctets' }, - { from: Math.pow(1024, 5), to: Math.pow(1024, 6), unit: 'Pio', long: 'pebioctets' }, - { from: Math.pow(1024, 6), to: Math.pow(1024, 7), unit: 'Eio', long: 'exbioctets' }, - { from: Math.pow(1024, 7), to: Math.pow(1024, 8), unit: 'Zio', long: 'zebioctets' }, - { from: Math.pow(1024, 8), to: Math.pow(1024, 9), unit: 'Yio', long: 'yobioctets' }, - ], - }; - Object.assign(tables, options.customUnits); - - const prefix = bytes < 0 ? '-' : ''; - bytes = Math.abs(bytes); - const table = tables[options.units]; - if (table) { - const units = table.find(u => bytes >= u.from && bytes < u.to); - if (units) { - const value = units.from === 0 - ? prefix + bytes - : prefix + (bytes / units.from).toFixed(options.precision); - this.value = value; - this.unit = units.unit; - this.long = units.long; - } else { - this.value = prefix + bytes; - this.unit = ''; - this.long = ''; - } - } else { - throw new Error(`Invalid units specified: ${options.units}`) - } - } - - toString () { - const options = _options.get(this); - return options.toStringFn ? options.toStringFn.bind(this)() : `${this.value} ${this.unit}` - } - } - - /** - * Returns an object with the spec `{ value: string, unit: string, long: string }`. The returned object defines a `toString` method meaning it can be used in any string context. - * @param {number} - The bytes value to convert. - * @param [options] {object} - Optional config. - * @param [options.precision] {number} - Number of decimal places. Defaults to `1`. - * @param [options.units] {string} - Specify `'metric'`, `'iec'`, `'metric_octet'`, `'iec_octet'` or the name of a property from the custom units table in `options.customUnits`. Defaults to `metric`. - * @param [options.customUnits] {object} - An object containing one or more custom unit lookup tables. - * @param [options.toStringFn] {function} - A `toString` function to override the default. - * @returns {object} - * @alias module:byte-size - */ - function byteSize (bytes, options) { - return new ByteSize(bytes, options) - } - - /** - * Set the default `byteSize` options for the duration of the process. - * @param options {object} - A `byteSize` options object. - */ - byteSize.defaultOptions = function (options) { - defaultOptions = options; - }; - - return byteSize; - -}))); diff --git a/node_modules/byte-size/index.mjs b/node_modules/byte-size/index.mjs deleted file mode 100644 index bd6548c686aa5..0000000000000 --- a/node_modules/byte-size/index.mjs +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @module byte-size - */ - -let defaultOptions = {} -const _options = new WeakMap() - -class ByteSize { - constructor (bytes, options) { - options = Object.assign({ - units: 'metric', - precision: 1 - }, defaultOptions, options) - _options.set(this, options) - - const tables = { - metric: [ - { from: 0 , to: 1e3 , unit: 'B' , long: 'bytes' }, - { from: 1e3 , to: 1e6 , unit: 'kB', long: 'kilobytes' }, - { from: 1e6 , to: 1e9 , unit: 'MB', long: 'megabytes' }, - { from: 1e9 , to: 1e12, unit: 'GB', long: 'gigabytes' }, - { from: 1e12, to: 1e15, unit: 'TB', long: 'terabytes' }, - { from: 1e15, to: 1e18, unit: 'PB', long: 'petabytes' }, - { from: 1e18, to: 1e21, unit: 'EB', long: 'exabytes' }, - { from: 1e21, to: 1e24, unit: 'ZB', long: 'zettabytes' }, - { from: 1e24, to: 1e27, unit: 'YB', long: 'yottabytes' }, - ], - metric_octet: [ - { from: 0 , to: 1e3 , unit: 'o' , long: 'octets' }, - { from: 1e3 , to: 1e6 , unit: 'ko', long: 'kilooctets' }, - { from: 1e6 , to: 1e9 , unit: 'Mo', long: 'megaoctets' }, - { from: 1e9 , to: 1e12, unit: 'Go', long: 'gigaoctets' }, - { from: 1e12, to: 1e15, unit: 'To', long: 'teraoctets' }, - { from: 1e15, to: 1e18, unit: 'Po', long: 'petaoctets' }, - { from: 1e18, to: 1e21, unit: 'Eo', long: 'exaoctets' }, - { from: 1e21, to: 1e24, unit: 'Zo', long: 'zettaoctets' }, - { from: 1e24, to: 1e27, unit: 'Yo', long: 'yottaoctets' }, - ], - iec: [ - { from: 0 , to: Math.pow(1024, 1), unit: 'B' , long: 'bytes' }, - { from: Math.pow(1024, 1), to: Math.pow(1024, 2), unit: 'KiB', long: 'kibibytes' }, - { from: Math.pow(1024, 2), to: Math.pow(1024, 3), unit: 'MiB', long: 'mebibytes' }, - { from: Math.pow(1024, 3), to: Math.pow(1024, 4), unit: 'GiB', long: 'gibibytes' }, - { from: Math.pow(1024, 4), to: Math.pow(1024, 5), unit: 'TiB', long: 'tebibytes' }, - { from: Math.pow(1024, 5), to: Math.pow(1024, 6), unit: 'PiB', long: 'pebibytes' }, - { from: Math.pow(1024, 6), to: Math.pow(1024, 7), unit: 'EiB', long: 'exbibytes' }, - { from: Math.pow(1024, 7), to: Math.pow(1024, 8), unit: 'ZiB', long: 'zebibytes' }, - { from: Math.pow(1024, 8), to: Math.pow(1024, 9), unit: 'YiB', long: 'yobibytes' }, - ], - iec_octet: [ - { from: 0 , to: Math.pow(1024, 1), unit: 'o' , long: 'octets' }, - { from: Math.pow(1024, 1), to: Math.pow(1024, 2), unit: 'Kio', long: 'kibioctets' }, - { from: Math.pow(1024, 2), to: Math.pow(1024, 3), unit: 'Mio', long: 'mebioctets' }, - { from: Math.pow(1024, 3), to: Math.pow(1024, 4), unit: 'Gio', long: 'gibioctets' }, - { from: Math.pow(1024, 4), to: Math.pow(1024, 5), unit: 'Tio', long: 'tebioctets' }, - { from: Math.pow(1024, 5), to: Math.pow(1024, 6), unit: 'Pio', long: 'pebioctets' }, - { from: Math.pow(1024, 6), to: Math.pow(1024, 7), unit: 'Eio', long: 'exbioctets' }, - { from: Math.pow(1024, 7), to: Math.pow(1024, 8), unit: 'Zio', long: 'zebioctets' }, - { from: Math.pow(1024, 8), to: Math.pow(1024, 9), unit: 'Yio', long: 'yobioctets' }, - ], - } - Object.assign(tables, options.customUnits) - - const prefix = bytes < 0 ? '-' : '' - bytes = Math.abs(bytes) - const table = tables[options.units] - if (table) { - const units = table.find(u => bytes >= u.from && bytes < u.to) - if (units) { - const value = units.from === 0 - ? prefix + bytes - : prefix + (bytes / units.from).toFixed(options.precision) - this.value = value - this.unit = units.unit - this.long = units.long - } else { - this.value = prefix + bytes - this.unit = '' - this.long = '' - } - } else { - throw new Error(`Invalid units specified: ${options.units}`) - } - } - - toString () { - const options = _options.get(this) - return options.toStringFn ? options.toStringFn.bind(this)() : `${this.value} ${this.unit}` - } -} - -/** - * Returns an object with the spec `{ value: string, unit: string, long: string }`. The returned object defines a `toString` method meaning it can be used in any string context. - * @param {number} - The bytes value to convert. - * @param [options] {object} - Optional config. - * @param [options.precision] {number} - Number of decimal places. Defaults to `1`. - * @param [options.units] {string} - Specify `'metric'`, `'iec'`, `'metric_octet'`, `'iec_octet'` or the name of a property from the custom units table in `options.customUnits`. Defaults to `metric`. - * @param [options.customUnits] {object} - An object containing one or more custom unit lookup tables. - * @param [options.toStringFn] {function} - A `toString` function to override the default. - * @returns {object} - * @alias module:byte-size - */ -function byteSize (bytes, options) { - return new ByteSize(bytes, options) -} - -/** - * Set the default `byteSize` options for the duration of the process. - * @param options {object} - A `byteSize` options object. - */ -byteSize.defaultOptions = function (options) { - defaultOptions = options -} - -export default byteSize diff --git a/node_modules/byte-size/package.json b/node_modules/byte-size/package.json deleted file mode 100644 index b5f454592da10..0000000000000 --- a/node_modules/byte-size/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "byte-size", - "author": "Lloyd Brookes <75pound@gmail.com>", - "contributors": [ - { - "name": "Raul Perez", - "email": "repejota@gmail.com", - "url": "http://repejota.com" - } - ], - "version": "7.0.1", - "main": "dist/index.js", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "description": "Convert a bytes or octets value (e.g. 34565346) to a human-readable string ('34.6 MB'). Choose between metric or IEC units.", - "repository": "https://github.com/75lb/byte-size", - "files": [ - "index.mjs", - "dist/index.js" - ], - "keywords": [ - "convert", - "bytes", - "octet", - "size", - "human", - "readable", - "metric", - "IEC" - ], - "scripts": { - "test": "npm run dist && npm run test:esm && npm run test:web", - "test:esm": "esm-runner test.mjs", - "test:web": "web-runner test.mjs", - "docs": "jsdoc2md -t README.hbs dist/index.js > README.md", - "cover": "c8 npm test && c8 report --reporter=text-lcov | coveralls", - "dist": "rollup -f umd -n byteSize -o dist/index.js index.mjs" - }, - "devDependencies": { - "@test-runner/web": "^0.3.5", - "coveralls": "^3.1.0", - "esm-runner": "^0.3.4", - "isomorphic-assert": "^0.1.1", - "jsdoc-to-markdown": "^7.0.0", - "rollup": "^2.40.0", - "test-object-model": "^0.6.1" - }, - "standard": { - "ignore": [ - "dist" - ] - } -} diff --git a/package-lock.json b/package-lock.json index 17f4439eee6a7..9288f9a98bfe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "ansicolors", "ansistyles", "archy", - "byte-size", "cacache", "chalk", "chownr", @@ -92,7 +91,6 @@ "ansicolors": "~0.3.2", "ansistyles": "~0.1.3", "archy": "~1.0.0", - "byte-size": "^7.0.1", "cacache": "^15.2.0", "chalk": "^4.1.2", "chownr": "^2.0.0", @@ -1528,15 +1526,6 @@ "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", "inBundle": true }, - "node_modules/byte-size": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz", - "integrity": "sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==", - "inBundle": true, - "engines": { - "node": ">=10" - } - }, "node_modules/cacache": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", @@ -11593,11 +11582,6 @@ "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" }, - "byte-size": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-7.0.1.tgz", - "integrity": "sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==" - }, "cacache": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.2.0.tgz", diff --git a/package.json b/package.json index 635a275826830..8ae29c538427f 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "ansicolors": "~0.3.2", "ansistyles": "~0.1.3", "archy": "~1.0.0", - "byte-size": "^7.0.1", "cacache": "^15.2.0", "chalk": "^4.1.2", "chownr": "^2.0.0", @@ -132,7 +131,6 @@ "ansicolors", "ansistyles", "archy", - "byte-size", "cacache", "chalk", "chownr", diff --git a/tap-snapshots/test/lib/view.js.test.cjs b/tap-snapshots/test/lib/view.js.test.cjs index 41d7a80fe3b16..27ba7b1eb6927 100644 --- a/tap-snapshots/test/lib/view.js.test.cjs +++ b/tap-snapshots/test/lib/view.js.test.cjs @@ -77,7 +77,7 @@ dist .tarball:http://hm.blue.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -94,7 +94,7 @@ dist .tarball:http://hm.blue.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -118,7 +118,7 @@ dist .tarball:http://hm.green.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dependencies: red: 1.0.0 @@ -178,7 +178,7 @@ dist .tarball:http://hm.orange.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -200,7 +200,7 @@ dist .tarball:http://hm.green.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dependencies: red: 1.0.0 @@ -223,7 +223,7 @@ dist .tarball:http://hm.pink.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -238,7 +238,7 @@ dist .tarball:http://hm.black.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dependencies: 0: 1.0.0 @@ -280,7 +280,7 @@ dist .tarball:http://hm.cyan.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -297,7 +297,7 @@ dist .tarball:http://hm.blue.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -401,7 +401,7 @@ dist .tarball:http://hm.green.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dependencies: red: 1.0.0 @@ -421,7 +421,7 @@ dist .tarball:http://hm.orange.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 @@ -469,7 +469,7 @@ dist .tarball:http://hm.green.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dependencies: red: 1.0.0 @@ -496,7 +496,7 @@ dist .tarball:http://hm.pink.com/1.0.0.tgz .shasum:123 .integrity:--- -.unpackedSize:1 B +.unpackedSize:1 B dist-tags: latest: 1.0.0 diff --git a/test/lib/utils/tar.js b/test/lib/utils/tar.js index 2662d47ace486..19d94916945db 100644 --- a/test/lib/utils/tar.js +++ b/test/lib/utils/tar.js @@ -57,6 +57,8 @@ t.test('should log tarball contents with unicode', async (t) => { logTar({ files: [], bundled: [], + size: 0, + unpackedSize: 0, integrity: '', }, { unicode: true }) t.end() @@ -75,6 +77,8 @@ t.test('should default to npmlog', async (t) => { logTar({ files: [], bundled: [], + size: 0, + unpackedSize: 0, integrity: '', }) t.end() From 61782fa858c278455ce144f975c6b0e3ea2d9944 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 11 Aug 2021 10:35:10 -0700 Subject: [PATCH 06/14] @npmcli/map-workspaces@1.0.4 * fix: better error message for duplicate workspace names --- node_modules/@npmcli/map-workspaces/index.js | 7 ++++++- node_modules/@npmcli/map-workspaces/package.json | 2 +- package-lock.json | 13 +++++++------ package.json | 1 + 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/node_modules/@npmcli/map-workspaces/index.js b/node_modules/@npmcli/map-workspaces/index.js index b06662154a83a..7587db717f362 100644 --- a/node_modules/@npmcli/map-workspaces/index.js +++ b/node_modules/@npmcli/map-workspaces/index.js @@ -129,7 +129,12 @@ async function mapWorkspaces (opts = {}) { if (seen.has(name) && seen.get(name) !== packagePathname) { throw getError({ Type: Error, - message: 'must not have multiple workspaces with the same name', + message: [ + 'must not have multiple workspaces with the same name', + `package '${name}' has conflicts in the following paths:`, + ' ' + seen.get(name), + ' ' + packagePathname + ].join('\n'), code: 'EDUPLICATEWORKSPACE' }) } diff --git a/node_modules/@npmcli/map-workspaces/package.json b/node_modules/@npmcli/map-workspaces/package.json index 2445c12f9c308..17cc4197e9e2b 100644 --- a/node_modules/@npmcli/map-workspaces/package.json +++ b/node_modules/@npmcli/map-workspaces/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/map-workspaces", - "version": "1.0.3", + "version": "1.0.4", "files": [ "index.js" ], diff --git a/package-lock.json b/package-lock.json index 9288f9a98bfe7..4d27861d14a52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -85,6 +85,7 @@ "@npmcli/arborist": "^2.8.0", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.2.0", + "@npmcli/map-workspaces": "^1.0.4", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^1.8.5", "abbrev": "~1.1.1", @@ -865,9 +866,9 @@ } }, "node_modules/@npmcli/map-workspaces": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.3.tgz", - "integrity": "sha512-SdlRlOoQw4WKD4vtb/n5gUkobEABYBEOo8fRE4L8CtBkyWDSvIrReTfKvQ/Jc/LQqDaaZ5iv1iMSQzKCUr1n1A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.4.tgz", + "integrity": "sha512-wVR8QxhyXsFcD/cORtJwGQodeeaDf0OxcHie8ema4VgFeqwYkFsDPnSrIRSytX8xR6nKPAH89WnwTcaU608b/Q==", "inBundle": true, "dependencies": { "@npmcli/name-from-folder": "^1.0.1", @@ -11083,9 +11084,9 @@ } }, "@npmcli/map-workspaces": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.3.tgz", - "integrity": "sha512-SdlRlOoQw4WKD4vtb/n5gUkobEABYBEOo8fRE4L8CtBkyWDSvIrReTfKvQ/Jc/LQqDaaZ5iv1iMSQzKCUr1n1A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-1.0.4.tgz", + "integrity": "sha512-wVR8QxhyXsFcD/cORtJwGQodeeaDf0OxcHie8ema4VgFeqwYkFsDPnSrIRSytX8xR6nKPAH89WnwTcaU608b/Q==", "requires": { "@npmcli/name-from-folder": "^1.0.1", "glob": "^7.1.6", diff --git a/package.json b/package.json index 8ae29c538427f..bda2982e8444f 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@npmcli/arborist": "^2.8.0", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.2.0", + "@npmcli/map-workspaces": "^1.0.4", "@npmcli/package-json": "^1.0.1", "@npmcli/run-script": "^1.8.5", "abbrev": "~1.1.1", From d5a099c7bf62977a5a5d8242c61f323a88e27c73 Mon Sep 17 00:00:00 2001 From: Yash Singh Date: Thu, 5 Aug 2021 14:22:56 -0700 Subject: [PATCH 07/14] fix(readme): add nvm-windows to installers links PR-URL: https://github.com/npm/cli/pull/3615 Credit: @Yash-Singh1 Close: #3615 Reviewed-by: @wraithgar --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 01de9e8f69445..822cdecc29294 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ If you're looking to manage multiple versions of **`node`** &/or **`npm`**, cons * [**`volta`**](https://github.com/volta-cli/volta) * [**`nodenv`**](https://github.com/nodenv/nodenv) * [**`asdf-nodejs`**](https://github.com/asdf-vm/asdf-nodejs) +* [**`nvm-windows`**](https://github.com/coreybutler/nvm-windows) ### Usage From 47a3d1805021f675afe523c4b7eebda4ade6e790 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 11 Aug 2021 10:53:45 -0700 Subject: [PATCH 08/14] fix(package): add map-workspaces to bundleDependencies --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index bda2982e8444f..c64238146aa25 100644 --- a/package.json +++ b/package.json @@ -126,6 +126,7 @@ "@npmcli/arborist", "@npmcli/ci-detect", "@npmcli/config", + "@npmcli/map-workspaces", "@npmcli/package-json", "@npmcli/run-script", "abbrev", From 5bebf280f228e818524f6989caab1cfba1ffaf90 Mon Sep 17 00:00:00 2001 From: Gar Date: Wed, 11 Aug 2021 12:37:10 -0700 Subject: [PATCH 09/14] tar@6.1.8 --- node_modules/tar/lib/path-reservations.js | 5 +++-- node_modules/tar/lib/unpack.js | 2 ++ node_modules/tar/package.json | 2 +- package-lock.json | 15 ++++++++------- package.json | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/node_modules/tar/lib/path-reservations.js b/node_modules/tar/lib/path-reservations.js index 1929ac9c2099f..167447af08057 100644 --- a/node_modules/tar/lib/path-reservations.js +++ b/node_modules/tar/lib/path-reservations.js @@ -8,6 +8,7 @@ const assert = require('assert') const normPath = require('./normalize-windows-path.js') +const { join } = require('path') module.exports = () => { // path => [function or Set] @@ -19,9 +20,8 @@ module.exports = () => { const reservations = new Map() // return a set of parent dirs for a given path - const { join } = require('path') const getDirs = path => - normPath(join(path)).split('/').slice(0, -1).reduce((set, path) => + path.split('/').slice(0, -1).reduce((set, path) => set.length ? set.concat(normPath(join(set[set.length - 1], path))) : [path], []) @@ -99,6 +99,7 @@ module.exports = () => { } const reserve = (paths, fn) => { + paths = paths.map(p => normPath(join(p)).toLowerCase()) const dirs = new Set( paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b)) ) diff --git a/node_modules/tar/lib/unpack.js b/node_modules/tar/lib/unpack.js index 3295015952fa1..cf10d07347b69 100644 --- a/node_modules/tar/lib/unpack.js +++ b/node_modules/tar/lib/unpack.js @@ -220,6 +220,8 @@ class Unpack extends Parser { const linkparts = normPath(entry.linkpath).split('/') if (linkparts.length >= this.strip) entry.linkpath = linkparts.slice(this.strip).join('/') + else + return false } } diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json index c95b771b3bf7c..42f55d0356ca4 100644 --- a/node_modules/tar/package.json +++ b/node_modules/tar/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "tar", "description": "tar for node", - "version": "6.1.7", + "version": "6.1.8", "repository": { "type": "git", "url": "https://github.com/npm/node-tar.git" diff --git a/package-lock.json b/package-lock.json index 4d27861d14a52..8e352377b1c1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@npmcli/arborist", "@npmcli/ci-detect", "@npmcli/config", + "@npmcli/map-workspaces", "@npmcli/package-json", "@npmcli/run-script", "abbrev", @@ -143,7 +144,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "ssri": "^8.0.1", - "tar": "^6.1.7", + "tar": "^6.1.8", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^1.0.4", @@ -9450,9 +9451,9 @@ } }, "node_modules/tar": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.7.tgz", - "integrity": "sha512-PBoRkOJU0X3lejJ8GaRCsobjXTgFofRDSPdSUhRSdlwJfifRlQBwGXitDItdGFu0/h0XDMCkig0RN1iT7DBxhA==", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.8.tgz", + "integrity": "sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A==", "inBundle": true, "dependencies": { "chownr": "^2.0.0", @@ -17385,9 +17386,9 @@ } }, "tar": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.7.tgz", - "integrity": "sha512-PBoRkOJU0X3lejJ8GaRCsobjXTgFofRDSPdSUhRSdlwJfifRlQBwGXitDItdGFu0/h0XDMCkig0RN1iT7DBxhA==", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.8.tgz", + "integrity": "sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", diff --git a/package.json b/package.json index c64238146aa25..c426a5ff8a04c 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "ssri": "^8.0.1", - "tar": "^6.1.7", + "tar": "^6.1.8", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^1.0.4", From b88f770faa2651ca0833e1c9eb361e9e07e0bbc3 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 12 Aug 2021 12:14:41 -0700 Subject: [PATCH 10/14] @npmcli/arborist@2.8.1 * [#3632] Fix "cannot read property path of null" error in 'npm dedupe' * fix(shrinkwrap): always set name on the root node --- node_modules/@npmcli/arborist/bin/dedupe.js | 46 +++++++++++++++++++ .../arborist/lib/arborist/build-ideal-tree.js | 11 ----- .../@npmcli/arborist/lib/can-place-dep.js | 19 ++++---- .../@npmcli/arborist/lib/place-dep.js | 17 ++++++- .../@npmcli/arborist/lib/shrinkwrap.js | 6 ++- node_modules/@npmcli/arborist/package.json | 2 +- package-lock.json | 14 +++--- package.json | 2 +- 8 files changed, 83 insertions(+), 34 deletions(-) create mode 100644 node_modules/@npmcli/arborist/bin/dedupe.js diff --git a/node_modules/@npmcli/arborist/bin/dedupe.js b/node_modules/@npmcli/arborist/bin/dedupe.js new file mode 100644 index 0000000000000..96f754e34ca9e --- /dev/null +++ b/node_modules/@npmcli/arborist/bin/dedupe.js @@ -0,0 +1,46 @@ +const Arborist = require('../') + +const options = require('./lib/options.js') +const print = require('./lib/print-tree.js') +require('./lib/logging.js') +require('./lib/timers.js') + +const printDiff = diff => { + const {depth} = require('treeverse') + depth({ + tree: diff, + visit: d => { + if (d.location === '') + return + switch (d.action) { + case 'REMOVE': + console.error('REMOVE', d.actual.location) + break + case 'ADD': + console.error('ADD', d.ideal.location, d.ideal.resolved) + break + case 'CHANGE': + console.error('CHANGE', d.actual.location, { + from: d.actual.resolved, + to: d.ideal.resolved, + }) + break + } + }, + getChildren: d => d.children, + }) +} + +const start = process.hrtime() +process.emit('time', 'install') +const arb = new Arborist(options) +arb.dedupe(options).then(tree => { + process.emit('timeEnd', 'install') + const end = process.hrtime(start) + print(tree) + if (options.dryRun) + printDiff(arb.diff) + console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`) + if (tree.meta && options.save) + tree.meta.save() +}).catch(er => console.error(require('util').inspect(er, { depth: Infinity }))) diff --git a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js index 7ef42289d297b..679d52582cb25 100644 --- a/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js +++ b/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js @@ -982,7 +982,6 @@ This is a one-time fix-up, please be patient... // Note that the virtual root will also have virtual copies of the // targets of any child Links, so that they resolve appropriately. const parent = parent_ || this[_virtualRoot](edge.from) - const realParent = edge.peer ? edge.from.resolveParent : edge.from const spec = npa.resolve(edge.name, edge.spec, edge.from.path) const first = await this[_nodeFromSpec](edge.name, spec, parent, edge) @@ -1013,16 +1012,6 @@ This is a one-time fix-up, please be patient... required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) required.add(node) - // handle otherwise unresolvable dependency nesting loops by - // creating a symbolic link - // a1 -> b1 -> a2 -> b2 -> a1 -> ... - // instead of nesting forever, when the loop occurs, create - // a symbolic link to the earlier instance - for (let p = edge.from.resolveParent; p; p = p.resolveParent) { - if (p.matches(node) && !p.isTop) - return new Link({ parent: realParent, target: p }) - } - // keep track of the thing that caused this node to be included. const src = parent.sourceReference this[_peerSetSource].set(node, src) diff --git a/node_modules/@npmcli/arborist/lib/can-place-dep.js b/node_modules/@npmcli/arborist/lib/can-place-dep.js index cf6b800c44ea2..9601ad7af3163 100644 --- a/node_modules/@npmcli/arborist/lib/can-place-dep.js +++ b/node_modules/@npmcli/arborist/lib/can-place-dep.js @@ -73,8 +73,10 @@ class CanPlaceDep { if (!edge) throw new Error('no edge provided to CanPlaceDep') - this._nodeSnapshot = JSON.stringify(dep) - this._treeSnapshot = JSON.stringify(target.root) + this._treeSnapshot = JSON.stringify([...target.root.inventory.entries()] + .map(([loc, {packageName, version, resolved}]) => { + return [loc, packageName, version, resolved] + }).sort(([a], [b]) => a.localeCompare(b, 'en'))) }) // the result of whether we can place it or not @@ -110,15 +112,10 @@ class CanPlaceDep { this.canPlaceSelf = this.canPlace debug(() => { - const nodeSnapshot = JSON.stringify(dep) - const treeSnapshot = JSON.stringify(target.root) - /* istanbul ignore if */ - if (this._nodeSnapshot !== nodeSnapshot) { - throw Object.assign(new Error('dep changed in CanPlaceDep'), { - expect: this._nodeSnapshot, - actual: nodeSnapshot, - }) - } + const treeSnapshot = JSON.stringify([...target.root.inventory.entries()] + .map(([loc, {packageName, version, resolved}]) => { + return [loc, packageName, version, resolved] + }).sort(([a], [b]) => a.localeCompare(b, 'en'))) /* istanbul ignore if */ if (this._treeSnapshot !== treeSnapshot) { throw Object.assign(new Error('tree changed in CanPlaceDep'), { diff --git a/node_modules/@npmcli/arborist/lib/place-dep.js b/node_modules/@npmcli/arborist/lib/place-dep.js index 913b2ba6c2bc7..c0023e74ad8ea 100644 --- a/node_modules/@npmcli/arborist/lib/place-dep.js +++ b/node_modules/@npmcli/arborist/lib/place-dep.js @@ -16,6 +16,7 @@ const { } = CanPlaceDep const debug = require('./debug.js') +const Link = require('./link.js') const gatherDepSet = require('./gather-dep-set.js') const peerEntrySets = require('./peer-entry-sets.js') @@ -256,6 +257,20 @@ class PlaceDep { return } + // we were told to place it here in the target, so either it does not + // already exist in the tree, OR it's shadowed. + // handle otherwise unresolvable dependency nesting loops by + // creating a symbolic link + // a1 -> b1 -> a2 -> b2 -> a1 -> ... + // instead of nesting forever, when the loop occurs, create + // a symbolic link to the earlier instance + for (let p = target; p; p = p.resolveParent) { + if (p.matches(dep) && !p.isTop) { + this.placed = new Link({ parent: target, target: p }) + return + } + } + // XXX if we are replacing SOME of a peer entry group, we will need to // remove any that are not being replaced and will now be invalid, and // re-evaluate them deeper into the tree. @@ -268,7 +283,7 @@ class PlaceDep { integrity: dep.integrity, legacyPeerDeps: this.legacyPeerDeps, error: dep.errors[0], - ...(dep.isLink ? { target: dep.target, realpath: dep.target.path } : {}), + ...(dep.isLink ? { target: dep.target, realpath: dep.realpath } : {}), }) this.oldDep = target.children.get(this.name) diff --git a/node_modules/@npmcli/arborist/lib/shrinkwrap.js b/node_modules/@npmcli/arborist/lib/shrinkwrap.js index ebbe004de72d6..83cb1f66f3a10 100644 --- a/node_modules/@npmcli/arborist/lib/shrinkwrap.js +++ b/node_modules/@npmcli/arborist/lib/shrinkwrap.js @@ -255,9 +255,11 @@ class Shrinkwrap { if (val) meta[key.replace(/^_/, '')] = val }) - // we only include name if different from the node path name + // we only include name if different from the node path name, and for the + // root to help prevent churn based on the name of the directory the + // project is in const pname = node.packageName - if (pname && pname !== node.name) + if (pname && (node === node.root || pname !== node.name)) meta.name = pname if (node.isTop && node.package.devDependencies) diff --git a/node_modules/@npmcli/arborist/package.json b/node_modules/@npmcli/arborist/package.json index 56046eaa5f357..01f018a629339 100644 --- a/node_modules/@npmcli/arborist/package.json +++ b/node_modules/@npmcli/arborist/package.json @@ -1,6 +1,6 @@ { "name": "@npmcli/arborist", - "version": "2.8.0", + "version": "2.8.1", "description": "Manage node_modules trees", "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", diff --git a/package-lock.json b/package-lock.json index 8e352377b1c1a..65ed51977b371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,7 +83,7 @@ "packages/*" ], "dependencies": { - "@npmcli/arborist": "^2.8.0", + "@npmcli/arborist": "^2.8.1", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.2.0", "@npmcli/map-workspaces": "^1.0.4", @@ -756,9 +756,9 @@ } }, "node_modules/@npmcli/arborist": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.0.tgz", - "integrity": "sha512-R9rTyak1rGdmVTyiU14dgBb+qMllY3B6I8hp7FB4xXsU9dJDrYZJR8I+191CMo5Y1941jTDCtNcXXW9TldPEFQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.1.tgz", + "integrity": "sha512-kbBWllN4CcdeN032Rw6b+TIsyoxWcv4YNN5gzkMCe8cCu0llwlq5P7uAD2oyL24QdmGlrlg/Yp0L1JF+HD8g9Q==", "inBundle": true, "dependencies": { "@npmcli/installed-package-contents": "^1.0.7", @@ -10997,9 +10997,9 @@ "dev": true }, "@npmcli/arborist": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.0.tgz", - "integrity": "sha512-R9rTyak1rGdmVTyiU14dgBb+qMllY3B6I8hp7FB4xXsU9dJDrYZJR8I+191CMo5Y1941jTDCtNcXXW9TldPEFQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-2.8.1.tgz", + "integrity": "sha512-kbBWllN4CcdeN032Rw6b+TIsyoxWcv4YNN5gzkMCe8cCu0llwlq5P7uAD2oyL24QdmGlrlg/Yp0L1JF+HD8g9Q==", "requires": { "@npmcli/installed-package-contents": "^1.0.7", "@npmcli/map-workspaces": "^1.0.2", diff --git a/package.json b/package.json index c426a5ff8a04c..94879b298370e 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "./package.json": "./package.json" }, "dependencies": { - "@npmcli/arborist": "^2.8.0", + "@npmcli/arborist": "^2.8.1", "@npmcli/ci-detect": "^1.2.0", "@npmcli/config": "^2.2.0", "@npmcli/map-workspaces": "^1.0.4", From d465ef690f2b0fe3ce53f43218f61fd803ea708f Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 12 Aug 2021 12:29:41 -0700 Subject: [PATCH 11/14] chore(smoke-tests): rebuild snapshots Name is always now set on the root node See: https://github.com/npm/arborist/pull/310 --- tap-snapshots/smoke-tests/index.js.test.cjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tap-snapshots/smoke-tests/index.js.test.cjs b/tap-snapshots/smoke-tests/index.js.test.cjs index 0a79e38cdfa03..c1316e04d7ad9 100644 --- a/tap-snapshots/smoke-tests/index.js.test.cjs +++ b/tap-snapshots/smoke-tests/index.js.test.cjs @@ -340,6 +340,7 @@ exports[`smoke-tests/index.js TAP npm install dev dep > should have expected dev "requires": true, "packages": { "": { + "name": "project", "version": "1.0.0", "license": "ISC", "dependencies": { @@ -426,6 +427,7 @@ exports[`smoke-tests/index.js TAP npm install prodDep@version > should have expe "requires": true, "packages": { "": { + "name": "project", "version": "1.0.0", "license": "ISC", "dependencies": { @@ -614,6 +616,7 @@ exports[`smoke-tests/index.js TAP npm uninstall > should have expected uninstall "requires": true, "packages": { "": { + "name": "project", "version": "1.0.0", "license": "ISC", "dependencies": { @@ -671,6 +674,7 @@ exports[`smoke-tests/index.js TAP npm update dep > should have expected update l "requires": true, "packages": { "": { + "name": "project", "version": "1.0.0", "license": "ISC", "dependencies": { From f7905cc254d5f356f5e18c3fe997ad92f46582f9 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 12 Aug 2021 12:37:04 -0700 Subject: [PATCH 12/14] docs: changelog for v7.20.6 --- CHANGELOG.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c36045f27b683..d3f915d6a0ee1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,40 @@ +## v7.20.6 (2021-08-12) + +### DEPENDENCIES + +* [`5bebf280f`](https://github.com/npm/cli/commit/5bebf280f228e818524f6989caab1cfba1ffaf90) + `tar@6.1.8` + * fix: reserve paths case-insensitively +* [`5d89de44d`](https://github.com/npm/cli/commit/5d89de44daa636dc151eaefcafabb357540d35ce) + `tar@6.1.7`: + * fix: normalize paths on Windows systems +* [`a1bdbea97`](https://github.com/npm/cli/commit/a1bdbea974ebfc6694b4c8ad5da86215c2924dde) + [#3569](https://github.com/npm/cli/issues/3569) + * remove byte-size + ([@wraithgar](https://github.com/wraithgar)) +* [`61782fa85`](https://github.com/npm/cli/commit/61782fa858c278455ce144f975c6b0e3ea2d9944) + `@npmcli/map-workspaces@1.0.4`: + * fix: better error message for duplicate workspace names +* [`b88f770fa`](https://github.com/npm/cli/commit/b88f770faa2651ca0833e1c9eb361e9e07e0bbc3) + `@npmcli/arborist@2.8.1`: + * [#3632] Fix "cannot read property path of null" error in 'npm dedupe' + * fix(shrinkwrap): always set name on the root node + +### DOCUMENTATION + +* [`001f2c1b7`](https://github.com/npm/cli/commit/001f2c1b7e9474049a45709f0e80ee3c474a4ba9) + [#3621](https://github.com/npm/cli/issues/3621) + fix(docs): do not include certain files + ([@AkiJoey](https://github.com/AkiJoey)) +* [`d1812f1a6`](https://github.com/npm/cli/commit/d1812f1a627d6a4d4cb6d07d7735d2d2cc2cf264) + [#3630](https://github.com/npm/cli/issues/3630) + fix(docs): update npm-publish access flag info + ([@austincho](https://github.com/austincho)) +* [`d5a099c7b`](https://github.com/npm/cli/commit/d5a099c7bf62977a5a5d8242c61f323a88e27c73) + [#3615](https://github.com/npm/cli/issues/3615) + fix(readme): add nvm-windows to installers links + ([@Yash-Singh1](https://github.com/Yash-Singh1)) + ## v7.20.5 (2021-08-05) ### DEPENDENCIES From 2591e67d2a4b7b53225b55b1b0290840629fe700 Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 12 Aug 2021 12:37:22 -0700 Subject: [PATCH 13/14] update AUTHORS --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index c3685720598a9..a0999c732f232 100644 --- a/AUTHORS +++ b/AUTHORS @@ -789,3 +789,5 @@ Aluneed <31174087+aluneed@users.noreply.github.com> relrelb Cameron Tacklind Demira Dimitrova +AkiJoey +austincho From 59b9851d1649b8f78203cae187b1337f2441219d Mon Sep 17 00:00:00 2001 From: Gar Date: Thu, 12 Aug 2021 12:37:22 -0700 Subject: [PATCH 14/14] 7.20.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65ed51977b371..682d82969f9c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "npm", - "version": "7.20.5", + "version": "7.20.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "npm", - "version": "7.20.5", + "version": "7.20.6", "bundleDependencies": [ "@npmcli/arborist", "@npmcli/ci-detect", diff --git a/package.json b/package.json index 94879b298370e..cee4f44d8cb68 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "7.20.5", + "version": "7.20.6", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [