mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-26 11:02:01 -04:00
fix(workspace): treat catalog refs in workspace overrides as used during cleanupUnusedCatalogs (#11075)
* fix(workspace): treat catalog refs in workspace overrides as used during cleanupUnusedCatalogs * fix: update * fix: update
This commit is contained in:
6
.changeset/clean-catalog-overrides.md
Normal file
6
.changeset/clean-catalog-overrides.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/workspace.workspace-manifest-writer": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Prevent catalog entries from being removed by `cleanupUnusedCatalogs` when they are referenced only from workspace `overrides` in `pnpm-workspace.yaml`.
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -9112,6 +9112,9 @@ importers:
|
||||
'@pnpm/catalogs.types':
|
||||
specifier: workspace:*
|
||||
version: link:../../catalogs/types
|
||||
'@pnpm/config.parse-overrides':
|
||||
specifier: workspace:*
|
||||
version: link:../../config/parse-overrides
|
||||
'@pnpm/constants':
|
||||
specifier: workspace:*
|
||||
version: link:../../core/constants
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/catalogs.types": "workspace:*",
|
||||
"@pnpm/config.parse-overrides": "workspace:*",
|
||||
"@pnpm/constants": "workspace:*",
|
||||
"@pnpm/lockfile.types": "workspace:*",
|
||||
"@pnpm/object.key-sorting": "workspace:*",
|
||||
|
||||
@@ -3,6 +3,7 @@ import path from 'node:path'
|
||||
import util from 'node:util'
|
||||
|
||||
import type { Catalogs } from '@pnpm/catalogs.types'
|
||||
import { parsePkgAndParentSelector } from '@pnpm/config.parse-overrides'
|
||||
import { type GLOBAL_CONFIG_YAML_FILENAME, WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants'
|
||||
import type { ResolvedCatalogEntry } from '@pnpm/lockfile.types'
|
||||
import { sortKeysByPriority } from '@pnpm/object.key-sorting'
|
||||
@@ -168,14 +169,24 @@ function removePackagesFromWorkspaceCatalog (manifest: Partial<WorkspaceManifest
|
||||
if (!deps) continue
|
||||
|
||||
for (const [pkgName, version] of Object.entries(deps)) {
|
||||
if (!packageReferences[pkgName]) {
|
||||
packageReferences[pkgName] = new Set()
|
||||
}
|
||||
packageReferences[pkgName].add(version)
|
||||
addPackageReference(packageReferences, pkgName, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [selector, version] of Object.entries(manifest.overrides ?? {})) {
|
||||
if (!version.startsWith('catalog:')) {
|
||||
continue
|
||||
}
|
||||
let pkgName: string
|
||||
try {
|
||||
pkgName = parsePkgAndParentSelector(selector).targetPkg.name
|
||||
} catch {
|
||||
continue
|
||||
}
|
||||
addPackageReference(packageReferences, pkgName, version)
|
||||
}
|
||||
|
||||
if (manifest.catalog) {
|
||||
const packagesToRemove = Object.keys(manifest.catalog).filter(pkg =>
|
||||
!packageReferences[pkg]?.has('catalog:')
|
||||
@@ -226,3 +237,10 @@ function removePackagesFromWorkspaceCatalog (manifest: Partial<WorkspaceManifest
|
||||
|
||||
return shouldBeUpdated
|
||||
}
|
||||
|
||||
function addPackageReference (packageReferences: Record<string, Set<string>>, pkgName: string, version: string): void {
|
||||
if (!packageReferences[pkgName]) {
|
||||
packageReferences[pkgName] = new Set()
|
||||
}
|
||||
packageReferences[pkgName].add(version)
|
||||
}
|
||||
|
||||
@@ -415,3 +415,97 @@ test('when allProjects is undefined should not cleanup unused catalogs', async (
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('keep catalogs referenced only in workspace overrides', async () => {
|
||||
const dir = tempDir(false)
|
||||
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
||||
writeYamlFileSync(filePath, {
|
||||
catalog: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
catalogs: {
|
||||
bar: {
|
||||
'@scope/def': '2.0.0',
|
||||
},
|
||||
},
|
||||
overrides: {
|
||||
foo: 'catalog:',
|
||||
'@scope/parent@1>@scope/def': 'catalog:bar',
|
||||
},
|
||||
})
|
||||
|
||||
prepare({
|
||||
dependencies: {
|
||||
zoo: '^1.0.0',
|
||||
},
|
||||
}, { tempDir: dir })
|
||||
const allProjects = await findPackages(dir)
|
||||
|
||||
await updateWorkspaceManifest(dir, {
|
||||
cleanupUnusedCatalogs: true,
|
||||
allProjects,
|
||||
})
|
||||
|
||||
expect(readYamlFileSync(filePath)).toStrictEqual({
|
||||
catalog: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
catalogs: {
|
||||
bar: {
|
||||
'@scope/def': '2.0.0',
|
||||
},
|
||||
},
|
||||
overrides: {
|
||||
foo: 'catalog:',
|
||||
'@scope/parent@1>@scope/def': 'catalog:bar',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('remove catalogs unused by dependencies and workspace overrides', async () => {
|
||||
const dir = tempDir(false)
|
||||
const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME)
|
||||
writeYamlFileSync(filePath, {
|
||||
catalog: {
|
||||
foo: '1.0.0',
|
||||
unusedDefault: '2.0.0',
|
||||
},
|
||||
catalogs: {
|
||||
bar: {
|
||||
def: '2.0.0',
|
||||
unusedNamed: '3.0.0',
|
||||
},
|
||||
},
|
||||
overrides: {
|
||||
foo: 'catalog:',
|
||||
def: 'catalog:bar',
|
||||
},
|
||||
})
|
||||
|
||||
prepare({
|
||||
dependencies: {
|
||||
zoo: '^1.0.0',
|
||||
},
|
||||
}, { tempDir: dir })
|
||||
const allProjects = await findPackages(dir)
|
||||
|
||||
await updateWorkspaceManifest(dir, {
|
||||
cleanupUnusedCatalogs: true,
|
||||
allProjects,
|
||||
})
|
||||
|
||||
expect(readYamlFileSync(filePath)).toStrictEqual({
|
||||
catalog: {
|
||||
foo: '1.0.0',
|
||||
},
|
||||
catalogs: {
|
||||
bar: {
|
||||
def: '2.0.0',
|
||||
},
|
||||
},
|
||||
overrides: {
|
||||
foo: 'catalog:',
|
||||
def: 'catalog:bar',
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
{
|
||||
"path": "../../catalogs/types"
|
||||
},
|
||||
{
|
||||
"path": "../../config/parse-overrides"
|
||||
},
|
||||
{
|
||||
"path": "../../core/constants"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user