Skip to content

Commit

Permalink
feat: add pnpm doctor command to do checks for known common issues (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
lvqq committed Oct 22, 2022
1 parent 804de21 commit bea0acd
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 11 deletions.
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.

0 comments on commit bea0acd

Please sign in to comment.