Skip to content

Commit b4c0dcb

Browse files
committed
refactor: simplify with useNodeVersion and onFail handling
1 parent fe6e1ae commit b4c0dcb

File tree

10 files changed

+77
-67
lines changed

10 files changed

+77
-67
lines changed

env/plugin-commands-env/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
"@pnpm/error": "workspace:*",
3838
"@pnpm/fetch": "workspace:*",
3939
"@pnpm/logger": "workspace:*",
40+
"@pnpm/manifest-utils": "workspace:*",
4041
"@pnpm/node.fetcher": "workspace:*",
4142
"@pnpm/node.resolver": "workspace:*",
42-
"@pnpm/read-project-manifest": "workspace:*",
4343
"@pnpm/remove-bins": "workspace:*",
4444
"@pnpm/store-path": "workspace:*",
4545
"@pnpm/types": "workspace:*",

env/plugin-commands-env/src/envUse.ts

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { promises as fs } from 'fs'
22
import util from 'util'
33
import gfs from 'graceful-fs'
44
import path from 'path'
5-
import { updateProjectManifest } from '@pnpm/read-project-manifest'
6-
import { type ProjectManifest } from '@pnpm/types'
75
import { PnpmError } from '@pnpm/error'
86
import { logger } from '@pnpm/logger'
97
import semver from 'semver'
@@ -13,49 +11,55 @@ import symlinkDir from 'symlink-dir'
1311
import { type NvmNodeCommandOptions } from './node'
1412
import { CURRENT_NODE_DIRNAME, getNodeExecPathInBinDir, getNodeExecPathInNodeDir } from './utils'
1513
import { downloadNodeVersion } from './downloadNodeVersion'
16-
17-
export const getRuntimeNodeVersion = ({ devEngines }: ProjectManifest = {}): string | undefined =>
18-
devEngines?.runtime?.name === 'node' ? devEngines?.runtime?.version : undefined
14+
import { getNodeRuntime, updateNodeRuntimeVersion } from '@pnpm/manifest-utils'
1915

