From 6bc9d95ce71420cbb498ebc771c3968f31e83c62 Mon Sep 17 00:00:00 2001 From: lvqq Date: Thu, 20 Oct 2022 08:55:13 +0800 Subject: [PATCH] feat: add `pnpm doctor` command to do checks for know common issues --- .changeset/gentle-lobsters-sit.md | 6 ++ packages/plugin-commands-audit/package.json | 5 ++ packages/plugin-commands-audit/src/doctor.ts | 62 +++++++++++++++++++ packages/plugin-commands-audit/src/index.ts | 6 +- packages/plugin-commands-audit/test/doctor.ts | 35 +++++++++++ packages/pnpm/src/cmd/index.ts | 6 +- pnpm-lock.yaml | 10 +++ 7 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 .changeset/gentle-lobsters-sit.md create mode 100644 packages/plugin-commands-audit/src/doctor.ts create mode 100644 packages/plugin-commands-audit/test/doctor.ts diff --git a/.changeset/gentle-lobsters-sit.md b/.changeset/gentle-lobsters-sit.md new file mode 100644 index 00000000000..eb36f414263 --- /dev/null +++ b/.changeset/gentle-lobsters-sit.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-audit": minor +"pnpm": minor +--- + +Add `pnpm doctor` command to do checks for know common issues diff --git a/packages/plugin-commands-audit/package.json b/packages/plugin-commands-audit/package.json index e92dd642c44..2b3042c28a9 100644 --- a/packages/plugin-commands-audit/package.json +++ b/packages/plugin-commands-audit/package.json @@ -34,9 +34,11 @@ "@pnpm/plugin-commands-audit": "workspace:*", "@pnpm/test-fixtures": "workspace:*", "@types/ramda": "0.28.15", + "@types/sinon": "^10.0.13", "@types/zkochan__table": "npm:@types/table@6.0.0", "load-json-file": "^6.2.0", "nock": "13.2.9", + "sinon": "^14.0.1", "strip-ansi": "^6.0.1", "tempy": "^1.0.1" }, @@ -59,5 +61,8 @@ "funding": "https://opencollective.com/pnpm", "exports": { ".": "./lib/index.js" + }, + "peerDependencies": { + "@pnpm/logger": "^5.0.0" } } diff --git a/packages/plugin-commands-audit/src/doctor.ts b/packages/plugin-commands-audit/src/doctor.ts new file mode 100644 index 00000000000..8a4629f20f1 --- /dev/null +++ b/packages/plugin-commands-audit/src/doctor.ts @@ -0,0 +1,62 @@ +import renderHelp from 'render-help' +import { docsUrl } from '@pnpm/cli-utils' +import { logger } from '@pnpm/logger' + +export const rcOptionsTypes = cliOptionsTypes + +export function cliOptionsTypes () { + return { + config: Boolean, + } +} + +export const shorthands = { + C: '--config', +} + +export const commandNames = ['doctor'] + +export function help () { + return renderHelp({ + description: 'Checks for known common issues.', + descriptionLists: [ + { + title: 'Options', + list: [ + { + description: 'Check the global config', + name: '--config', + shortAlias: '-C', + }, + ], + }, + ], + url: docsUrl('doctor'), + usages: ['pnpm doctor [options]'], + }) +} + +export async function handler ( + opts: { + config: boolean + }) { + if (opts.config) { + const paths = require.resolve.paths('npm') + try { + require.resolve('npm', { paths: paths?.slice(-1) }) + } catch (e) { + // If error, means loading npm builtin config failed + if ( + process.platform === 'darwin' && + process.env.HOMEBREW_PREFIX && + process.execPath.startsWith(process.env.HOMEBREW_PREFIX) + ) { + // Npm installed via brew may have prefix error, related: https://github.com/pnpm/pnpm/issues/5404 + logger.warn({ + message: 'Load npm builtin configs failed. If the prefix builtin config does not work, you can use "pnpm config ls" to show builtin configs. And then use "pnpm config --global set " to migrate configs from builtin to global.', + prefix: process.cwd(), + }) + } + } + } +} \ No newline at end of file diff --git a/packages/plugin-commands-audit/src/index.ts b/packages/plugin-commands-audit/src/index.ts index bf21e69be18..2c2a7347ee1 100644 --- a/packages/plugin-commands-audit/src/index.ts +++ b/packages/plugin-commands-audit/src/index.ts @@ -1,3 +1,7 @@ import * as audit from './audit' +import * as doctor from './doctor' -export { audit } +export { + audit, + doctor, +} diff --git a/packages/plugin-commands-audit/test/doctor.ts b/packages/plugin-commands-audit/test/doctor.ts new file mode 100644 index 00000000000..387a587fadb --- /dev/null +++ b/packages/plugin-commands-audit/test/doctor.ts @@ -0,0 +1,35 @@ +import { doctor } from '@pnpm/plugin-commands-audit' +import sinon from 'sinon' +import { logger } from '@pnpm/logger' + +test('doctor --config', async () => { + const oldExecPath = process.execPath + const oldPlatform = process.platform + const oldEnv = process.env + const HOMEBREW_PREFIX = '.' + + process.env = { ...oldEnv, HOMEBREW_PREFIX } + process.execPath = HOMEBREW_PREFIX + // platform is read only + Object.defineProperty(process, 'platform', { + value: 'darwin', + }) + + const reporter = sinon.spy(logger, 'warn') + + // In the scope of jest, require.resolve.paths('npm') cannot reach global npm path by default + await doctor.handler({ + config: true, + }) + + expect(reporter.calledWithMatch({ + message: 'Load npm builtin configs failed. If the prefix builtin config does not work, you can use "pnpm config ls" to show builtin configs. And then use "pnpm config --global set " to migrate configs from builtin to global.', + prefix: process.cwd(), + })).toBeTruthy() + + process.env = oldEnv + process.execPath = oldExecPath + Object.defineProperty(process, 'platform', { + value: oldPlatform, + }) +}) \ No newline at end of file diff --git a/packages/pnpm/src/cmd/index.ts b/packages/pnpm/src/cmd/index.ts index c72b2c26dce..2c086397b50 100644 --- a/packages/pnpm/src/cmd/index.ts +++ b/packages/pnpm/src/cmd/index.ts @@ -1,6 +1,9 @@ import { CompletionFunc } from '@pnpm/command' import { types as allTypes } from '@pnpm/config' -import { audit } from '@pnpm/plugin-commands-audit' +import { + audit, + doctor, +} from '@pnpm/plugin-commands-audit' import { env } from '@pnpm/plugin-commands-env' import { deploy } from '@pnpm/plugin-commands-deploy' import { add, fetch, install, link, prune, remove, unlink, update, importCommand } from '@pnpm/plugin-commands-installation' @@ -100,6 +103,7 @@ const commands: CommandDefinition[] = [ create, deploy, dlx, + doctor, env, exec, fetch, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62aa53364a0..5744df2a9d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3001,6 +3001,9 @@ importers: '@pnpm/lockfile-file': specifier: workspace:* version: link:../lockfile-file + '@pnpm/logger': + specifier: ^5.0.0 + version: 5.0.0 '@pnpm/read-project-manifest': specifier: workspace:* version: link:../read-project-manifest @@ -3035,6 +3038,9 @@ importers: '@types/ramda': specifier: 0.28.15 version: 0.28.15 + '@types/sinon': + specifier: ^10.0.13 + version: 10.0.13 '@types/zkochan__table': specifier: npm:@types/table@6.0.0 version: /@types/table/6.0.0 @@ -3044,6 +3050,9 @@ importers: nock: specifier: 13.2.9 version: 13.2.9 + sinon: + specifier: ^14.0.1 + version: 14.0.1 strip-ansi: specifier: ^6.0.1 version: 6.0.1 @@ -16746,6 +16755,7 @@ packages: /w3c-hr-time/1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. dependencies: browser-process-hrtime: 1.0.0