From 4f66fbe6fa8c515c58ab27e86327ecf126eafaed Mon Sep 17 00:00:00 2001 From: Yeom <76275691+prgmr99@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:07:28 +0900 Subject: [PATCH] fix(workspace.manifest-writer): preserve formatting in pnpm-workspace.yaml when updating catalogs (#10430) * fix(workspace.manifest-writer): preserve yaml formatting in pnpm-workspace.yaml Ensure that the original formatting (quotes, etc.) in pnpm-workspace.yaml is preserved when running commands like \`pnpm update\`. Close #10425 * docs: add changeset * fix(workspace/manifest-writer): restore formats * test: manifest writer preservers quotes in catalogs * fix(workspace.manifest-writer): only update catalog when values change * fix: remove redundant code * test: adding catalog --------- Co-authored-by: Zoltan Kochan --- .changeset/solid-eagles-mate.md | 8 +++ workspace/manifest-writer/src/index.ts | 7 ++- .../test/updateWorkspaceManifest.test.ts | 55 +++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 .changeset/solid-eagles-mate.md diff --git a/.changeset/solid-eagles-mate.md b/.changeset/solid-eagles-mate.md new file mode 100644 index 0000000000..a5ac5e6b46 --- /dev/null +++ b/.changeset/solid-eagles-mate.md @@ -0,0 +1,8 @@ +--- +"@pnpm/workspace.manifest-writer": patch +"pnpm": patch +--- + +Fix YAML formatting preservation in `pnpm-workspace.yaml` when running commands like `pnpm update`. Previously, quotes and other formatting were lost even when catalog values didn't change. + +Closes #10425 diff --git a/workspace/manifest-writer/src/index.ts b/workspace/manifest-writer/src/index.ts index e5e376fbe0..e523efe3b8 100644 --- a/workspace/manifest-writer/src/index.ts +++ b/workspace/manifest-writer/src/index.ts @@ -115,13 +115,14 @@ function addCatalogs (manifest: Partial, newCatalogs: Catalog } targetCatalog ??= {} - targetCatalog[dependencyName] = specifier + if (targetCatalog[dependencyName] !== specifier) { + targetCatalog[dependencyName] = specifier + shouldBeUpdated = true + } } if (targetCatalog == null) continue - shouldBeUpdated = true - if (targetCatalogWasNil) { if (catalogName === 'default') { manifest.catalog = targetCatalog diff --git a/workspace/manifest-writer/test/updateWorkspaceManifest.test.ts b/workspace/manifest-writer/test/updateWorkspaceManifest.test.ts index 6270509cfe..c1d94ba600 100644 --- a/workspace/manifest-writer/test/updateWorkspaceManifest.test.ts +++ b/workspace/manifest-writer/test/updateWorkspaceManifest.test.ts @@ -98,3 +98,58 @@ test('updateWorkspaceManifest updates allowBuilds', async () => { }, }) }) + +test('updateWorkspaceManifest adds a new catalog', async () => { + const dir = tempDir(false) + const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME) + + fs.writeFileSync(filePath, 'packages:\n - \'*\'\n') + + await updateWorkspaceManifest(dir, { + updatedCatalogs: { + default: { + foo: '1.0.0', + }, + }, + }) + + expect(readYamlFile(filePath)).toStrictEqual({ + packages: ['*'], + catalog: { foo: '1.0.0' }, + }) +}) + +test('updateWorkspaceManifest preserves quotes', async () => { + const dir = tempDir(false) + const filePath = path.join(dir, WORKSPACE_MANIFEST_FILENAME) + + const manifest = `\ +catalog: + "bar": "2.0.0" + 'foo': '1.0.0' + qar: 3.0.0 +` + + const expected = `\ +catalog: + "bar": "2.0.0" + 'foo': '1.0.0' + qar: 3.0.0 + zoo: 4.0.0 +` + + fs.writeFileSync(filePath, manifest) + + await updateWorkspaceManifest(dir, { + updatedCatalogs: { + default: { + foo: '1.0.0', + bar: '2.0.0', + qar: '3.0.0', + zoo: '4.0.0', + }, + }, + }) + + expect(fs.readFileSync(filePath).toString()).toStrictEqual(expected) +})