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 4 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
5 changes: 5 additions & 0 deletions .changeset/gentle-lobsters-sit.md
@@ -0,0 +1,5 @@
---
"pnpm": minor
---

Add `pnpm doctor` command to do checks for known common issues
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": "1.0.0",
lvqq marked this conversation as resolved.
Show resolved Hide resolved
"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/npm-conf": "2.0.2",
"render-help": "^1.0.2"
},
"funding": "https://opencollective.com/pnpm",
"exports": {
".": "./lib/index.js"
},
"peerDependencies": {
"@pnpm/logger": "^5.0.0"
},
"devDependencies": {
"@pnpm/plugin-commands-doctor": "workspace:*"
}
}
60 changes: 60 additions & 0 deletions packages/plugin-commands-doctor/src/doctor.ts
@@ -0,0 +1,60 @@
import renderHelp from 'render-help'
import { docsUrl } from '@pnpm/cli-utils'
import { logger } from '@pnpm/logger'
import loadNpmConf from '@pnpm/npm-conf'

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',
lvqq marked this conversation as resolved.
Show resolved Hide resolved
},
],
},
],
url: docsUrl('doctor'),
usages: ['pnpm doctor [options]'],
})
}

export async function handler (
opts: {
config: boolean
}) {
if (opts.config) {
const { failedToLoadBuiltInConfig } = loadNpmConf()
lvqq marked this conversation as resolved.
Show resolved Hide resolved
if (
// If error, means loading npm builtin config failed
failedToLoadBuiltInConfig &&
// Npm installed via brew may have prefix error, related: https://github.com/pnpm/pnpm/issues/5404
process.platform === 'darwin' &&
process.env.HOMEBREW_PREFIX &&
process.execPath.startsWith(process.env.HOMEBREW_PREFIX)
) {
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 }
40 changes: 40 additions & 0 deletions packages/plugin-commands-doctor/test/index.ts
@@ -0,0 +1,40 @@
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 --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',
})

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

expect(logger.warn).toHaveBeenCalledWith({
message: expect.stringMatching(/^Load npm builtin configs failed./),
prefix: process.cwd(),
})

process.env = oldEnv
process.execPath = oldExecPath
Object.defineProperty(process, 'platform', {
value: oldPlatform,
})
})
16 changes: 16 additions & 0 deletions packages/plugin-commands-doctor/tsconfig.json
@@ -0,0 +1,16 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../typings/**/*.d.ts"
],
"references": [
{
"path": "../cli-utils"
}
]
}
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
32 changes: 32 additions & 0 deletions pnpm-lock.yaml

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