From b1d5e8d243822301c51cfdeffa6db2621e599d2e Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 24 Jul 2019 01:31:43 -0700 Subject: [PATCH 01/17] doc: fix typo in changelog --- CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a77c898d984aa..7cf53e92f553a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,10 +28,6 @@ Unix systems. * [`235e5d6df`](https://github.com/npm/cli/commit/235e5d6df6f427585ec58425f1f3339d08f39d8a) ensure correct owner on cached all-packages metadata ([@isaacs](https://github.com/isaacs)) -* [`fa6acd2ea`](https://github.com/npm/cli/commit/fa6acd2ea035bf26c04d7885b534d03d5b77e7ba) - [npm.community#8450](https://npm.community/t/npm-audit-fails-with-child-requires-fails-because-requires-must-be-an-object/8540) - audit: report server error on failure - ([@isaacs](https://github.com/isaacs)) * [`e2d377bb6`](https://github.com/npm/cli/commit/e2d377bb6419d8a3c1d80a73dba46062b4dad336) [npm.community#8540](https://npm.community/t/npm-audit-fails-with-child-requires-fails-because-requires-must-be-an-object/8540) audit: report server error on failure From 0ebf071f5b8d0cdc2790c2c0a3fbf98183cd0df2 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 13:51:47 -0700 Subject: [PATCH 02/17] chore: add a scripts to land PRs more easily --- scripts/pr | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100755 scripts/pr diff --git a/scripts/pr b/scripts/pr new file mode 100755 index 0000000000000..dfaf6e4dbbb37 --- /dev/null +++ b/scripts/pr @@ -0,0 +1,116 @@ +#!/usr/bin/env bash + +# Land a pull request +# Creates a PR-### branch, pulls the commits, opens up an interactive rebase to +# squash, and then annotates the commit with the changelog goobers +# +# Usage: +# pr [=origin] + +main () { + local url="$(prurl "$@")" + local num=$(basename $url) + local prpath="${url#git@github.com:}" + local repo=${prpath%/pull/$num} + local prweb="https://github.com/$prpath" + local root="$(prroot "$url")" + local api="https://api.github.com/repos/${repo}/pulls/${num}" + local user=$(curl -s $api | json user.login) + local ref="$(prref "$url" "$root")" + local curhead="$(git show --no-patch --pretty=%H HEAD)" + local curbranch="$(git rev-parse --abbrev-ref HEAD)" + local cleanlines + IFS=$'\n' cleanlines=($(git status -s -uno)) + if [ ${#cleanlines[@]} -ne 0 ]; then + echo "working dir not clean" >&2 + IFS=$'\n' echo "${cleanlines[@]}" >&2 + echo "aborting PR merge" >&2 + fi + + # ok, ready to rock + branch=PR-$num + if [ "$curbranch" == "$branch" ]; then + echo "already on $branch, you're on your own" >&2 + return 1 + fi + + me=$(git config github.user || git config user.name) + if [ "$me" == "" ]; then + echo "run 'git config --add github.user '" >&2 + return 1 + fi + + exists=$(git show --no-patch --pretty=%H $branch 2>/dev/null) + if [ "$exists" == "" ]; then + git fetch origin pull/$num/head:$branch + git checkout $branch + else + git checkout $branch + git pull --rebase origin pull/$num/head + fi + + # add the PR-URL to the last commit, after squashing + + git rebase -i $curbranch # squash and test + + local lastmsg="$(git log -1 --pretty=%B)" + local newmsg="${lastmsg} + +PR-URL: ${prweb} +Credit: @${user} +Close: #${num} +Reviewed-by: @${me} +" + git commit --amend -m "$newmsg" + git checkout $curbranch + git merge $branch --ff-only +} + +prurl () { + local url="$1" + if [ "$url" == "" ] && type pbpaste &>/dev/null; then + url="$(pbpaste)" + fi + if [[ "$url" =~ ^[0-9]+$ ]]; then + local us="$2" + if [ "$us" == "" ]; then + us="origin" + fi + local num="$url" + local o="$(git config --get remote.${us}.url)" + url="${o}" + url="${url#(git:\/\/|https:\/\/)}" + url="${url#git@}" + url="${url#github.com[:\/]}" + url="${url%.git}" + url="https://github.com/${url}/pull/$num" + fi + url=${url%/commits} + url=${url%/files} + url="$(echo $url | perl -p -e 's/#issuecomment-[0-9]+$//g')" + + local p='^https:\/\/github.com\/[^\/]+\/[^\/]+\/pull\/[0-9]+$' + if ! [[ "$url" =~ $p ]]; then + echo "Usage:" + echo " $0 " + echo " $0 [=origin]" + type pbpaste &>/dev/null && + echo "(will read url/id from clipboard if not specified)" + exit 1 + fi + url="${url/https:\/\/github\.com\//git@github.com:}" + echo "$url" +} + +prroot () { + local url="$1" + echo "${url/\/pull\/+([0-9])/}" +} + +prref () { + local url="$1" + local root="$2" + echo "refs${url:${#root}}/head" +} + +main "$@" From 272e6c48b95597309d297fdeaacf30b3f66f13fd Mon Sep 17 00:00:00 2001 From: Kitten King Date: Thu, 25 Jul 2019 02:47:36 +0000 Subject: [PATCH 03/17] Fix Typos PR-URL: https://github.com/npm/cli/pull/220 Credit: @kittenking Close: #220 Reviewed-by: @isaacs --- lib/install/diff-trees.js | 2 +- lib/shrinkwrap.js | 2 +- test/tap/false-name.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/install/diff-trees.js b/lib/install/diff-trees.js index 346846fdc0ffe..147aa9b8e74f3 100644 --- a/lib/install/diff-trees.js +++ b/lib/install/diff-trees.js @@ -11,7 +11,7 @@ var moduleName = require('../utils/module-name.js') var isOnlyOptional = require('./is-only-optional.js') // we don't use get-requested because we're operating on files on disk, and -// we don't want to extropolate from what _should_ be there. +// we don't want to extrapolate from what _should_ be there. function pkgRequested (pkg) { return pkg._requested || (pkg._resolved && npa(pkg._resolved)) || (pkg._from && npa(pkg._from)) } diff --git a/lib/shrinkwrap.js b/lib/shrinkwrap.js index bd8c0abbaa205..35e063d447956 100644 --- a/lib/shrinkwrap.js +++ b/lib/shrinkwrap.js @@ -121,7 +121,7 @@ function shrinkwrapDeps (deps, top, tree, seen) { if (isRegistry(requested)) { pkginfo.resolved = child.package._resolved } - // no integrity for git deps as integirty hashes are based on the + // no integrity for git deps as integrity hashes are based on the // tarball and we can't (yet) create consistent tarballs from a stable // source. if (requested.type !== 'git') { diff --git a/test/tap/false-name.js b/test/tap/false-name.js index 541bacc7eda53..57d2a2ad2f8dd 100644 --- a/test/tap/false-name.js +++ b/test/tap/false-name.js @@ -58,7 +58,7 @@ test('not every pkg.name can be required', function (t) { ) t.ok( existsSync(path.join(pkg, 'node_modules', 'test-package')), - 'test-pacakge subdep installed OK' + 'test-package subdep installed OK' ) t.end() } From aacd355018e108e031e238ee10bf7705b6de3f69 Mon Sep 17 00:00:00 2001 From: claudiahdz Date: Tue, 23 Jul 2019 21:26:56 +0300 Subject: [PATCH 04/17] chore: remove unused config/fetch-opts file PR-URL: https://github.com/npm/cli/pull/219 Credit: @claudiahdz Close: #219 Reviewed-by: @isaacs --- lib/config/fetch-opts.js | 77 ---------------------------------------- 1 file changed, 77 deletions(-) delete mode 100644 lib/config/fetch-opts.js diff --git a/lib/config/fetch-opts.js b/lib/config/fetch-opts.js deleted file mode 100644 index 213c293d6c7c9..0000000000000 --- a/lib/config/fetch-opts.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict' - -const url = require('url') - -module.exports.fromPacote = fromPacote - -function fromPacote (opts) { - return { - cache: getCacheMode(opts), - cacheManager: opts.cache, - ca: opts.ca, - cert: opts.cert, - headers: getHeaders('', opts.registry, opts), - key: opts.key, - localAddress: opts.localAddress, - maxSockets: opts.maxSockets, - proxy: opts.proxy, - referer: opts.refer, - retry: opts.retry, - strictSSL: !!opts.strictSSL, - timeout: opts.timeout, - uid: opts.uid, - gid: opts.gid - } -} - -function getCacheMode (opts) { - return opts.offline - ? 'only-if-cached' - : opts.preferOffline - ? 'force-cache' - : opts.preferOnline - ? 'no-cache' - : 'default' -} - -function getHeaders (uri, registry, opts) { - const headers = Object.assign({ - 'npm-in-ci': opts.isFromCI, - 'npm-scope': opts.projectScope, - 'npm-session': opts.npmSession, - 'user-agent': opts.userAgent, - 'referer': opts.refer - }, opts.headers) - // check for auth settings specific to this registry - let auth = ( - opts.auth && - opts.auth[registryKey(registry)] - ) || opts.auth - // If a tarball is hosted on a different place than the manifest, only send - // credentials on `alwaysAuth` - const shouldAuth = auth && ( - auth.alwaysAuth || - url.parse(uri).host === url.parse(registry).host - ) - if (shouldAuth && auth.token) { - headers.authorization = `Bearer ${auth.token}` - } else if (shouldAuth && auth.username && auth.password) { - const encoded = Buffer.from( - `${auth.username}:${auth.password}`, 'utf8' - ).toString('base64') - headers.authorization = `Basic ${encoded}` - } else if (shouldAuth && auth._auth) { - headers.authorization = `Basic ${auth._auth}` - } - return headers -} - -function registryKey (registry) { - const parsed = url.parse(registry) - const formatted = url.format({ - host: parsed.host, - pathname: parsed.pathname, - slashes: parsed.slashes - }) - return url.resolve(formatted, '.') -} From 27cccfbdac8526cc807b07f416355949b1372a9b Mon Sep 17 00:00:00 2001 From: Artem Sapegin Date: Tue, 30 Jul 2019 08:37:36 +0200 Subject: [PATCH 05/17] =?UTF-8?q?vulns=20=E2=86=92=C2=A0vulnerabilities=20?= =?UTF-8?q?in=20npm=20audit=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consistently use “vulnerabilities” in the message, don't use confusing “vulns”. PR-URL: https://github.com/npm/cli/pull/223 Credit: @sapegin Close: #223 Reviewed-by: @isaacs --- lib/audit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/audit.js b/lib/audit.js index c86566403a2bf..7b694c13c5d7f 100644 --- a/lib/audit.js +++ b/lib/audit.js @@ -277,7 +277,7 @@ function auditCmd (args, cb) { output(` ${actions.review.size} vulnerabilit${actions.review.size === 1 ? 'y' : 'ies'} required manual review and could not be updated`) } if (actions.major.size) { - output(` ${actions.major.size} package update${actions.major.size === 1 ? '' : 's'} for ${actions.majorFixes.size} vuln${actions.majorFixes.size === 1 ? '' : 's'} involved breaking changes`) + output(` ${actions.major.size} package update${actions.major.size === 1 ? '' : 's'} for ${actions.majorFixes.size} vulnerabilit${actions.majorFixes.size === 1 ? 'y' : 'ies'} involved breaking changes`) if (installMajor) { output(' (installed due to `--force` option)') } else { From d5e865eb79329665a927cc2767b4395c03045dbb Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 26 Jul 2019 11:46:14 -0700 Subject: [PATCH 06/17] install, doctor: don't crash if registry unset Close: https://github.com/npm/cli/pull/222 PR-URL: https://github.com/npm/cli/pull/226 Credit: @isaacs Close: #226 --- lib/doctor.js | 2 +- lib/install/inflate-shrinkwrap.js | 2 +- test/tap/doctor.js | 48 ++++++++++++++++----- test/tap/install-without-registry-config.js | 35 +++++++++++++++ 4 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 test/tap/install-without-registry-config.js diff --git a/lib/doctor.js b/lib/doctor.js index 95ede1bc87242..96094e6346d05 100644 --- a/lib/doctor.js +++ b/lib/doctor.js @@ -87,7 +87,7 @@ function makePretty (p) { const cacheStatus = p[8] ? `verified ${p[8].verifiedContent} tarballs` : 'notOk' const npmV = npm.version const nodeV = process.version.replace('v', '') - const registry = npm.config.get('registry') + const registry = npm.config.get('registry') || '' const list = [ ['npm ping', ping], ['npm -v', 'v' + npmV], diff --git a/lib/install/inflate-shrinkwrap.js b/lib/install/inflate-shrinkwrap.js index 395cc11191309..5da9418bbdb7a 100644 --- a/lib/install/inflate-shrinkwrap.js +++ b/lib/install/inflate-shrinkwrap.js @@ -74,7 +74,7 @@ function quotemeta (str) { } function tarballToVersion (name, tb) { - const registry = quotemeta(npm.config.get('registry')) + const registry = quotemeta(npm.config.get('registry') || '') .replace(/https?:/, 'https?:') .replace(/([^/])$/, '$1/') let matchRegTarball diff --git a/test/tap/doctor.js b/test/tap/doctor.js index 7b07e0f39b7d8..9285518c2e10e 100644 --- a/test/tap/doctor.js +++ b/test/tap/doctor.js @@ -5,9 +5,8 @@ const http = require('http') const mr = require('npm-registry-mock') const npm = require('../../lib/npm.js') const path = require('path') -const rimraf = require('rimraf') const Tacks = require('tacks') -const test = require('tap').test +const t = require('tap') const which = require('which') const Dir = Tacks.Dir @@ -44,12 +43,23 @@ const npmResponse = { } } -test('setup', (t) => { +let nodeServer + +t.teardown(() => { + if (server) { + server.close() + } + if (nodeServer) { + nodeServer.close() + } +}) + +t.test('setup', (t) => { const port = common.port + 1 - http.createServer(function (q, s) { + nodeServer = http.createServer(function (q, s) { s.end(JSON.stringify([{lts: true, version: '0.0.0'}])) - this.close() - }).listen(port, () => { + }) + nodeServer.listen(port, () => { node_url = 'http://localhost:' + port mr({port: common.port}, (err, s) => { t.ifError(err, 'registry mocked successfully') @@ -78,7 +88,7 @@ test('setup', (t) => { }) }) -test('npm doctor', function (t) { +t.test('npm doctor', function (t) { npm.commands.doctor({'node-url': node_url}, true, function (e, list) { t.ifError(e, 'npm loaded successfully') t.same(list.length, 9, 'list should have 9 prop') @@ -93,13 +103,29 @@ test('npm doctor', function (t) { which('git', function (e, resolvedPath) { t.ifError(e, 'git command is installed') t.same(list[4][1], resolvedPath, 'which git') - server.close() t.done() }) }) }) -test('cleanup', (t) => { - rimraf.sync(ROOT) - t.done() +t.test('npm doctor works without registry', function (t) { + npm.config.set('registry', false) + npm.commands.doctor({'node-url': node_url}, true, function (e, list) { + t.ifError(e, 'npm loaded successfully') + t.same(list.length, 9, 'list should have 9 prop') + t.same(list[0][1], 'OK', 'npm ping') + t.same(list[1][1], 'v' + npm.version, 'npm -v') + t.same(list[2][1], process.version, 'node -v') + t.same(list[3][1], '', 'no registry, but no crash') + t.same(list[5][1], 'ok', 'Perms check on cached files') + t.same(list[6][1], 'ok', 'Perms check on global node_modules') + t.same(list[7][1], 'ok', 'Perms check on local node_modules') + t.match(list[8][1], /^verified \d+ tarballs?$/, 'Cache verified') + which('git', function (e, resolvedPath) { + t.ifError(e, 'git command is installed') + t.same(list[4][1], resolvedPath, 'which git') + server.close() + t.done() + }) + }) }) diff --git a/test/tap/install-without-registry-config.js b/test/tap/install-without-registry-config.js new file mode 100644 index 0000000000000..852bd777ced5a --- /dev/null +++ b/test/tap/install-without-registry-config.js @@ -0,0 +1,35 @@ +const t = require('tap') +const { pkg, npm } = require('../common-tap.js') +const { writeFileSync, statSync, readFileSync } = require('fs') +const mkdirp = require('mkdirp') +const proj = pkg + '/project' +const dep = pkg + '/dep' +mkdirp.sync(proj) +mkdirp.sync(dep) +writeFileSync(dep + '/package.json', JSON.stringify({ + name: 'dependency', + version: '1.2.3' +})) +writeFileSync(proj + '/package.json', JSON.stringify({ + name: 'project', + version: '4.2.0' +})) + +const runTest = t => npm([ + 'install', + '../dep', + '--no-registry' +], { cwd: proj }).then(([code, out, err]) => { + t.equal(code, 0) + t.match(out, /^\+ dependency@1\.2\.3\n.* 1 package in [0-9.]+m?s\n$/) + t.equal(err, '') + const data = readFileSync(proj + '/node_modules/dependency/package.json', 'utf8') + t.same(JSON.parse(data), { + name: 'dependency', + version: '1.2.3' + }, 'dep got installed') + t.ok(statSync(proj + '/package-lock.json').isFile(), 'package-lock exists') +}) + +t.test('install without a registry, no package lock', t => runTest(t)) +t.test('install without a registry, with package lock', t => runTest(t)) From 77516df6eac94a6d7acb5e9ca06feaa0868d779b Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 14:00:39 -0700 Subject: [PATCH 07/17] licensee@7.0.3 --- package-lock.json | 13 +++++++------ package.json | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index d325b301f1ba4..48bd8f4d7510b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3239,15 +3239,16 @@ } }, "licensee": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/licensee/-/licensee-7.0.2.tgz", - "integrity": "sha512-U30RSe5DI7HfKGM2LNgt/5QP7QEk4leKcRTp/6PorHHDeAoFsZn7SGwR/MKgP3xdk6cTD+G3SBdYwQGcZ1zPfA==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/licensee/-/licensee-7.0.3.tgz", + "integrity": "sha512-Rdwk+y+nOzkTKz68Gj0OOIy7ISkw+JJzSpn37hfHOXT6swkGfnKEt9+jRolWIFONiIhwv+W5E8K/pnXBfWLewQ==", "dev": true, "requires": { "@blueoak/list": "^1.0.2", "correct-license-metadata": "^1.0.1", "docopt": "^0.6.2", "fs-access": "^2.0.0", + "has": "^1.0.3", "json-parse-errback": "^2.0.1", "npm-license-corrections": "^1.0.0", "read-package-tree": "^5.2.1", @@ -3261,9 +3262,9 @@ }, "dependencies": { "semver": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.2.tgz", - "integrity": "sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } diff --git a/package.json b/package.json index 00c0e1dc5c631..810b07c015c09 100644 --- a/package.json +++ b/package.json @@ -277,7 +277,7 @@ "devDependencies": { "deep-equal": "^1.0.1", "get-stream": "^4.1.0", - "licensee": "^7.0.2", + "licensee": "^7.0.3", "marked": "^0.6.3", "marked-man": "^0.6.0", "npm-registry-couchapp": "^2.7.3", From ceb993590e4e376a9a78264ce7bb4327fbbb37fe Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 14:01:05 -0700 Subject: [PATCH 08/17] query-string@6.8.2 --- node_modules/query-string/index.js | 2 +- node_modules/query-string/package.json | 20 ++++++++++---------- package-lock.json | 6 +++--- package.json | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/node_modules/query-string/index.js b/node_modules/query-string/index.js index da459c9404d0b..35c13e1a66565 100644 --- a/node_modules/query-string/index.js +++ b/node_modules/query-string/index.js @@ -202,7 +202,7 @@ function parse(input, options) { // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters value = value === undefined ? null : decode(value, options); - if (options.parseNumbers && !Number.isNaN(Number(value))) { + if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) { value = Number(value); } else if (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) { value = value.toLowerCase() === 'true'; diff --git a/node_modules/query-string/package.json b/node_modules/query-string/package.json index 916b3fe5a1714..4df6b20ef0e91 100644 --- a/node_modules/query-string/package.json +++ b/node_modules/query-string/package.json @@ -1,27 +1,27 @@ { - "_from": "query-string@6.8.1", - "_id": "query-string@6.8.1", + "_from": "query-string@6.8.2", + "_id": "query-string@6.8.2", "_inBundle": false, - "_integrity": "sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q==", + "_integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==", "_location": "/query-string", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "query-string@6.8.1", + "raw": "query-string@6.8.2", "name": "query-string", "escapedName": "query-string", - "rawSpec": "6.8.1", + "rawSpec": "6.8.2", "saveSpec": null, - "fetchSpec": "6.8.1" + "fetchSpec": "6.8.2" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.1.tgz", - "_shasum": "62c54a7ef37d01b538c8fd56f95740c81d438a26", - "_spec": "query-string@6.8.1", + "_resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.2.tgz", + "_shasum": "36cb7e452ae11a4b5e9efee83375e0954407b2f6", + "_spec": "query-string@6.8.2", "_where": "/Users/isaacs/dev/npm/cli", "author": { "name": "Sindre Sorhus", @@ -78,5 +78,5 @@ "scripts": { "test": "xo && ava && tsd" }, - "version": "6.8.1" + "version": "6.8.2" } diff --git a/package-lock.json b/package-lock.json index 48bd8f4d7510b..bca91e2e34205 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4762,9 +4762,9 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.1.tgz", - "integrity": "sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q==", + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.2.tgz", + "integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==", "requires": { "decode-uri-component": "^0.2.0", "split-on-first": "^1.0.0", diff --git a/package.json b/package.json index 810b07c015c09..6b802b7dbbc99 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", "qrcode-terminal": "^0.12.0", - "query-string": "^6.8.1", + "query-string": "^6.8.2", "qw": "~1.0.1", "read": "~1.0.7", "read-cmd-shim": "~1.0.1", From 9bb66e1c0c6d18e93f3900c1d540b030f139aca8 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 15:07:24 -0700 Subject: [PATCH 09/17] docs: changelog for 6.10.3 --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cf53e92f553a..024a069b10f38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## v6.10.3 (2019-08-06): + +### BUGFIXES + +* [`27cccfbda`](https://github.com/npm/cli/commit/27cccfbdac8526cc807b07f416355949b1372a9b) + [#223](https://github.com/npm/cli/pull/223) vulns → vulnerabilities in + npm audit output ([@sapegin](https://github.com/sapegin)) +* [`d5e865eb7`](https://github.com/npm/cli/commit/d5e865eb79329665a927cc2767b4395c03045dbb) + [#222](https://github.com/npm/cli/pull/222) + [#226](https://github.com/npm/cli/pull/226) install, doctor: don't crash + if registry unset ([@isaacs](https://github.com/isaacs)) + +### DEPENDENCIES + +* [`77516df6e`](https://github.com/npm/cli/commit/77516df6eac94a6d7acb5e9ca06feaa0868d779b) + `licensee@7.0.3` ([@isaacs](https://github.com/isaacs)) +* [`ceb993590`](https://github.com/npm/cli/commit/ceb993590e4e376a9a78264ce7bb4327fbbb37fe) + `query-string@6.8.2` ([@isaacs](https://github.com/isaacs)) + ## v6.10.2 (2019-07-23): tl;dr - Fixes several issues with the cache when npm is run as `sudo` on From 99edd49e77ab8d41a6b2613f7399c0f9b6fb1675 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 15:18:25 -0700 Subject: [PATCH 10/17] test: clean up some unnecessary setup/cleanup --- test/tap/cache-shasum-fork.js | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/test/tap/cache-shasum-fork.js b/test/tap/cache-shasum-fork.js index e035c78111af8..fade5ffb646c5 100644 --- a/test/tap/cache-shasum-fork.js +++ b/test/tap/cache-shasum-fork.js @@ -3,8 +3,6 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -19,7 +17,8 @@ var cache = common.cache var server test('setup', function (t) { - setup() + mkdirp.sync(path.join(pkg, 'node_modules')) + process.chdir(pkg) t.comment('test for https://github.com/npm/npm/issues/3265') mr({ port: common.port }, function (er, s) { server = s @@ -28,7 +27,6 @@ test('setup', function (t) { }) test('npm cache - install from fork', function (t) { - setup() common.npm( [ '--loglevel', 'silent', @@ -60,7 +58,6 @@ test('npm cache - install from fork', function (t) { // Now install the real 1.5.1. test('npm cache - install from origin', function (t) { - setup() common.npm( [ '--loglevel', 'silent', @@ -91,17 +88,5 @@ test('npm cache - install from origin', function (t) { test('cleanup', function (t) { server.close() - cleanup() t.end() }) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - mkdirp.sync(cache) - mkdirp.sync(path.join(pkg, 'node_modules')) - process.chdir(pkg) -} From 5b389022652abeb0e1c278a152550eb95bc6c452 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 16:48:19 -0700 Subject: [PATCH 11/17] Handle unhandledRejections, help with cache eacces Suggested by @godmar in https://npm.community/t/npm-err-cb-never-called-permission-denied/9167/5 Incidentally, this turned up that we're catching uncaughtExceptions in the main npm functions, but not unhandledRejections! Tracing this through, it seems like node-fetch-npm's use of cacache is particularly brittle. Any throw that comes from cacache is not caught properly, since node-fetch-npm is all streams and callbacks. The naive approach (just adding a catch and failing the callback) doesn't work, because then make-fetch-happen and npm-registry-fetch interpret the failure as an invalid response, when actually it was a local cache error. So, a bit more love and polish is definitely still needed in the guts of npm's fetching and caching code paths. In the meantime, though, handling any unhandledRejection at the top level prevents at least the worst and most useless type of error message. PR-URL: https://github.com/npm/cli/pull/227 Credit: @isaacs Close: #227 Reviewed-by: @isaacs --- bin/npm-cli.js | 1 + lib/utils/error-handler.js | 7 ++-- lib/utils/error-message.js | 49 +++++++++++++++++++------- test/tap/cache-eacces-error-message.js | 38 ++++++++++++++++++++ 4 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 test/tap/cache-eacces-error-message.js diff --git a/bin/npm-cli.js b/bin/npm-cli.js index 705aa472e7e55..93eddc7a3c892 100755 --- a/bin/npm-cli.js +++ b/bin/npm-cli.js @@ -62,6 +62,7 @@ log.info('using', 'node@%s', process.version) process.on('uncaughtException', errorHandler) + process.on('unhandledRejection', errorHandler) if (conf.usage && npm.command !== 'help') { npm.argv.unshift(npm.command) diff --git a/lib/utils/error-handler.js b/lib/utils/error-handler.js index 7cb43be2900ec..39e0035c27288 100644 --- a/lib/utils/error-handler.js +++ b/lib/utils/error-handler.js @@ -187,11 +187,12 @@ function errorHandler (er) { log.verbose('npm ', 'v' + npm.version) ;[ + 'code', + 'syscall', 'file', 'path', - 'code', - 'errno', - 'syscall' + 'dest', + 'errno' ].forEach(function (k) { var v = er[k] if (v) log.error(k, v) diff --git a/lib/utils/error-message.js b/lib/utils/error-message.js index bf5d65c0df3ca..ea8b05938c108 100644 --- a/lib/utils/error-message.js +++ b/lib/utils/error-message.js @@ -2,6 +2,7 @@ var npm = require('../npm.js') var util = require('util') var nameValidator = require('validate-npm-package-name') +var npmlog = require('npmlog') module.exports = errorMessage @@ -33,18 +34,42 @@ function errorMessage (er) { case 'EACCES': case 'EPERM': - short.push(['', er]) - detail.push([ - '', - [ - '\nThe operation was rejected by your operating system.', - (process.platform === 'win32' - ? 'It\'s possible that the file was already in use (by a text editor or antivirus),\nor that you lack permissions to access it.' - : 'It is likely you do not have the permissions to access this file as the current user'), - '\nIf you believe this might be a permissions issue, please double-check the', - 'permissions of the file and its containing directories, or try running', - 'the command again as root/Administrator (though this is not recommended).' - ].join('\n')]) + const isCachePath = typeof er.path === 'string' && + er.path.startsWith(npm.config.get('cache')) + const isCacheDest = typeof er.dest === 'string' && + er.dest.startsWith(npm.config.get('cache')) + + const isWindows = process.platform === 'win32' + + if (!isWindows && (isCachePath || isCacheDest)) { + // user probably doesn't need this, but still add it to the debug log + npmlog.verbose(er.stack) + short.push([ + '', + [ + '', + 'Your cache folder contains root-owned files, due to a bug in', + 'previous versions of npm which has since been addressed.', + '', + 'To permanently fix this problem, please run:', + ` sudo chown -R ${process.getuid()}:${process.getgid()} ${JSON.stringify(npm.config.get('cache'))}` + ].join('\n') + ]) + } else { + short.push(['', er]) + detail.push([ + '', + [ + '\nThe operation was rejected by your operating system.', + (process.platform === 'win32' + ? 'It\'s possible that the file was already in use (by a text editor or antivirus),\n' + + 'or that you lack permissions to access it.' + : 'It is likely you do not have the permissions to access this file as the current user'), + '\nIf you believe this might be a permissions issue, please double-check the', + 'permissions of the file and its containing directories, or try running', + 'the command again as root/Administrator.' + ].join('\n')]) + } break case 'ELIFECYCLE': diff --git a/test/tap/cache-eacces-error-message.js b/test/tap/cache-eacces-error-message.js new file mode 100644 index 0000000000000..aa112eba43921 --- /dev/null +++ b/test/tap/cache-eacces-error-message.js @@ -0,0 +1,38 @@ +const npm = require('../../lib/npm.js') +const t = require('tap') + +if (process.platform === 'win32') { + t.plan(0, 'this is a unix-only thing') + process.exit(0) +} + +const errorMessage = require('../../lib/utils/error-message.js') + +const common = require('../common-tap.js') + +t.plan(1) + +npm.load({ cache: common.cache }, () => { + npm.config.set('cache', common.cache) + const er = new Error('access is e, i am afraid') + er.code = 'EACCES' + er.errno = -13 + er.path = common.cache + '/src' + er.dest = common.cache + '/to' + + t.match(errorMessage(er), { + summary: [ + [ + '', + new RegExp('\n' + + 'Your cache folder contains root-owned files, due to a bug in\n' + + 'previous versions of npm which has since been addressed.\n' + + '\n' + + 'To permanently fix this problem, please run:\n' + + ' sudo chown -R [0-9]+:[0-9]+ ".*npm_cache_cache-eacces-error-message"' + ) + ] + ], + detail: [] + }, 'get the helpful error message') +}) From 0f980f55e8f16c58cf63872b5babcd401ba04b10 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 1 Aug 2019 17:11:51 -0700 Subject: [PATCH 12/17] doc: changelog 6.10.3 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 024a069b10f38..8c8795a1454f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ [#222](https://github.com/npm/cli/pull/222) [#226](https://github.com/npm/cli/pull/226) install, doctor: don't crash if registry unset ([@isaacs](https://github.com/isaacs)) +* [`5b3890226`](https://github.com/npm/cli/commit/5b389022652abeb0e1c278a152550eb95bc6c452) + [#227](https://github.com/npm/cli/pull/227) + [npm.community#9167](https://npm.community/t/npm-err-cb-never-called-permission-denied/9167/5) + Handle unhandledRejections, tell user what to do when encountering an + `EACCES` error in the cache. ([@isaacs](https://github.com/isaacs)) ### DEPENDENCIES From 46181cb490ebb7732e806d6f4f0771bf42e6fa50 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 4 Aug 2019 16:17:38 -0700 Subject: [PATCH 13/17] dev: make the pr script a little friendlier with conflicts --- scripts/pr | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/scripts/pr b/scripts/pr index dfaf6e4dbbb37..30a3b05ffe3b1 100755 --- a/scripts/pr +++ b/scripts/pr @@ -8,6 +8,12 @@ # pr [=origin] main () { + if [ "$1" = "finish" ]; then + shift + finish "$@" + return $? + fi + local url="$(prurl "$@")" local num=$(basename $url) local prpath="${url#git@github.com:}" @@ -49,10 +55,53 @@ main () { git pull --rebase origin pull/$num/head fi - # add the PR-URL to the last commit, after squashing - git rebase -i $curbranch # squash and test + if [ $? -eq 0 ]; then + finish "${curbranch}" + else + echo "resolve conflicts and run: $0 finish "'"'${curbranch}'"' + fi +} + +# add the PR-URL to the last commit, after squashing +finish () { + if [ $# -eq 0 ]; then + echo "Usage: $0 finish (while on a PR-### branch)" >&2 + return 1 + fi + + local curbranch="$1" + local ref=$(cat .git/HEAD) + local prnum + case $ref in + "ref: refs/heads/PR-"*) + prnum=${ref#ref: refs/heads/PR-} + ;; + *) + echo "not on the PR-## branch any more!" >&2 + return 1 + ;; + esac + + local me=$(git config github.user || git config user.name) + if [ "$me" == "" ]; then + echo "run 'git config --add github.user '" >&2 + return 1 + fi + + set -x + + local url="$(prurl "$prnum")" + local num=$prnum + local prpath="${url#git@github.com:}" + local repo=${prpath%/pull/$num} + local prweb="https://github.com/$prpath" + local root="$(prroot "$url")" + + local api="https://api.github.com/repos/${repo}/pulls/${num}" + local user=$(curl -s $api | json user.login) + local lastmsg="$(git log -1 --pretty=%B)" local newmsg="${lastmsg} @@ -63,9 +112,11 @@ Reviewed-by: @${me} " git commit --amend -m "$newmsg" git checkout $curbranch - git merge $branch --ff-only + git merge PR-${prnum} --ff-only + set +x } + prurl () { local url="$1" if [ "$url" == "" ] && type pbpaste &>/dev/null; then From 4050b91898c60e9b22998cf82b70b9b822de592a Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 5 Aug 2019 09:39:24 -0700 Subject: [PATCH 14/17] hosted-git-info@2.8.2 FEATURES * [bbcf7b2](https://github.com/npm/hosted-git-info/commit/bbcf7b2d4090bc75bb8501aa40450bb0e8496787) [#46](https://github.com/npm/hosted-git-info/issues/46) [#43](https://github.com/npm/hosted-git-info/issues/43) [#47](https://github.com/npm/hosted-git-info/pull/47) [#44](https://github.com/npm/hosted-git-info/pull/44) Add support for GitLab groups and subgroups ([@mterrel](https://github.com/mterrel), [@isaacs](https://github.com/isaacs), [@ybiquitous](https://github.com/ybiquitous)) BUGFIXES * ([3b1d629](https://github.com/npm/hosted-git-info/commit/3b1d629)) [#48](https://github.com/npm/hosted-git-info/issues/48) fix http protocol using sshurl by default ([@fengmk2](https://github.com/fengmk2)) * [5d4a8d7](https://github.com/npm/hosted-git-info/commit/5d4a8d7) ignore noCommittish on tarball url generation ([@isaacs](https://github.com/isaacs)) * [1692435](https://github.com/npm/hosted-git-info/commit/1692435) use gist tarball url that works for anonymous gists ([@isaacs](https://github.com/isaacs)) * [d5cf830](https://github.com/npm/hosted-git-info/commit/d5cf8309be7af884032616c63ea302ce49dd321c) * Do not allow invalid gist urls ([@isaacs](https://github.com/isaacs)) * [e518222](https://github.com/npm/hosted-git-info/commit/e5182224351183ce619dd5ef00019ae700ed37b7) Use LRU cache to prevent unbounded memory consumption ([@iarna](https://github.com/iarna)) --- node_modules/hosted-git-info/CHANGELOG.md | 40 +++++++++++++++++ node_modules/hosted-git-info/git-host-info.js | 8 ++-- node_modules/hosted-git-info/git-host.js | 45 ++++++++++++++----- node_modules/hosted-git-info/index.js | 32 ++++++------- node_modules/hosted-git-info/package.json | 33 +++++++------- package-lock.json | 9 ++-- package.json | 2 +- 7 files changed, 122 insertions(+), 47 deletions(-) diff --git a/node_modules/hosted-git-info/CHANGELOG.md b/node_modules/hosted-git-info/CHANGELOG.md index 7a8d5df968da3..9eedbb80b1ecc 100644 --- a/node_modules/hosted-git-info/CHANGELOG.md +++ b/node_modules/hosted-git-info/CHANGELOG.md @@ -2,6 +2,46 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [2.8.2](https://github.com/npm/hosted-git-info/compare/v2.8.1...v2.8.2) (2019-08-05) + + +### Bug Fixes + +* http protocol use sshurl by default ([3b1d629](https://github.com/npm/hosted-git-info/commit/3b1d629)), closes [#48](https://github.com/npm/hosted-git-info/issues/48) + + + + +## [2.8.1](https://github.com/npm/hosted-git-info/compare/v2.8.0...v2.8.1) (2019-08-05) + + +### Bug Fixes + +* ignore noCommittish on tarball url generation ([5d4a8d7](https://github.com/npm/hosted-git-info/commit/5d4a8d7)) +* use gist tarball url that works for anonymous gists ([1692435](https://github.com/npm/hosted-git-info/commit/1692435)) + + + + +# [2.8.0](https://github.com/npm/hosted-git-info/compare/v2.7.1...v2.8.0) (2019-08-05) + + +### Bug Fixes + +* Allow slashes in gitlab project section ([bbcf7b2](https://github.com/npm/hosted-git-info/commit/bbcf7b2)), closes [#46](https://github.com/npm/hosted-git-info/issues/46) [#43](https://github.com/npm/hosted-git-info/issues/43) +* **git-host:** disallow URI-encoded slash (%2F) in `path` ([3776fa5](https://github.com/npm/hosted-git-info/commit/3776fa5)), closes [#44](https://github.com/npm/hosted-git-info/issues/44) +* **gitlab:** Do not URL encode slashes in project name for GitLab https URL ([cbf04f9](https://github.com/npm/hosted-git-info/commit/cbf04f9)), closes [#47](https://github.com/npm/hosted-git-info/issues/47) +* do not allow invalid gist urls ([d5cf830](https://github.com/npm/hosted-git-info/commit/d5cf830)) +* **cache:** Switch to lru-cache to save ourselves from unlimited memory consumption ([e518222](https://github.com/npm/hosted-git-info/commit/e518222)), closes [#38](https://github.com/npm/hosted-git-info/issues/38) + + +### Features + +* give these objects a name ([60abaea](https://github.com/npm/hosted-git-info/commit/60abaea)) + + + ## [2.7.1](https://github.com/npm/hosted-git-info/compare/v2.7.0...v2.7.1) (2018-07-07) diff --git a/node_modules/hosted-git-info/git-host-info.js b/node_modules/hosted-git-info/git-host-info.js index 090a23251fbd2..d81be2050cd56 100644 --- a/node_modules/hosted-git-info/git-host-info.js +++ b/node_modules/hosted-git-info/git-host-info.js @@ -23,12 +23,14 @@ var gitHosts = module.exports = { 'domain': 'gitlab.com', 'treepath': 'tree', 'bugstemplate': 'https://{domain}/{user}/{project}/issues', - 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}' + 'httpstemplate': 'git+https://{auth@}{domain}/{user}/{projectPath}.git{#committish}', + 'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}', + 'pathmatch': /^[/]([^/]+)[/](.+?)(?:[.]git|[/])?$/ }, gist: { 'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ], 'domain': 'gist.github.com', - 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/, + 'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]{32,})(?:[.]git)?$/, 'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}', 'bugstemplate': 'https://{domain}/{project}', 'gittemplate': 'git://{domain}/{project}.git{#committish}', @@ -40,7 +42,7 @@ var gitHosts = module.exports = { 'httpstemplate': 'git+https://{domain}/{project}.git{#committish}', 'shortcuttemplate': '{type}:{project}{#committish}', 'pathtemplate': '{project}{#committish}', - 'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz', + 'tarballtemplate': 'https://codeload.github.com/gist/{project}/tar.gz/{committish}', 'hashformat': function (fragment) { return 'file-' + formatHashFragment(fragment) } diff --git a/node_modules/hosted-git-info/git-host.js b/node_modules/hosted-git-info/git-host.js index 733648d84b6c9..ee5bb1af0ae9e 100644 --- a/node_modules/hosted-git-info/git-host.js +++ b/node_modules/hosted-git-info/git-host.js @@ -1,9 +1,24 @@ 'use strict' var gitHosts = require('./git-host-info.js') /* eslint-disable node/no-deprecated-api */ -var extend = Object.assign || require('util')._extend -var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { +// copy-pasta util._extend from node's source, to avoid pulling +// the whole util module into peoples' webpack bundles. +/* istanbul ignore next */ +var extend = Object.assign || function _extend (target, source) { + // Don't do anything if source isn't an object + if (source === null || typeof source !== 'object') return target + + const keys = Object.keys(source) + let i = keys.length + while (i--) { + target[keys[i]] = source[keys[i]] + } + return target +} + +module.exports = GitHost +function GitHost (type, user, auth, project, committish, defaultRepresentation, opts) { var gitHostInfo = this gitHostInfo.type = type Object.keys(gitHosts[type]).forEach(function (key) { @@ -16,7 +31,6 @@ var GitHost = module.exports = function (type, user, auth, project, committish, gitHostInfo.default = defaultRepresentation gitHostInfo.opts = opts || {} } -GitHost.prototype = {} GitHost.prototype.hash = function () { return this.committish ? '#' + this.committish : '' @@ -32,24 +46,33 @@ GitHost.prototype._fill = function (template, opts) { if (self[key] != null && vars[key] == null) vars[key] = self[key] }) var rawAuth = vars.auth - var rawComittish = vars.committish + var rawcommittish = vars.committish var rawFragment = vars.fragment var rawPath = vars.path + var rawProject = vars.project Object.keys(vars).forEach(function (key) { - vars[key] = encodeURIComponent(vars[key]) + var value = vars[key] + if ((key === 'path' || key === 'project') && typeof value === 'string') { + vars[key] = value.split('/').map(function (pathComponent) { + return encodeURIComponent(pathComponent) + }).join('/') + } else { + vars[key] = encodeURIComponent(value) + } }) vars['auth@'] = rawAuth ? rawAuth + '@' : '' vars['#fragment'] = rawFragment ? '#' + this.hashformat(rawFragment) : '' vars.fragment = vars.fragment ? vars.fragment : '' vars['#path'] = rawPath ? '#' + this.hashformat(rawPath) : '' vars['/path'] = vars.path ? '/' + vars.path : '' + vars.projectPath = rawProject.split('/').map(encodeURIComponent).join('/') if (opts.noCommittish) { vars['#committish'] = '' vars['/tree/committish'] = '' - vars['/comittish'] = '' - vars.comittish = '' + vars['/committish'] = '' + vars.committish = '' } else { - vars['#committish'] = rawComittish ? '#' + rawComittish : '' + vars['#committish'] = rawcommittish ? '#' + rawcommittish : '' vars['/tree/committish'] = vars.committish ? '/' + vars.treepath + '/' + vars.committish : '' @@ -114,7 +137,8 @@ GitHost.prototype.path = function (opts) { return this._fill(this.pathtemplate, opts) } -GitHost.prototype.tarball = function (opts) { +GitHost.prototype.tarball = function (opts_) { + var opts = extend({}, opts_, { noCommittish: false }) return this._fill(this.tarballtemplate, opts) } @@ -127,5 +151,6 @@ GitHost.prototype.getDefaultRepresentation = function () { } GitHost.prototype.toString = function (opts) { - return (this[this.default] || this.sshurl).call(this, opts) + if (this.default && typeof this[this.default] === 'function') return this[this.default](opts) + return this.sshurl(opts) } diff --git a/node_modules/hosted-git-info/index.js b/node_modules/hosted-git-info/index.js index c1c2cc8996b9a..adae4604c4dbd 100644 --- a/node_modules/hosted-git-info/index.js +++ b/node_modules/hosted-git-info/index.js @@ -2,17 +2,18 @@ var url = require('url') var gitHosts = require('./git-host-info.js') var GitHost = module.exports = require('./git-host.js') +var LRU = require('lru-cache') +var cache = new LRU({max: 1000}) var protocolToRepresentationMap = { - 'git+ssh': 'sshurl', - 'git+https': 'https', - 'ssh': 'sshurl', - 'git': 'git' + 'git+ssh:': 'sshurl', + 'git+https:': 'https', + 'ssh:': 'sshurl', + 'git:': 'git' } function protocolToRepresentation (protocol) { - if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1) - return protocolToRepresentationMap[protocol] || protocol + return protocolToRepresentationMap[protocol] || protocol.slice(0, -1) } var authProtocols = { @@ -23,17 +24,15 @@ var authProtocols = { 'git+http:': true } -var cache = {} - module.exports.fromUrl = function (giturl, opts) { if (typeof giturl !== 'string') return var key = giturl + JSON.stringify(opts || {}) - if (!(key in cache)) { - cache[key] = fromUrl(giturl, opts) + if (!cache.has(key)) { + cache.set(key, fromUrl(giturl, opts)) } - return cache[key] + return cache.get(key) } function fromUrl (giturl, opts) { @@ -65,13 +64,17 @@ function fromUrl (giturl, opts) { var pathmatch = gitHostInfo.pathmatch var matched = parsed.path.match(pathmatch) if (!matched) return - if (matched[1] != null) user = decodeURIComponent(matched[1].replace(/^:/, '')) - if (matched[2] != null) project = decodeURIComponent(matched[2]) + if (matched[1] !== null && matched[1] !== undefined) { + user = decodeURIComponent(matched[1].replace(/^:/, '')) + } + project = decodeURIComponent(matched[2]) defaultRepresentation = protocolToRepresentation(parsed.protocol) } return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts) } catch (ex) { - if (!(ex instanceof URIError)) throw ex + /* istanbul ignore else */ + if (ex instanceof URIError) { + } else throw ex } }).filter(function (gitHostInfo) { return gitHostInfo }) if (matches.length !== 1) return @@ -101,7 +104,6 @@ function fixupUnqualifiedGist (giturl) { } function parseGitUrl (giturl) { - if (typeof giturl !== 'string') giturl = '' + giturl var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/) if (!matched) return url.parse(giturl) return { diff --git a/node_modules/hosted-git-info/package.json b/node_modules/hosted-git-info/package.json index de1ee3d7f6422..86e7ba59a7c9c 100644 --- a/node_modules/hosted-git-info/package.json +++ b/node_modules/hosted-git-info/package.json @@ -1,19 +1,19 @@ { - "_from": "hosted-git-info@latest", - "_id": "hosted-git-info@2.7.1", + "_from": "hosted-git-info@2.8.2", + "_id": "hosted-git-info@2.8.2", "_inBundle": false, - "_integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "_integrity": "sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w==", "_location": "/hosted-git-info", "_phantomChildren": {}, "_requested": { - "type": "tag", + "type": "version", "registry": true, - "raw": "hosted-git-info@latest", + "raw": "hosted-git-info@2.8.2", "name": "hosted-git-info", "escapedName": "hosted-git-info", - "rawSpec": "latest", + "rawSpec": "2.8.2", "saveSpec": null, - "fetchSpec": "latest" + "fetchSpec": "2.8.2" }, "_requiredBy": [ "#USER", @@ -21,10 +21,10 @@ "/normalize-package-data", "/npm-package-arg" ], - "_resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "_shasum": "97f236977bd6e125408930ff6de3eec6281ec047", - "_spec": "hosted-git-info@latest", - "_where": "/Users/zkat/Documents/code/work/npm", + "_resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.2.tgz", + "_shasum": "a35c3f355ac1249f1093c0c2a542ace8818c171a", + "_spec": "hosted-git-info@2.8.2", + "_where": "/Users/isaacs/dev/npm/cli", "author": { "name": "Rebecca Turner", "email": "me@re-becca.org", @@ -34,12 +34,15 @@ "url": "https://github.com/npm/hosted-git-info/issues" }, "bundleDependencies": false, + "dependencies": { + "lru-cache": "^5.1.1" + }, "deprecated": false, "description": "Provides metadata and conversions from repository urls for Github, Bitbucket and Gitlab", "devDependencies": { "standard": "^11.0.1", - "standard-version": "^4.3.0", - "tap": "^12.0.1" + "standard-version": "^4.4.0", + "tap": "^12.7.0" }, "files": [ "index.js", @@ -65,7 +68,7 @@ "prerelease": "npm t", "pretest": "standard", "release": "standard-version -s", - "test": "tap -J --nyc-arg=--all --coverage test" + "test": "tap -J --100 --no-esm test/*.js" }, - "version": "2.7.1" + "version": "2.8.2" } diff --git a/package-lock.json b/package-lock.json index bca91e2e34205..e910fd1c1c82d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2464,9 +2464,12 @@ } }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.2.tgz", + "integrity": "sha512-CyjlXII6LMsPMyUzxpTt8fzh5QwzGqPmQXgY/Jyf4Zfp27t/FvfhwoE/8laaMUcMy816CkWF20I7NeQhwwY88w==", + "requires": { + "lru-cache": "^5.1.1" + } }, "http-cache-semantics": { "version": "3.8.1", diff --git a/package.json b/package.json index 6b802b7dbbc99..4a30cdd8eb565 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "glob": "^7.1.4", "graceful-fs": "^4.2.0", "has-unicode": "~2.0.1", - "hosted-git-info": "^2.7.1", + "hosted-git-info": "^2.8.2", "iferr": "^1.0.2", "infer-owner": "^1.0.4", "inflight": "~1.0.6", From 586c938f974d4e0763812956a834b2128aa2c726 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 5 Aug 2019 09:56:04 -0700 Subject: [PATCH 15/17] doc: changelog 6.10.3 update --- CHANGELOG.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8795a1454f5..e843fcaef659a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ * [`d5e865eb7`](https://github.com/npm/cli/commit/d5e865eb79329665a927cc2767b4395c03045dbb) [#222](https://github.com/npm/cli/pull/222) [#226](https://github.com/npm/cli/pull/226) install, doctor: don't crash - if registry unset ([@isaacs](https://github.com/isaacs)) + if registry unset ([@dmitrydvorkin](https://github.com/dmitrydvorkin), + [@isaacs](https://github.com/isaacs)) * [`5b3890226`](https://github.com/npm/cli/commit/5b389022652abeb0e1c278a152550eb95bc6c452) [#227](https://github.com/npm/cli/pull/227) [npm.community#9167](https://npm.community/t/npm-err-cb-never-called-permission-denied/9167/5) @@ -21,6 +22,30 @@ `licensee@7.0.3` ([@isaacs](https://github.com/isaacs)) * [`ceb993590`](https://github.com/npm/cli/commit/ceb993590e4e376a9a78264ce7bb4327fbbb37fe) `query-string@6.8.2` ([@isaacs](https://github.com/isaacs)) +* [`4050b9189`](https://github.com/npm/cli/commit/4050b91898c60e9b22998cf82b70b9b822de592a) + `hosted-git-info@2.8.2` + * [#46](https://github.com/npm/hosted-git-info/issues/46) + [#43](https://github.com/npm/hosted-git-info/issues/43) + [#47](https://github.com/npm/hosted-git-info/pull/47) + [#44](https://github.com/npm/hosted-git-info/pull/44) Add support for + GitLab subgroups ([@mterrel](https://github.com/mterrel), + [@isaacs](https://github.com/isaacs), + [@ybiquitous](https://github.com/ybiquitous)) + * [`3b1d629`](https://github.com/npm/hosted-git-info/commit/3b1d629) + [#48](https://github.com/npm/hosted-git-info/issues/48) fix http + protocol using sshurl by default + ([@fengmk2](https://github.com/fengmk2)) + * [`5d4a8d7`](https://github.com/npm/hosted-git-info/commit/5d4a8d7) + ignore noCommittish on tarball url generation + ([@isaacs](https://github.com/isaacs)) + * [`1692435`](https://github.com/npm/hosted-git-info/commit/1692435) + use gist tarball url that works for anonymous gists + ([@isaacs](https://github.com/isaacs)) + * [`d5cf830`](https://github.com/npm/hosted-git-info/commit/d5cf8309be7af884032616c63ea302ce49dd321c) + Do not allow invalid gist urls ([@isaacs](https://github.com/isaacs)) + * [`e518222`](https://github.com/npm/hosted-git-info/commit/e5182224351183ce619dd5ef00019ae700ed37b7) + Use LRU cache to prevent unbounded memory consumption + ([@iarna](https://github.com/iarna)) ## v6.10.2 (2019-07-23): From d2eaf0bff7ecc9e996bd24c20eb987f1e0d77b33 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 6 Aug 2019 09:14:44 -0700 Subject: [PATCH 16/17] update AUTHORS --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index e50da41e47212..69e158001e92f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -649,3 +649,6 @@ Iván Reinoso García Roy Marples Robert James Gabriel John Firebaugh +Kitten King +claudiahdz +Artem Sapegin From 897537ab08261fe4323b0d079047507dba62bc11 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 6 Aug 2019 09:14:45 -0700 Subject: [PATCH 17/17] 6.10.3 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e910fd1c1c82d..0cc22483e134e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "npm", - "version": "6.10.2", + "version": "6.10.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4a30cdd8eb565..58631e96bb75d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "6.10.2", + "version": "6.10.3", "name": "npm", "description": "a package manager for JavaScript", "keywords": [