Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: upgrade npm to 9.2.0 #45780

Merged
merged 1 commit into from Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 5 additions & 3 deletions deps/npm/docs/content/commands/npm-doctor.md
Expand Up @@ -7,7 +7,7 @@ description: Check your npm environment
### Synopsis

```bash
npm doctor
npm doctor [ping] [registry] [versions] [environment] [permissions] [cache]
```

Note: This command is unaware of workspaces.
Expand All @@ -33,8 +33,10 @@ Also, in addition to this, there are also very many issue reports due to
using old versions of npm. Since npm is constantly improving, running
`npm@latest` is better than an old version.

`npm doctor` verifies the following items in your environment, and if there
are any recommended changes, it will display them.
`npm doctor` verifies the following items in your environment, and if
there are any recommended changes, it will display them. By default npm
runs all of these checks. You can limit what checks are ran by
specifying them as extra arguments.

#### `npm ping`

Expand Down
2 changes: 1 addition & 1 deletion deps/npm/docs/content/commands/npm-ls.md
Expand Up @@ -27,7 +27,7 @@ packages will *also* show the paths to the specified packages. For
example, running `npm ls promzard` in npm's source tree will show:

```bash
npm@9.1.3 /path/to/npm
npm@9.2.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
```
Expand Down
2 changes: 1 addition & 1 deletion deps/npm/docs/content/commands/npm.md
Expand Up @@ -12,7 +12,7 @@ npm

### Version

9.1.3
9.2.0

### Description

Expand Down
8 changes: 5 additions & 3 deletions deps/npm/docs/output/commands/npm-doctor.html
Expand Up @@ -146,7 +146,7 @@ <h2 id="table-of-contents">Table of contents</h2>
</section>