2016
export async function envUse (opts: NvmNodeCommandOptions, params: string[]): Promise<string> {
21-
if (params.length === 0) {
17+
let [nodeVersion] = params
18+
if (!nodeVersion) {
2219
throw new PnpmError('ENV_USE_NO_PARAMS', '`pnpm env use` requires a Node.js version specifier')
2320
}
24-
const nodeInfo = await downloadNodeVersion(opts, params[0])
25-
if (!nodeInfo) {
26-
throw new PnpmError('COULD_NOT_RESOLVE_NODEJS', `Couldn't find Node.js version matching "${params[0]}"`)
27-
}
28-
const { nodeDir, nodeVersion } = nodeInfo
29-
21+
const prefix = opts.rootProjectManifestDir
22+
let overwriteVersion
3023
if (!opts.global) {
31-
const runtimeNodeVersion = getRuntimeNodeVersion(opts.rootProjectManifest)
32-
const prefix = opts.rootProjectManifestDir
33-
let overwrite = !semver.valid(runtimeNodeVersion)
34-
35-
if (runtimeNodeVersion && !semver.satisfies(nodeVersion, runtimeNodeVersion)) {
36-
const message = `"Node.js version "${nodeVersion}" is incompatible with "devEngines.runtime.version: ${runtimeNodeVersion}"`
37-
if (opts.engineStrict) {
38-
throw new PnpmError('INVALID_NODE_VERSION', message)
24+
if (opts.useNodeVersion) {
25+
if (semver.satisfies(opts.useNodeVersion, nodeVersion)) {
26+
nodeVersion = opts.useNodeVersion
3927
} else {
40-
logger.warn({ message, prefix })
41-
overwrite ||= true
28+
const msg = `"Node.js version "${nodeVersion}" is incompatible with "useNodeVersion: ${opts.useNodeVersion}"`
29+
throw new PnpmError('INVALID_NODE_VERSION', msg)
4230
}
43-
}
44-
if (overwrite) {
45-
await updateProjectManifest(prefix, {
46-
devEngines: {
47-
runtime: {
48-
name: 'node',
49-
version: nodeVersion
50-
}
31+
} else if (opts.rootProjectManifest?.devEngines) {
32+
const { version, onFail } = getNodeRuntime(opts.rootProjectManifest.devEngines) ?? {}
33+
if (version) {
34+
const message = `"Node.js version "${nodeVersion}" is incompatible with "devEngines.runtime.version: ${version}"`
35+
switch (onFail) {
36+
case 'download':
37+
overwriteVersion = version
38+
break
39+
case 'ignore':
40+
return ''
41+
case 'warn':
42+
logger.warn({ message, prefix })
43+
break
44+
case 'error':
45+
default: throw new PnpmError('INVALID_NODE_VERSION', message)
5146
}
52-
}).then(() => {
53-
const verb = semver.intersects(runtimeNodeVersion ?? '0', nodeVersion) ? 'resolved' : 'modified'
54-
const message = `"devEngines.runtime.version": "${runtimeNodeVersion}" was ${verb} to "${nodeVersion}"`
55-
logger[verb === 'modified' ? 'warn' : 'info']({ message, prefix })
56-
})
47+
}
5748
}
5849
}
50+
const nodeInfo = await downloadNodeVersion(opts, nodeVersion)
51+
if (!nodeInfo) {
52+
throw new PnpmError('COULD_NOT_RESOLVE_NODEJS', `Couldn't find Node.js version matching "${nodeVersion}"`)
53+
}
54+
const {nodeDir} = nodeInfo;
55+
nodeVersion = nodeInfo.nodeVersion
56+
if (overwriteVersion) {
57+
const range = `^${semver.major(nodeVersion)}`
58+
await updateNodeRuntimeVersion(prefix, opts.rootProjectManifest, range)
59+
60+
const message = `"devEngines.runtime.version": "${overwriteVersion}" was modified to "${range}"`
61+
logger.info({ message, prefix })
62+
}
5963
const src = getNodeExecPathInNodeDir(nodeDir)
6064
const dest = getNodeExecPathInBinDir(opts.bin)
6165
await symlinkDir(nodeDir, path.join(opts.pnpmHomeDir, CURRENT_NODE_DIRNAME))

env/plugin-commands-env/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ import * as env from './env'
22
import { prepareExecutionEnv } from './node'
33

44
export { getNodeVersion } from './downloadNodeVersion'
5-
export { getRuntimeNodeVersion } from './envUse'
65
export { env, prepareExecutionEnv }

packages/types/src/package.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ export interface PnpmSettings {
176176
auditConfig?: AuditConfig
177177
requiredScripts?: string[]
178178
supportedArchitectures?: SupportedArchitectures
179-
executionEnv?: ExecutionEnv
180179
useNodeVersion?: string
180+
executionEnv?: ExecutionEnv
181181
}
182182

183183
export interface ProjectManifest extends BaseManifest {

pkg-manifest/manifest-utils/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"dependencies": {
3434
"@pnpm/core-loggers": "workspace:*",
3535
"@pnpm/error": "workspace:*",
36+
"@pnpm/read-project-manifest": "workspace:*",
3637
"@pnpm/types": "workspace:*"
3738
},
3839
"devDependencies": {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { ProjectManifest, DevEngines, DevEngineDependency } from '@pnpm/types'
2+
import { updateProjectManifest } from '@pnpm/read-project-manifest'
3+
4+
export const getNodeRuntime = ({ runtime }: DevEngines = {}): DevEngineDependency | undefined =>
5+
[runtime].flat().find(runtime => runtime?.name === 'node')
6+
7+
export async function updateNodeRuntimeVersion (projectDir: string, { devEngines }: ProjectManifest = {}, version: string): Promise<void> {
8+
if (!devEngines) return
9+
10+
devEngines.runtime &&= Array.isArray(devEngines.runtime)
11+
? devEngines.runtime?.map(runtime => runtime.name === 'node' ? { ...runtime, version } : runtime) ?? {}
12+
: { ...devEngines.runtime, version }
13+
14+
return updateProjectManifest(projectDir, {devEngines})
15+
}

pkg-manifest/manifest-utils/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { getSpecFromPackageManifest } from './getSpecFromPackageManifest'
88

99
export * from './updateProjectManifestObject'
1010
export * from './getDependencyTypeFromManifest'
11+
export * from './getNodeRuntimeFromManifest'
1112

1213
export { getSpecFromPackageManifest, getAllUniqueSpecs }
1314

pnpm-lock.yaml

Lines changed: 9 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"@pnpm/find-workspace-dir": "workspace:*",
9797
"@pnpm/lockfile.types": "workspace:*",
9898
"@pnpm/logger": "workspace:*",
99+
"@pnpm/manifest-utils": "workspace:*",
99100
"@pnpm/modules-yaml": "workspace:*",
100101
"@pnpm/nopt": "catalog:",
101102
"@pnpm/parse-cli-args": "workspace:*",

pnpm/src/main.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ import { PnpmError } from '@pnpm/error'
1616
import { filterPackagesFromDir } from '@pnpm/filter-workspace-packages'
1717
import { globalWarn, logger } from '@pnpm/logger'
1818
import { type ParsedCliArgs } from '@pnpm/parse-cli-args'
19-
import { getNodeVersion, getRuntimeNodeVersion, prepareExecutionEnv } from '@pnpm/plugin-commands-env'
20-
import { updateProjectManifest } from '@pnpm/read-project-manifest'
19+
import { getNodeVersion, prepareExecutionEnv } from '@pnpm/plugin-commands-env'
20+
import { getNodeRuntime } from '@pnpm/manifest-utils'
2121
import { finishWorkers } from '@pnpm/worker'
22-
import semver from 'semver'
2322
import chalk from 'chalk'
2423
import path from 'path'
2524
import isEmpty from 'ramda/src/isEmpty'
@@ -285,32 +284,16 @@ export async function main (inputArgv: string[]): Promise<void> {
285284
...(workspaceDir ? { workspacePrefix: workspaceDir } : {}),
286285
})
287286

288-
if (config.useNodeVersion == null) { //&& config.executionEnv == null) TODO
289-
const runtimeNodeVersion = getRuntimeNodeVersion(config.rootProjectManifest)
290-
const prefix = config.rootProjectManifestDir
291-
292-
if (runtimeNodeVersion != null) {
293-
const {nodeVersion} = await getNodeVersion(config, runtimeNodeVersion)
294-
config.useNodeVersion = nodeVersion ?? undefined
295-
296-
if (!semver.valid(runtimeNodeVersion)) {
297-
await updateProjectManifest(prefix, {
298-
devEngines: {
299-
runtime: {
300-
name: 'node',
301-
version: nodeVersion
302-
}
303-
}
304-
}).then(() => {
305-
const message = `"devEngines.runtime.version": "${runtimeNodeVersion}" was resolved to "${nodeVersion}"`
306-
logger.info({ message, prefix })
307-
})
308-
}
309-
}
310-
}
287+
const {devEngines} = config.rootProjectManifest ?? {}
311288

312289
if ('webcontainer' in process.versions) {
313290
globalWarn('Automatic installation of different Node.js versions is not supported in WebContainer')
291+
} else if (!config.useNodeVersion && devEngines) {
292+
const {version} = getNodeRuntime(devEngines) ?? {}
293+
if (version) {
294+
const {nodeVersion} = await getNodeVersion(config, version)
295+
config.useNodeVersion = nodeVersion ?? undefined
296+
}
314297
} else {
315298
config.extraBinPaths = (
316299
await prepareExecutionEnv(config, {

0 commit comments

Comments
 (0)