diff --git a/.changeset/odd-moments-tell.md b/.changeset/odd-moments-tell.md new file mode 100644 index 0000000000..e236cadcd1 --- /dev/null +++ b/.changeset/odd-moments-tell.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-config": minor +"@pnpm/workspace.manifest-writer": minor +--- + +`pnpm config delete --location=project` The setting in `pnpm-workspace.yaml` file will be deleted if no `.npmrc` file is present in the directory diff --git a/config/plugin-commands-config/test/configSet.test.ts b/config/plugin-commands-config/test/configSet.test.ts index f562d6be09..cbbcd15905 100644 --- a/config/plugin-commands-config/test/configSet.test.ts +++ b/config/plugin-commands-config/test/configSet.test.ts @@ -64,6 +64,34 @@ test('config set using the location=project option. The setting is written to pn }) }) +test('config delete using the location=project option. The setting in pnpm-workspace.yaml will be deleted, when .npmrc is not present', async () => { + const tmp = tempDir() + const configDir = path.join(tmp, 'global-config') + fs.mkdirSync(configDir, { recursive: true }) + + await config.handler({ + dir: process.cwd(), + cliOptions: {}, + configDir, + location: 'project', + rawConfig: {}, + }, ['set', 'virtual-store-dir', '.pnpm']) + + expect(readYamlFile(path.join(tmp, 'pnpm-workspace.yaml'))).toEqual({ + virtualStoreDir: '.pnpm', + }) + + await config.handler({ + dir: process.cwd(), + cliOptions: {}, + configDir, + location: 'project', + rawConfig: {}, + }, ['delete', 'virtual-store-dir']) + + expect(fs.existsSync(path.join(tmp, 'pnpm-workspace.yaml'))).toBeFalsy() +}) + test('config set using the location=project option', async () => { const tmp = tempDir() const configDir = path.join(tmp, 'global-config') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 101c89c724..b425e6fa64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8181,6 +8181,9 @@ importers: '@pnpm/workspace.read-manifest': specifier: workspace:* version: link:../read-manifest + ramda: + specifier: 'catalog:' + version: '@pnpm/ramda@0.28.1' write-yaml-file: specifier: 'catalog:' version: 5.0.0 @@ -8191,6 +8194,9 @@ importers: '@pnpm/workspace.manifest-writer': specifier: workspace:* version: 'link:' + '@types/ramda': + specifier: 'catalog:' + version: 0.29.12 read-yaml-file: specifier: 'catalog:' version: 2.1.0 diff --git a/workspace/manifest-writer/package.json b/workspace/manifest-writer/package.json index c82de2a52c..32b54d29bb 100644 --- a/workspace/manifest-writer/package.json +++ b/workspace/manifest-writer/package.json @@ -32,11 +32,13 @@ "dependencies": { "@pnpm/constants": "workspace:*", "@pnpm/workspace.read-manifest": "workspace:*", + "ramda": "catalog:", "write-yaml-file": "catalog:" }, "devDependencies": { "@pnpm/prepare-temp-dir": "workspace:*", "@pnpm/workspace.manifest-writer": "workspace:*", + "@types/ramda": "catalog:", "read-yaml-file": "catalog:" }, "engines": { diff --git a/workspace/manifest-writer/src/index.ts b/workspace/manifest-writer/src/index.ts index 558a8b7089..77d94bf4fb 100644 --- a/workspace/manifest-writer/src/index.ts +++ b/workspace/manifest-writer/src/index.ts @@ -1,12 +1,30 @@ +import fs from 'fs' import path from 'path' import { readWorkspaceManifest, type WorkspaceManifest } from '@pnpm/workspace.read-manifest' import { WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants' import writeYamlFile from 'write-yaml-file' +import equals from 'ramda/src/equals' export async function updateWorkspaceManifest (dir: string, updatedFields: Partial): Promise { - const manifest = await readWorkspaceManifest(dir) - await writeYamlFile(path.join(dir, WORKSPACE_MANIFEST_FILENAME), { - ...manifest, - ...updatedFields, - }) + const manifest = await readWorkspaceManifest(dir) ?? {} as WorkspaceManifest + let shouldBeUpdated = false + for (const [key, value] of Object.entries(updatedFields)) { + if (!equals(manifest[key as keyof WorkspaceManifest], value)) { + shouldBeUpdated = true + if (value == null) { + delete manifest[key as keyof WorkspaceManifest] + } else { + // @ts-expect-error + manifest[key as keyof WorkspaceManifest] = value + } + } + } + if (!shouldBeUpdated) { + return + } + if (Object.keys(manifest).length === 0) { + await fs.promises.rm(path.join(dir, WORKSPACE_MANIFEST_FILENAME)) + return + } + await writeYamlFile(path.join(dir, WORKSPACE_MANIFEST_FILENAME), manifest) }