<div id="_content"><h3 id="synopsis">Synopsis</h3>
<pre><code class="language-bash">npm doctor
<pre><code class="language-bash">npm doctor [ping] [registry] [versions] [environment] [permissions] [cache]
</code></pre>
<p>Note: This command is unaware of workspaces.</p>
<h3 id="description">Description</h3>
Expand All @@ -167,8 +167,10 @@ <h3 id="description">Description</h3>
<p>Also, in addition to this, there are also very many issue reports due to
using old versions of npm. Since npm is constantly improving, running
<code>npm@latest</code> is better than an old version.</p>
<p><code>npm doctor</code> verifies the following items in your environment, and if there
are any recommended changes, it will display them.</p>
<p><code>npm doctor</code> verifies the following items in your environment, and if
there are any recommended changes, it will display them. By default npm
runs all of these checks. You can limit what checks are ran by
specifying them as extra arguments.</p>
<h4 id="npm-ping"><code>npm ping</code></h4>
<p>By default, npm installs from the primary npm registry,
<code>registry.npmjs.org</code>. <code>npm doctor</code> hits a special ping endpoint within the
Expand Down
2 changes: 1 addition & 1 deletion deps/npm/docs/output/commands/npm-ls.html
Expand Up @@ -160,7 +160,7 @@ <h3 id="description">Description</h3>
the results to only the paths to the packages named. Note that nested
packages will <em>also</em> show the paths to the specified packages. For
example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
<pre><code class="language-bash">npm@9.1.3 /path/to/npm
<pre><code class="language-bash">npm@9.2.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
</code></pre>
Expand Down
2 changes: 1 addition & 1 deletion deps/npm/docs/output/commands/npm.html
Expand Up @@ -149,7 +149,7 @@ <h2 id="table-of-contents">Table of contents</h2>
<pre><code class="language-bash">npm
</code></pre>
<h3 id="version">Version</h3>
<p>9.1.3</p>
<p>9.2.0</p>
<h3 id="description">Description</h3>
<p>npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
Expand Down
2 changes: 1 addition & 1 deletion deps/npm/lib/commands/completion.js
Expand Up @@ -54,7 +54,7 @@ const BaseCommand = require('../base-command.js')
class Completion extends BaseCommand {
static description = 'Tab Completion for npm'
static name = 'completion'
static ignoreImplicitWorkspace = false
static ignoreImplicitWorkspace = true

// completion for the completion command
async completion (opts) {
Expand Down
230 changes: 162 additions & 68 deletions deps/npm/lib/commands/doctor.js
@@ -1,14 +1,13 @@
const cacache = require('cacache')
const fs = require('fs')
const fetch = require('make-fetch-happen')
const table = require('text-table')
const Table = require('cli-table3')
const which = require('which')
const pacote = require('pacote')
const { resolve } = require('path')
const semver = require('semver')
const { promisify } = require('util')
const log = require('../utils/log-shim.js')
const ansiTrim = require('../utils/ansi-trim.js')
const ping = require('../utils/ping.js')
const {
registry: { default: defaultRegistry },
Expand All @@ -17,6 +16,7 @@ const lstat = promisify(fs.lstat)
const readdir = promisify(fs.readdir)
const access = promisify(fs.access)
const { R_OK, W_OK, X_OK } = fs.constants

const maskLabel = mask => {
const label = []
if (mask & R_OK) {
Expand All @@ -34,76 +34,105 @@ const maskLabel = mask => {
return label.join(', ')
}

const subcommands = [
{
groups: ['ping', 'registry'],
title: 'npm ping',
cmd: 'checkPing',
}, {
groups: ['versions'],
title: 'npm -v',
cmd: 'getLatestNpmVersion',
}, {
groups: ['versions'],
title: 'node -v',
cmd: 'getLatestNodejsVersion',
}, {
groups: ['registry'],
title: 'npm config get registry',
cmd: 'checkNpmRegistry',
}, {
groups: ['environment'],
title: 'git executable in PATH',
cmd: 'getGitPath',
}, {
groups: ['environment'],
title: 'global bin folder in PATH',
cmd: 'getBinPath',
}, {
groups: ['permissions', 'cache'],
title: 'Perms check on cached files',
cmd: 'checkCachePermission',
windows: false,
}, {
groups: ['permissions'],
title: 'Perms check on local node_modules',
cmd: 'checkLocalModulesPermission',
windows: false,
}, {
groups: ['permissions'],
title: 'Perms check on global node_modules',
cmd: 'checkGlobalModulesPermission',
windows: false,
}, {
groups: ['permissions'],
title: 'Perms check on local bin folder',
cmd: 'checkLocalBinPermission',
windows: false,
}, {
groups: ['permissions'],
title: 'Perms check on global bin folder',
cmd: 'checkGlobalBinPermission',
windows: false,
}, {
groups: ['cache'],
title: 'Verify cache contents',
cmd: 'verifyCachedFiles',
windows: false,
},
// TODO:
// group === 'dependencies'?
// - ensure arborist.loadActual() runs without errors and no invalid edges
// - ensure package-lock.json matches loadActual()
// - verify loadActual without hidden lock file matches hidden lockfile
// group === '???'
// - verify all local packages have bins linked
// What is the fix for these?
]
const BaseCommand = require('../base-command.js')
class Doctor extends BaseCommand {
static description = 'Check your npm environment'
static name = 'doctor'
static params = ['registry']
static ignoreImplicitWorkspace = false
static usage = [`[${subcommands.flatMap(s => s.groups)
.filter((value, index, self) => self.indexOf(value) === index)
.join('] [')}]`]

static subcommands = subcommands

// minimum width of check column, enough for the word `Check`
#checkWidth = 5

async exec (args) {
log.info('Running checkup')
let allOk = true

// each message is [title, ok, message]
const messages = []

const actions = [
['npm ping', 'checkPing', []],
['npm -v', 'getLatestNpmVersion', []],
['node -v', 'getLatestNodejsVersion', []],
['npm config get registry', 'checkNpmRegistry', []],
['which git', 'getGitPath', []],
...(process.platform === 'win32'
? []
: [
[
'Perms check on cached files',
'checkFilesPermission',
[this.npm.cache, true, R_OK],
], [
'Perms check on local node_modules',
'checkFilesPermission',
[this.npm.localDir, true, R_OK | W_OK, true],
], [
'Perms check on global node_modules',
'checkFilesPermission',
[this.npm.globalDir, false, R_OK],
], [
'Perms check on local bin folder',
'checkFilesPermission',
[this.npm.localBin, false, R_OK | W_OK | X_OK, true],
], [
'Perms check on global bin folder',
'checkFilesPermission',
[this.npm.globalBin, false, X_OK],
],
]),
[
'Verify cache contents',
'verifyCachedFiles',
[this.npm.flatOptions.cache],
],
// TODO:
// - ensure arborist.loadActual() runs without errors and no invalid edges
// - ensure package-lock.json matches loadActual()
// - verify loadActual without hidden lock file matches hidden lockfile
// - verify all local packages have bins linked
]
const actions = this.actions(args)
this.#checkWidth = actions.reduce((length, item) =>
Math.max(item.title.length, length), this.#checkWidth)

if (!this.npm.silent) {
this.output(['Check', 'Value', 'Recommendation/Notes'].map(h => this.npm.chalk.underline(h)))
}
// Do the actual work
for (const [msg, fn, args] of actions) {
const line = [msg]
for (const { title, cmd } of actions) {
const item = [title]
try {
line.push(true, await this[fn](...args))
} catch (er) {
line.push(false, er)
item.push(true, await this[cmd]())
} catch (err) {
item.push(false, err)
}
messages.push(line)
}

const outHead = ['Check', 'Value', 'Recommendation/Notes'].map(h => this.npm.chalk.underline(h))
let allOk = true
const outBody = messages.map(item => {
if (!item[1]) {
allOk = false
item[0] = this.npm.chalk.red(item[0])
Expand All @@ -112,18 +141,18 @@ class Doctor extends BaseCommand {
} else {
item[1] = this.npm.chalk.green('ok')
}
return item
})
const outTable = [outHead, ...outBody]
const tableOpts = {
stringLength: s => ansiTrim(s).length,
if (!this.npm.silent) {
this.output(item)
}
}

if (!this.npm.silent) {
this.npm.output(table(outTable, tableOpts))
}
if (!allOk) {
throw new Error('Some problems found. See above for recommendations.')
if (this.npm.silent) {
/* eslint-disable-next-line max-len */
throw new Error('Some problems found. Check logs or disable silent mode for recommendations.')
} else {
throw new Error('Some problems found. See above for recommendations.')
}
}
}

Expand Down Expand Up @@ -191,6 +220,35 @@ class Doctor extends BaseCommand {
}
}

async getBinPath (dir) {
const tracker = log.newItem('getBinPath', 1)
tracker.info('getBinPath', 'Finding npm global bin in your PATH')
if (!process.env.PATH.includes(this.npm.globalBin)) {
throw new Error(`Add ${this.npm.globalBin} to your $PATH`)
}
return this.npm.globalBin
}

async checkCachePermission () {
return this.checkFilesPermission(this.npm.cache, true, R_OK)
}

async checkLocalModulesPermission () {
return this.checkFilesPermission(this.npm.localDir, true, R_OK | W_OK, true)
}

async checkGlobalModulesPermission () {
return this.checkFilesPermission(this.npm.globalDir, false, R_OK)
}

async checkLocalBinPermission () {
return this.checkFilesPermission(this.npm.localBin, false, R_OK | W_OK | X_OK, true)
}

async checkGlobalBinPermission () {
return this.checkFilesPermission(this.npm.globalBin, false, X_OK)
}

async checkFilesPermission (root, shouldOwn, mask, missingOk) {
let ok = true

Expand Down Expand Up @@ -264,7 +322,7 @@ class Doctor extends BaseCommand {
try {
return await which('git').catch(er => {
tracker.warn(er)
throw "Install git and ensure it's in your PATH."
throw new Error("Install git and ensure it's in your PATH.")
})
} finally {
tracker.finish()
Expand Down Expand Up @@ -312,6 +370,42 @@ class Doctor extends BaseCommand {
return `using default registry (${defaultRegistry})`
}
}

output (row) {
const t = new Table({
chars: { top: '',
'top-mid': '',
'top-left': '',
'top-right': '',
bottom: '',
'bottom-mid': '',
'bottom-left': '',
'bottom-right': '',
left: '',
'left-mid': '',
mid: '',
'mid-mid': '',
right: '',
'right-mid': '',
middle: ' ' },
style: { 'padding-left': 0, 'padding-right': 0 },
colWidths: [this.#checkWidth, 6],
})
t.push(row)
this.npm.output(t.toString())
}

actions (params) {
return this.constructor.subcommands.filter(subcmd => {
if (process.platform === 'win32' && subcmd.windows === false) {
return false
}
if (params.length) {
return params.some(param => subcmd.groups.includes(param))
}
return true
})
}
}

module.exports = Doctor
2 changes: 1 addition & 1 deletion deps/npm/man/man1/npm-access.1
@@ -1,4 +1,4 @@
.TH "NPM-ACCESS" "1" "November 2022" "" ""
.TH "NPM-ACCESS" "1" "December 2022" "" ""
.SH "NAME"
\fBnpm-access\fR - Set access level on published packages
.SS "Synopsis"
Expand Down