fix: pnpm exec should use the right Node.js version (#3477)

This commit is contained in:
Zoltan Kochan
2021-05-27 02:00:26 +03:00
committed by GitHub
parent 7aa9f13a9b
commit c1f137412c
13 changed files with 68 additions and 103 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/plugin-commands-nvm": minor
---
Remove the `pnpm node [args...]` command.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/plugin-commands-script-runners": patch
---
`pnpm exec` should add `node_modules/.bin` to the PATH.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/plugin-commands-script-runners": patch
---
`pnpm exec` should add the Node.js location to the PATH.

View File

@@ -29,18 +29,14 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/master/packages/plugin-commands-nvm#readme",
"dependencies": {
"@pnpm/cli-utils": "workspace:0.6.5",
"@pnpm/config": "workspace:12.3.0",
"@pnpm/fetch": "workspace:3.1.0",
"@pnpm/package-store": "workspace:12.0.7",
"@pnpm/store-path": "^5.0.0",
"@pnpm/tarball-fetcher": "workspace:9.2.2",
"adm-zip": "^0.5.5",
"execa": "^5.0.0",
"load-json-file": "^6.2.0",
"path-name": "^1.0.0",
"rename-overwrite": "^4.0.0",
"render-help": "^1.0.1",
"tempy": "^1.0.0",
"write-json-file": "^4.3.0"
},

View File

@@ -1,37 +1,16 @@
import fs from 'fs'
import path from 'path'
import { docsUrl } from '@pnpm/cli-utils'
import { Config } from '@pnpm/config'
import fetch, { createFetchFromRegistry, FetchFromRegistry } from '@pnpm/fetch'
import { createCafsStore } from '@pnpm/package-store'
import storePath from '@pnpm/store-path'
import createFetcher, { waitForFilesIndex } from '@pnpm/tarball-fetcher'
import AdmZip from 'adm-zip'
import execa from 'execa'
import PATH from 'path-name'
import renameOverwrite from 'rename-overwrite'
import renderHelp from 'render-help'
import tempy from 'tempy'
import loadJsonFile from 'load-json-file'
import writeJsonFile from 'write-json-file'
export const rcOptionsTypes = () => ({})
export const cliOptionsTypes = () => ({})
export const shorthands = {}
export const commandNames = ['node']
export function help () {
return renderHelp({
description: 'Run Node.js',
descriptionLists: [],
url: docsUrl('node'),
usages: ['pnpm node'],
})
}
export type NvmNodeCommandOptions = Pick<Config,
| 'rawConfig'
| 'fetchRetries'
@@ -54,24 +33,6 @@ export type NvmNodeCommandOptions = Pick<Config,
| 'pnpmHomeDir'
>
export async function handler (
opts: NvmNodeCommandOptions & {
argv: {
original: string[]
}
}
) {
const nodeDir = await getNodeDir(opts)
const { exitCode } = await execa('node', opts.argv.original.slice(1), {
env: {
[PATH]: `${nodeDir}${path.delimiter}${process.env[PATH]!}`,
},
stdout: 'inherit',
stdin: 'inherit',
})
return { exitCode }
}
export async function getNodeDir (opts: NvmNodeCommandOptions) {
const nodesDir = path.join(opts.pnpmHomeDir, 'nodes')
let wantedNodeVersion = opts.useNodeVersion ?? (await readNodeVersionsManifest(nodesDir))?.default

View File

@@ -1,30 +1,5 @@
import fs from 'fs'
import { node } from '@pnpm/plugin-commands-nvm'
import { tempDir } from '@pnpm/prepare'
test('run specific version of Node.js', async () => {
tempDir()
const { exitCode } = await node.handler({
argv: {
original: ['node', '-e', 'require("fs").writeFileSync("version",process.version, "utf8")'],
},
useNodeVersion: '14.0.0',
pnpmHomeDir: process.cwd(),
rawConfig: {},
})
expect(exitCode).toBe(0)
expect(fs.readFileSync('version', 'utf8')).toBe('v14.0.0')
})
test('run LTS version of Node.js by default', async () => {
tempDir()
const { exitCode } = await node.handler({
argv: {
original: ['node', '-e', 'require("fs").writeFileSync("version",process.version, "utf8")'],
},
pnpmHomeDir: process.cwd(),
rawConfig: {},
})
expect(exitCode).toBe(0)
expect(fs.readFileSync('version', 'utf8')).toMatch(/^v[0-9]+\.[0-9]+\.[0-9]+$/)
test('check API (placeholder test)', async () => {
expect(typeof node.getNodeDir).toBe('function')
})

View File

@@ -48,10 +48,12 @@
"@pnpm/config": "workspace:12.3.0",
"@pnpm/error": "workspace:2.0.0",
"@pnpm/lifecycle": "workspace:11.0.0",
"@pnpm/read-project-manifest": "workspace:2.0.2",
"@pnpm/sort-packages": "workspace:2.0.1",
"@pnpm/types": "workspace:7.1.0",
"p-limit": "^3.1.0",
"path-exists": "^4.0.0",
"path-name": "^1.0.0",
"ramda": "^0.27.1",
"realpath-missing": "^1.1.0",
"render-help": "^1.0.1"

View File

@@ -1,11 +1,13 @@
import path from 'path'
import { RecursiveSummary, throwOnCommandFail } from '@pnpm/cli-utils'
import { Config, types } from '@pnpm/config'
import PnpmError from '@pnpm/error'
import { makeNodeRequireOption } from '@pnpm/lifecycle'
import logger from '@pnpm/logger'
import readProjectManifest from '@pnpm/read-project-manifest'
import sortPackages from '@pnpm/sort-packages'
import execa from 'execa'
import pLimit from 'p-limit'
import PATH from 'path-name'
import * as R from 'ramda'
import renderHelp from 'render-help'
import existsInDir from './existsInDir'
@@ -57,12 +59,9 @@ export async function handler (
rawConfig: object
sort?: boolean
workspaceConcurrency?: number
} & Pick<Config, 'recursive' | 'workspaceDir'>,
} & Pick<Config, 'extraBinPaths' | 'lockfileDir' | 'dir' | 'recursive' | 'workspaceDir'>,
params: string[]
) {
if (!opts.recursive) {
throw new PnpmError('EXEC_NOT_RECURSIVE', 'The "pnpm exec" command currently only works with the "-r" option')
}
const limitRun = pLimit(opts.workspaceConcurrency ?? 4)
const result = {
@@ -70,9 +69,24 @@ export async function handler (
passes: 0,
} as RecursiveSummary
const chunks = opts.sort
? sortPackages(opts.selectedProjectsGraph)
: [Object.keys(opts.selectedProjectsGraph).sort()]
const rootDir = opts.lockfileDir ?? opts.workspaceDir ?? opts.dir
let chunks!: string[][]
if (opts.recursive) {
chunks = opts.sort
? sortPackages(opts.selectedProjectsGraph)
: [Object.keys(opts.selectedProjectsGraph).sort()]
} else {
chunks = [[rootDir]]
opts.selectedProjectsGraph = {
[rootDir]: {
dependencies: [],
package: {
...await readProjectManifest(rootDir),
dir: rootDir,
},
},
}
}
const existsPnp = existsInDir.bind(null, '.pnp.cjs')
const workspacePnpPath = opts.workspaceDir && await existsPnp(opts.workspaceDir)
@@ -89,6 +103,11 @@ export async function handler (
env: {
...process.env,
...extraEnv,
[PATH]: [
...opts.extraBinPaths,
path.join(rootDir, 'node_modules/.bin'),
process.env[PATH],
].join(path.delimiter),
PNPM_PACKAGE_NAME: opts.selectedProjectsGraph[prefix].package.manifest.name,
},
stdio: 'inherit',

View File

@@ -3,7 +3,7 @@ import path from 'path'
import PnpmError from '@pnpm/error'
import { readProjects } from '@pnpm/filter-workspace-packages'
import { exec } from '@pnpm/plugin-commands-script-runners'
import { preparePackages } from '@pnpm/prepare'
import prepare, { preparePackages } from '@pnpm/prepare'
import rimraf from '@zkochan/rimraf'
import execa from 'execa'
import { DEFAULT_OPTS, REGISTRY } from './utils'
@@ -62,6 +62,7 @@ test('pnpm recursive exec', async () => {
])
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
}, ['npm', 'run', 'build'])
@@ -84,6 +85,7 @@ test('pnpm recursive exec sets PNPM_PACKAGE_NAME env var', async () => {
const { selectedProjectsGraph } = await readProjects(process.cwd(), [])
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
}, ['node', '-e', 'require(\'fs\').writeFileSync(\'pkgname\', process.env.PNPM_PACKAGE_NAME, \'utf8\')'])
@@ -145,6 +147,7 @@ test('testing the bail config with "pnpm recursive exec"', async () => {
try {
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
}, ['npm', 'run', 'build', '--no-bail'])
@@ -165,6 +168,7 @@ test('testing the bail config with "pnpm recursive exec"', async () => {
try {
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
}, ['npm', 'run', 'build'])
@@ -215,6 +219,7 @@ test('pnpm recursive exec --no-sort', async () => {
])
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
sort: false,
@@ -226,21 +231,18 @@ test('pnpm recursive exec --no-sort', async () => {
expect(outputs).toStrictEqual(['a-dependent', 'b-dependency'])
})
test('pnpm exec fails without the recursive=true option', async () => {
preparePackages([])
test('pnpm exec on single project', async () => {
prepare({})
let err!: PnpmError
try {
await exec.handler({
...DEFAULT_OPTS,
recursive: false,
selectedProjectsGraph: {},
}, ['npm', 'run', 'build'])
} catch (_err) {
err = _err
}
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: false,
selectedProjectsGraph: {},
}, ['node', '-e', 'require("fs").writeFileSync("output.json", "[]", "utf8")'])
expect(err.code).toBe('ERR_PNPM_EXEC_NOT_RECURSIVE')
const { default: outputs } = await import(path.resolve('output.json'))
expect(outputs).toStrictEqual([])
})
test('pnpm recursive exec works with PnP', async () => {
@@ -300,6 +302,7 @@ test('pnpm recursive exec works with PnP', async () => {
})
await exec.handler({
...DEFAULT_OPTS,
dir: process.cwd(),
recursive: true,
selectedProjectsGraph,
}, ['npm', 'run', 'build'])

View File

@@ -9,6 +9,7 @@ export const DEFAULT_OPTS = {
ca: undefined,
cert: undefined,
cliOptions: {},
extraBinPaths: [],
fetchRetries: 2,
fetchRetryFactor: 90,
fetchRetryMaxtimeout: 90,

View File

@@ -5,7 +5,6 @@
### Minor Changes
- New setting added: `use-node-version`. When set, pnpm will install the specified version of Node.js and use it for running any lifecycle scripts [#3459](https://github.com/pnpm/pnpm/pull/3459).
- New experimental command added: `pnpm node [args...]`. Runs Node.js with the provided arguments. When `use-node-version` is provided, also installs the wanted Node.js version to run it [#3459](https://github.com/pnpm/pnpm/pull/3459).
- New experimental command added: `pnpm setup`. This command adds the path to the pnpm bin to the active shell of the user. So it modifies the bash, zsh, or fish config file [#3456](https://github.com/pnpm/pnpm/pull/3456).
- `pnpm publish -r` supports a new option: `--report-summary`. When it is used, `pnpm publish -r --report-summary` will save the summary of published packages to `pnpm-publish-summary.json` [#3461](https://github.com/pnpm/pnpm/pull/3461).
- New CLI option added: `--use-stderr`. When set, all the output is written to stderr [#3463](https://github.com/pnpm/pnpm/pull/3463).

View File

@@ -4,7 +4,6 @@ import { audit } from '@pnpm/plugin-commands-audit'
import { importCommand } from '@pnpm/plugin-commands-import'
import { add, fetch, install, link, prune, remove, unlink, update } from '@pnpm/plugin-commands-installation'
import { list, ll, why } from '@pnpm/plugin-commands-listing'
import { node } from '@pnpm/plugin-commands-nvm'
import { outdated } from '@pnpm/plugin-commands-outdated'
import { pack, publish } from '@pnpm/plugin-commands-publishing'
import { rebuild } from '@pnpm/plugin-commands-rebuild'
@@ -70,7 +69,6 @@ const commands: Array<{
link,
list,
ll,
node,
outdated,
pack,
prune,

12
pnpm-lock.yaml generated
View File

@@ -1927,7 +1927,6 @@ importers:
packages/plugin-commands-nvm:
specifiers:
'@pnpm/cli-utils': workspace:0.6.5
'@pnpm/config': workspace:12.3.0
'@pnpm/fetch': workspace:3.1.0
'@pnpm/package-store': workspace:12.0.7
@@ -1937,26 +1936,19 @@ importers:
'@pnpm/tarball-fetcher': workspace:9.2.2
'@types/adm-zip': ^0.4.34
adm-zip: ^0.5.5
execa: ^5.0.0
load-json-file: ^6.2.0
path-name: ^1.0.0
rename-overwrite: ^4.0.0
render-help: ^1.0.1
tempy: ^1.0.0
write-json-file: ^4.3.0
dependencies:
'@pnpm/cli-utils': link:../cli-utils
'@pnpm/config': link:../config
'@pnpm/fetch': link:../fetch
'@pnpm/package-store': link:../package-store
'@pnpm/store-path': 5.0.0
'@pnpm/tarball-fetcher': link:../tarball-fetcher
adm-zip: 0.5.5
execa: 5.0.0
load-json-file: 6.2.0
path-name: 1.0.0
rename-overwrite: 4.0.0
render-help: 1.0.2
tempy: 1.0.1
write-json-file: 4.3.0
devDependencies:
@@ -2207,6 +2199,7 @@ importers:
'@pnpm/logger': ^4.0.0
'@pnpm/plugin-commands-script-runners': 'link:'
'@pnpm/prepare': workspace:0.0.23
'@pnpm/read-project-manifest': workspace:2.0.2
'@pnpm/sort-packages': workspace:2.0.1
'@pnpm/types': workspace:7.1.0
'@types/ramda': 0.27.39
@@ -2215,6 +2208,7 @@ importers:
is-windows: ^1.0.2
p-limit: ^3.1.0
path-exists: ^4.0.0
path-name: ^1.0.0
ramda: ^0.27.1
realpath-missing: ^1.1.0
render-help: ^1.0.1
@@ -2226,10 +2220,12 @@ importers:
'@pnpm/config': link:../config
'@pnpm/error': link:../error
'@pnpm/lifecycle': link:../lifecycle
'@pnpm/read-project-manifest': link:../read-project-manifest
'@pnpm/sort-packages': link:../sort-packages
'@pnpm/types': link:../types
p-limit: 3.1.0
path-exists: 4.0.0
path-name: 1.0.0
ramda: 0.27.1
realpath-missing: 1.1.0
render-help: 1.0.2