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

feat: add pnpm doctor command to do checks for known common issues #5526

Merged
merged 7 commits into from Oct 22, 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
7 changes: 7 additions & 0 deletions .changeset/selfish-socks-camp.md
@@ -0,0 +1,7 @@
---
"@pnpm/plugin-commands-doctor": major
"pnpm": minor
"@pnpm/config": patch
---

Add `pnpm doctor` command to do checks for known common issues
2 changes: 1 addition & 1 deletion packages/config/package.json
Expand Up @@ -36,7 +36,7 @@
"@pnpm/error": "workspace:*",
"@pnpm/git-utils": "workspace:*",
"@pnpm/matcher": "workspace:*",
"@pnpm/npm-conf": "2.0.0",
"@pnpm/npm-conf": "2.0.2",
"@pnpm/pnpmfile": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/types": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions packages/config/src/Config.ts
Expand Up @@ -86,6 +86,7 @@ export interface Config {
preferSymlinkedExecutables?: boolean
resolutionMode?: 'highest' | 'time-based'
registrySupportsTimeField?: boolean
failedToLoadBuiltInConfig: boolean

// proxy
httpProxy?: string
Expand Down
4 changes: 3 additions & 1 deletion packages/config/src/index.ts
Expand Up @@ -181,7 +181,7 @@ export async function getConfig (
cliOptions['prefix'] = cliOptions.dir // the npm config system still expects `prefix`
}
const rcOptionsTypes = { ...types, ...opts.rcOptionsTypes }
const { config: npmConfig, warnings } = loadNpmConf(cliOptions, rcOptionsTypes, {
const { config: npmConfig, warnings, failedToLoadBuiltInConfig } = loadNpmConf(cliOptions, rcOptionsTypes, {
'auto-install-peers': false,
bail: true,
color: 'auto',
Expand Down Expand Up @@ -526,6 +526,8 @@ export async function getConfig (
}
pnpmConfig.rootProjectManifest = await safeReadProjectManifestOnly(pnpmConfig.lockfileDir ?? pnpmConfig.dir) ?? undefined

pnpmConfig.failedToLoadBuiltInConfig = failedToLoadBuiltInConfig

return { config: pnpmConfig, warnings }
}

Expand Down
12 changes: 12 additions & 0 deletions packages/config/test/index.ts
Expand Up @@ -929,3 +929,15 @@ test('return a warning when the .npmrc has an env variable that does not exist',

expect(warnings).toEqual(expect.arrayContaining(expected))
})

test('getConfig() returns failedToLoadBuiltInConfig', async () => {
const { config } = await getConfig({
cliOptions: {},
packageManager: {
name: 'pnpm',
version: '1.0.0',
},
})

expect(config.failedToLoadBuiltInConfig).toBeDefined()
})
15 changes: 15 additions & 0 deletions packages/plugin-commands-doctor/README.md
@@ -0,0 +1,15 @@
# @pnpm/plugin-commands-doctor

> pnpm commands for checks of known common issues

[![npm version](https://img.shields.io/npm/v/@pnpm/plugin-commands-doctor.svg)](https://www.npmjs.com/package/@pnpm/plugin-commands-doctor)

## Installation

```sh
pnpm add @pnpm/plugin-commands-doctor
```

## License

MIT
1 change: 1 addition & 0 deletions packages/plugin-commands-doctor/jest.config.js
@@ -0,0 +1 @@
module.exports = require('../../jest.config.js')
47 changes: 47 additions & 0 deletions packages/plugin-commands-doctor/package.json
@@ -0,0 +1,47 @@
{
"name": "@pnpm/plugin-commands-doctor",
"version": "0.0.0",
"description": "Commands for checks of known common issues ",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib",
"!*.map"
],
"engines": {
"node": ">=14.6"
},
"scripts": {
"lint": "eslint src/**/*.ts test/**/*.ts",
"_test": "jest",
"test": "pnpm run compile && pnpm run _test",
"prepublishOnly": "pnpm run compile",
"compile": "tsc --build && pnpm run lint --fix"
},
"repository": "https://github.com/pnpm/pnpm/blob/main/packages/plugin-commands-doctor",
"keywords": [
"pnpm7",
"pnpm",
"doctor"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/packages/plugin-commands-doctor#readme",
"dependencies": {
"@pnpm/cli-utils": "workspace:*",
"@pnpm/config": "workspace:*",
"render-help": "^1.0.2"
},
"peerDependencies": {
"@pnpm/logger": "^5.0.0"
},
"devDependencies": {
"@pnpm/plugin-commands-doctor": "workspace:*"
},
"funding": "https://opencollective.com/pnpm",
"exports": {
".": "./lib/index.js"
}
}
35 changes: 35 additions & 0 deletions packages/plugin-commands-doctor/src/doctor.ts
@@ -0,0 +1,35 @@
import renderHelp from 'render-help'
import { docsUrl } from '@pnpm/cli-utils'
import { logger } from '@pnpm/logger'
import { Config } from '@pnpm/config'

export const rcOptionsTypes = cliOptionsTypes

export function cliOptionsTypes () {
return {}
}

export const shorthands = {}

export const commandNames = ['doctor']

export function help () {
return renderHelp({
description: 'Checks for known common issues.',
url: docsUrl('doctor'),
usages: ['pnpm doctor [options]'],
})
}

export async function handler (
opts: Pick<Config, 'failedToLoadBuiltInConfig'>
) {
const { failedToLoadBuiltInConfig } = opts
if (failedToLoadBuiltInConfig) {
// If true, means loading npm builtin config failed. Then there may have a 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 <key> <value>" to migrate configs from builtin to global.',
prefix: process.cwd(),
})
}
}
3 changes: 3 additions & 0 deletions packages/plugin-commands-doctor/src/index.ts
@@ -0,0 +1,3 @@
import * as doctor from './doctor'

export { doctor }
22 changes: 22 additions & 0 deletions packages/plugin-commands-doctor/test/index.ts
@@ -0,0 +1,22 @@
import { doctor } from '@pnpm/plugin-commands-doctor'
import { logger } from '@pnpm/logger'

beforeEach(() => {
jest.spyOn(logger, 'warn')
})

afterEach(() => {
(logger.warn as jest.Mock).mockRestore()
})

test('doctor', async () => {
// In the scope of jest, require.resolve.paths('npm') cannot reach global npm path by default
await doctor.handler({
failedToLoadBuiltInConfig: true,
})

expect(logger.warn).toHaveBeenCalledWith({
message: expect.stringMatching(/^Load npm builtin configs failed./),
prefix: process.cwd(),
})
})
19 changes: 19 additions & 0 deletions packages/plugin-commands-doctor/tsconfig.json
@@ -0,0 +1,19 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../typings/**/*.d.ts"
],
"references": [
{
"path": "../cli-utils"
},
{
"path": "../config"
}
]
}
8 changes: 8 additions & 0 deletions packages/plugin-commands-doctor/tsconfig.lint.json
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"test/**/*.ts",
"../../typings/**/*.d.ts"
]
}
1 change: 1 addition & 0 deletions packages/pnpm/package.json
Expand Up @@ -41,6 +41,7 @@
"@pnpm/pick-registry-for-package": "workspace:*",
"@pnpm/plugin-commands-audit": "workspace:*",
"@pnpm/plugin-commands-deploy": "workspace:*",
"@pnpm/plugin-commands-doctor": "workspace:*",
"@pnpm/plugin-commands-env": "workspace:*",
"@pnpm/plugin-commands-init": "workspace:*",
"@pnpm/plugin-commands-installation": "workspace:*",
Expand Down
2 changes: 2 additions & 0 deletions packages/pnpm/src/cmd/index.ts
@@ -1,6 +1,7 @@
import { CompletionFunc } from '@pnpm/command'
import { types as allTypes } from '@pnpm/config'
import { audit } from '@pnpm/plugin-commands-audit'
import { doctor } from '@pnpm/plugin-commands-doctor'
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'
Expand Down Expand Up @@ -100,6 +101,7 @@ const commands: CommandDefinition[] = [
create,
deploy,
dlx,
doctor,
env,
exec,
fetch,
Expand Down
3 changes: 3 additions & 0 deletions packages/pnpm/tsconfig.json
Expand Up @@ -78,6 +78,9 @@
{
"path": "../plugin-commands-deploy"
},
{
"path": "../plugin-commands-doctor"
},
{
"path": "../plugin-commands-env"
},
Expand Down
41 changes: 32 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.