refactor: updating specs in the manifest (#9410)

This commit is contained in:
Zoltan Kochan
2025-04-13 21:44:35 +02:00
committed by GitHub
parent 4ac46c7efa
commit 81f441cd3a
10 changed files with 55 additions and 64 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/resolver-base": major
"@pnpm/npm-resolver": major
---
`updateToLatest` replaced with `update` field.

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": major
---
Removed `raw` from `WantedDependency` object. Remove `updateWorkspaceDependencies` field.

View File

@@ -474,7 +474,6 @@ export async function mutateModules (
const wantedDependencies = getWantedDependencies(project.manifest, {
autoInstallPeers: opts.autoInstallPeers,
includeDirect: opts.includeDirect,
updateWorkspaceDependencies: project.update,
nodeExecPath: opts.nodeExecPath,
})
.map((wantedDependency) => ({ ...wantedDependency, updateSpec: true, preserveNonSemverVersionSpec: true }))

View File

@@ -38,11 +38,7 @@ export function parseWantedDependencies (
pref = 'catalog:'
}
if (alias && opts.currentPrefs[alias]) {
if (!pref) {
pref = (opts.currentPrefs[alias].startsWith('workspace:') && opts.updateWorkspaceDependencies === true)
? 'workspace:*'
: opts.currentPrefs[alias]
}
pref ??= opts.currentPrefs[alias]
pinnedVersion = whichVersionIsPinned(opts.currentPrefs[alias])
}
const result = {
@@ -50,7 +46,6 @@ export function parseWantedDependencies (
dev: Boolean(opts.dev || alias && !!opts.devDependencies[alias]),
optional: Boolean(opts.optional || alias && !!opts.optionalDependencies[alias]),
pinnedVersion,
raw: alias && opts.currentPrefs?.[alias]?.startsWith('workspace:') ? `${alias}@${opts.currentPrefs[alias]}` : rawWantedDependency,
}
if (pref) {
return {
@@ -62,14 +57,12 @@ export function parseWantedDependencies (
return {
...result,
pref: opts.preferredSpecs[alias],
raw: `${rawWantedDependency}@${opts.preferredSpecs[alias]}`,
}
}
if (alias && opts.overrides?.[alias]) {
return {
...result,
pref: opts.overrides[alias],
raw: `${alias}@${opts.overrides[alias]}`,
}
}
return {

View File

@@ -186,7 +186,7 @@ async function resolveAndFetch (
preferWorkspacePackages: options.preferWorkspacePackages,
projectDir: options.projectDir,
workspacePackages: options.workspacePackages,
updateToLatest: options.update === 'latest',
update: options.update,
injectWorkspacePackages: options.injectWorkspacePackages,
}), { priority: options.downloadPriority })

View File

@@ -6,7 +6,6 @@ import {
type ProjectManifest,
} from '@pnpm/types'
import { whichVersionIsPinned } from '@pnpm/which-version-is-pinned'
import { WorkspaceSpec } from '@pnpm/workspace.spec-parser'
export type PinnedVersion = 'major' | 'minor' | 'patch' | 'none'
@@ -15,7 +14,6 @@ export interface WantedDependency {
pref: string // package reference
dev: boolean
optional: boolean
raw: string
pinnedVersion?: PinnedVersion
nodeExecPath?: string
updateSpec?: boolean
@@ -27,7 +25,6 @@ export function getWantedDependencies (
autoInstallPeers?: boolean
includeDirect?: IncludedDependencies
nodeExecPath?: string
updateWorkspaceDependencies?: boolean
}
): WantedDependency[] {
let depsToInstall = filterDependenciesByType(pkg,
@@ -48,19 +45,9 @@ export function getWantedDependencies (
optionalDependencies: pkg.optionalDependencies ?? {},
dependenciesMeta: pkg.dependenciesMeta ?? {},
peerDependencies: pkg.peerDependencies ?? {},
updatePref: opts?.updateWorkspaceDependencies === true
? updateWorkspacePref
: (pref) => pref,
})
}
function updateWorkspacePref (pref: string): string {
const spec = WorkspaceSpec.parse(pref)
if (!spec) return pref
spec.version = '*'
return spec.toString()
}
function getWantedDependenciesFromGivenSet (
deps: Dependencies,
opts: {
@@ -70,12 +57,10 @@ function getWantedDependenciesFromGivenSet (
peerDependencies: Dependencies
dependenciesMeta: DependenciesMeta
nodeExecPath?: string
updatePref: (pref: string) => string
}
): WantedDependency[] {
if (!deps) return []
return Object.entries(deps).map(([alias, pref]) => {
const updatedPref = opts.updatePref(pref)
let depType
if (opts.optionalDependencies[alias] != null) depType = 'optional'
else if (opts.dependencies[alias] != null) depType = 'prod'
@@ -88,8 +73,7 @@ function getWantedDependenciesFromGivenSet (
optional: depType === 'optional',
nodeExecPath: opts.nodeExecPath ?? opts.dependenciesMeta[alias]?.node,
pinnedVersion: whichVersionIsPinned(pref),
pref: updatedPref,
raw: `${alias}@${pref}`,
pref,
}
})
}

View File

@@ -76,7 +76,6 @@ export interface ImporterToResolve extends Importer<{
isNew?: boolean
nodeExecPath?: string
pinnedVersion?: PinnedVersion
raw: string
updateSpec?: boolean
preserveNonSemverVersionSpec?: boolean
}> {

View File

@@ -1,6 +1,5 @@
import {
createVersionSpec,
getPrefix,
type PackageSpecObject,
type PinnedVersion,
updateProjectManifestObject,
@@ -32,7 +31,7 @@ export async function updateProjectManifest (
...rdd,
isNew:
wantedDep.isNew,
specRaw: wantedDep.raw,
currentPref: wantedDep.pref,
preserveNonSemverVersionSpec: wantedDep.preserveNonSemverVersionSpec,
// For git-protocol dependencies that are already installed locally, there is no normalizedPref unless do force resolve,
// so we use pref in wantedDependency here.
@@ -77,10 +76,10 @@ function resolvedDirectDepToSpecObject (
name,
normalizedPref,
resolution,
specRaw,
currentPref,
version,
preserveNonSemverVersionSpec,
}: ResolvedDirectDependency & { isNew?: boolean, specRaw: string, preserveNonSemverVersionSpec?: boolean },
}: ResolvedDirectDependency & { isNew?: boolean, currentPref: string, preserveNonSemverVersionSpec?: boolean },
importer: ImporterToResolve,
opts: {
nodeExecPath?: string
@@ -98,7 +97,7 @@ function resolvedDirectDepToSpecObject (
const shouldUseWorkspaceProtocol = resolution.type === 'directory' &&
(
Boolean(opts.saveWorkspaceProtocol) ||
(opts.preserveWorkspaceProtocol && specRaw.includes('@workspace:'))
(opts.preserveWorkspaceProtocol && currentPref.startsWith('workspace:'))
) &&
opts.pinnedVersion !== 'none'
@@ -107,7 +106,7 @@ function resolvedDirectDepToSpecObject (
alias,
name,
pinnedVersion: opts.pinnedVersion,
specRaw,
currentPref,
version,
rolling: shouldUseWorkspaceProtocol && opts.saveWorkspaceProtocol === 'rolling',
})
@@ -116,7 +115,7 @@ function resolvedDirectDepToSpecObject (
alias,
name,
pinnedVersion: opts.pinnedVersion,
specRaw,
currentPref,
version,
rolling: shouldUseWorkspaceProtocol && opts.saveWorkspaceProtocol === 'rolling',
preserveNonSemverVersionSpec,
@@ -144,19 +143,17 @@ function getPrefPreferSpecifiedSpec (
alias: string
name: string
version: string
specRaw: string
currentPref: string
pinnedVersion?: PinnedVersion
rolling: boolean
}
): string {
const prefix = getPrefix(opts.alias, opts.name)
if (opts.specRaw?.startsWith(`${opts.alias}@${prefix}`)) {
const range = opts.specRaw.slice(`${opts.alias}@${prefix}`.length)
if (range) {
const selector = versionSelectorType(range)
if ((selector != null) && (selector.type === 'version' || selector.type === 'range')) {
return opts.specRaw.slice(opts.alias.length + 1)
}
const prefix = opts.currentPref.startsWith('npm:') ? `npm:${opts.name}@` : ''
const range = opts.currentPref.slice(prefix.length)
if (range) {
const selector = versionSelectorType(range)
if ((selector != null) && (selector.type === 'version' || selector.type === 'range')) {
return opts.currentPref
}
}
// A prerelease version is always added as an exact version
@@ -171,29 +168,28 @@ function getPrefPreferSpecifiedExoticSpec (
alias: string
name: string
version: string
specRaw: string
currentPref: string
pinnedVersion: PinnedVersion
rolling: boolean
preserveNonSemverVersionSpec?: boolean
}
): string {
const prefix = getPrefix(opts.alias, opts.name)
if (opts.specRaw?.startsWith(`${opts.alias}@${prefix}`)) {
let specWithoutName = opts.specRaw.slice(`${opts.alias}@${prefix}`.length)
if (specWithoutName.startsWith('workspace:')) {
specWithoutName = specWithoutName.slice(10)
if (specWithoutName === '*' || specWithoutName === '^' || specWithoutName === '~') {
return specWithoutName
}
}
const selector = versionSelectorType(specWithoutName)
if (
((selector == null) || (selector.type !== 'version' && selector.type !== 'range')) &&
opts.preserveNonSemverVersionSpec
) {
return opts.specRaw.slice(opts.alias.length + 1)
let prefix = opts.currentPref.startsWith('npm:') ? `npm:${opts.name}@` : ''
let specWithoutName = opts.currentPref.slice(prefix.length)
if (specWithoutName.startsWith('workspace:')) {
prefix = 'workspace:'
specWithoutName = specWithoutName.slice(10)
if (specWithoutName === '*' || specWithoutName === '^' || specWithoutName === '~') {
return specWithoutName
}
}
const selector = versionSelectorType(specWithoutName)
if (
((selector == null) || (selector.type !== 'version' && selector.type !== 'range')) &&
opts.preserveNonSemverVersionSpec
) {
return opts.currentPref
}
// A prerelease version is always added as an exact version
if (semver.parse(opts.version)?.prerelease.length) {
return `${prefix}${opts.version}`

View File

@@ -121,7 +121,7 @@ export type ResolveFromNpmOptions = {
lockfileDir?: string
preferredVersions?: PreferredVersions
preferWorkspacePackages?: boolean
updateToLatest?: boolean
update?: false | 'compatible' | 'latest'
injectWorkspacePackages?: boolean
} & ({
projectDir?: string
@@ -153,6 +153,7 @@ async function resolveNpm (
registry,
workspacePackages: opts.workspacePackages,
injectWorkspacePackages: opts.injectWorkspacePackages,
update: Boolean(opts.update),
})
if (resolvedFromWorkspace != null) {
return resolvedFromWorkspace
@@ -174,7 +175,7 @@ async function resolveNpm (
dryRun: opts.dryRun === true,
preferredVersionSelectors: opts.preferredVersions?.[spec.name],
registry,
updateToLatest: opts.updateToLatest,
updateToLatest: opts.update === 'latest',
})
} catch (err: any) { // eslint-disable-line
if ((workspacePackages != null) && opts.projectDir) {
@@ -184,6 +185,7 @@ async function resolveNpm (
projectDir: opts.projectDir,
lockfileDir: opts.lockfileDir,
hardLinkLocalPackages: opts.injectWorkspacePackages === true || wantedDependency.injected,
update: Boolean(opts.update),
})
} catch {
// ignore
@@ -201,6 +203,7 @@ async function resolveNpm (
projectDir: opts.projectDir,
lockfileDir: opts.lockfileDir,
hardLinkLocalPackages: opts.injectWorkspacePackages === true || wantedDependency.injected,
update: Boolean(opts.update),
})
} catch {
// ignore
@@ -260,6 +263,7 @@ function tryResolveFromWorkspace (
registry: string
workspacePackages?: WorkspacePackages
injectWorkspacePackages?: boolean
update?: boolean
}
): WorkspaceResolveResult | null {
if (!wantedDependency.pref?.startsWith('workspace:')) {
@@ -280,6 +284,7 @@ function tryResolveFromWorkspace (
projectDir: opts.projectDir,
hardLinkLocalPackages: opts.injectWorkspacePackages === true || wantedDependency.injected,
lockfileDir: opts.lockfileDir,
update: opts.update,
})
}
@@ -291,6 +296,7 @@ function tryResolveFromWorkspacePackages (
hardLinkLocalPackages?: boolean
projectDir: string
lockfileDir?: string
update?: boolean
}
): WorkspaceResolveResult {
const workspacePkgsMatchingName = workspacePackages.get(spec.name)
@@ -303,7 +309,10 @@ function tryResolveFromWorkspacePackages (
}
)
}
const localVersion = pickMatchingLocalVersionOrNull(workspacePkgsMatchingName, spec)
const localVersion = pickMatchingLocalVersionOrNull(
workspacePkgsMatchingName,
opts.update ? { name: spec.name, fetchSpec: '*', type: 'range' } : spec
)
if (!localVersion) {
throw new PnpmError(
'NO_MATCHING_VERSION_INSIDE_WORKSPACE',

View File

@@ -97,7 +97,7 @@ export interface ResolveOptions {
preferredVersions: PreferredVersions
preferWorkspacePackages?: boolean
workspacePackages?: WorkspacePackages
updateToLatest?: boolean
update?: false | 'compatible' | 'latest'
injectWorkspacePackages?: boolean
}