From 81f441cd3a3d9df35f270c62b29ffa5e3036102f Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 13 Apr 2025 21:44:35 +0200 Subject: [PATCH] refactor: updating specs in the manifest (#9410) --- .changeset/early-falcons-yawn.md | 6 ++ .changeset/puny-jobs-notice.md | 5 ++ pkg-manager/core/src/install/index.ts | 1 - .../core/src/parseWantedDependencies.ts | 9 +-- .../package-requester/src/packageRequester.ts | 2 +- .../src/getWantedDependencies.ts | 18 +----- pkg-manager/resolve-dependencies/src/index.ts | 1 - .../src/updateProjectManifest.ts | 60 +++++++++---------- resolving/npm-resolver/src/index.ts | 15 ++++- resolving/resolver-base/src/index.ts | 2 +- 10 files changed, 55 insertions(+), 64 deletions(-) create mode 100644 .changeset/early-falcons-yawn.md create mode 100644 .changeset/puny-jobs-notice.md diff --git a/.changeset/early-falcons-yawn.md b/.changeset/early-falcons-yawn.md new file mode 100644 index 0000000000..96ac152181 --- /dev/null +++ b/.changeset/early-falcons-yawn.md @@ -0,0 +1,6 @@ +--- +"@pnpm/resolver-base": major +"@pnpm/npm-resolver": major +--- + +`updateToLatest` replaced with `update` field. diff --git a/.changeset/puny-jobs-notice.md b/.changeset/puny-jobs-notice.md new file mode 100644 index 0000000000..187534e573 --- /dev/null +++ b/.changeset/puny-jobs-notice.md @@ -0,0 +1,5 @@ +--- +"@pnpm/resolve-dependencies": major +--- + +Removed `raw` from `WantedDependency` object. Remove `updateWorkspaceDependencies` field. diff --git a/pkg-manager/core/src/install/index.ts b/pkg-manager/core/src/install/index.ts index 876b160748..890f89cf48 100644 --- a/pkg-manager/core/src/install/index.ts +++ b/pkg-manager/core/src/install/index.ts @@ -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 })) diff --git a/pkg-manager/core/src/parseWantedDependencies.ts b/pkg-manager/core/src/parseWantedDependencies.ts index 24027f3026..eaf612f454 100644 --- a/pkg-manager/core/src/parseWantedDependencies.ts +++ b/pkg-manager/core/src/parseWantedDependencies.ts @@ -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 { diff --git a/pkg-manager/package-requester/src/packageRequester.ts b/pkg-manager/package-requester/src/packageRequester.ts index 9255f1f64c..2d79a12ab3 100644 --- a/pkg-manager/package-requester/src/packageRequester.ts +++ b/pkg-manager/package-requester/src/packageRequester.ts @@ -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 }) diff --git a/pkg-manager/resolve-dependencies/src/getWantedDependencies.ts b/pkg-manager/resolve-dependencies/src/getWantedDependencies.ts index bf182f52d3..0eb984a674 100644 --- a/pkg-manager/resolve-dependencies/src/getWantedDependencies.ts +++ b/pkg-manager/resolve-dependencies/src/getWantedDependencies.ts @@ -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, } }) } diff --git a/pkg-manager/resolve-dependencies/src/index.ts b/pkg-manager/resolve-dependencies/src/index.ts index 5c5b0688b3..735d08a1ec 100644 --- a/pkg-manager/resolve-dependencies/src/index.ts +++ b/pkg-manager/resolve-dependencies/src/index.ts @@ -76,7 +76,6 @@ export interface ImporterToResolve extends Importer<{ isNew?: boolean nodeExecPath?: string pinnedVersion?: PinnedVersion - raw: string updateSpec?: boolean preserveNonSemverVersionSpec?: boolean }> { diff --git a/pkg-manager/resolve-dependencies/src/updateProjectManifest.ts b/pkg-manager/resolve-dependencies/src/updateProjectManifest.ts index 75becc8ebd..a2451538ae 100644 --- a/pkg-manager/resolve-dependencies/src/updateProjectManifest.ts +++ b/pkg-manager/resolve-dependencies/src/updateProjectManifest.ts @@ -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}` diff --git a/resolving/npm-resolver/src/index.ts b/resolving/npm-resolver/src/index.ts index 367699cd18..b567fa6aa7 100644 --- a/resolving/npm-resolver/src/index.ts +++ b/resolving/npm-resolver/src/index.ts @@ -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', diff --git a/resolving/resolver-base/src/index.ts b/resolving/resolver-base/src/index.ts index d43ffb9c38..750bb0b56e 100644 --- a/resolving/resolver-base/src/index.ts +++ b/resolving/resolver-base/src/index.ts @@ -97,7 +97,7 @@ export interface ResolveOptions { preferredVersions: PreferredVersions preferWorkspacePackages?: boolean workspacePackages?: WorkspacePackages - updateToLatest?: boolean + update?: false | 'compatible' | 'latest' injectWorkspacePackages?: boolean }