diff --git a/.changeset/eight-ads-mate.md b/.changeset/eight-ads-mate.md new file mode 100644 index 0000000000..0d1ecdbc39 --- /dev/null +++ b/.changeset/eight-ads-mate.md @@ -0,0 +1,5 @@ +--- +"@pnpm/plugin-commands-installation": patch +--- + +`pnpm update pkg` should not fail if `pkg` not found as a direct dependency, unless `--depth=0` is passed as a CLI option [#4122](https://github.com/pnpm/pnpm/issues/4122). diff --git a/packages/plugin-commands-installation/src/installDeps.ts b/packages/plugin-commands-installation/src/installDeps.ts index 12063a84f2..5b2fb7680d 100644 --- a/packages/plugin-commands-installation/src/installDeps.ts +++ b/packages/plugin-commands-installation/src/installDeps.ts @@ -197,7 +197,7 @@ when running add/update with the --workspace option') const updateMatch = opts.update && (params.length > 0) ? createMatcher(params) : null if (updateMatch != null) { params = matchDependencies(updateMatch, manifest, includeDirect) - if (params.length === 0) { + if (params.length === 0 && opts.depth === 0) { throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', 'None of the specified packages were found in the dependencies.') } diff --git a/packages/plugin-commands-installation/src/recursive.ts b/packages/plugin-commands-installation/src/recursive.ts index caf9bd2175..8bc1a3c869 100755 --- a/packages/plugin-commands-installation/src/recursive.ts +++ b/packages/plugin-commands-installation/src/recursive.ts @@ -275,7 +275,7 @@ export default async function recursive ( rootDir: opts.workspaceDir, } as MutatedProject) } - if ((mutatedImporters.length === 0) && cmdFullName === 'update') { + if ((mutatedImporters.length === 0) && cmdFullName === 'update' && opts.depth === 0) { throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', 'None of the specified packages were found in the dependencies of any of the projects.') } @@ -412,7 +412,7 @@ export default async function recursive ( throwOnFail(result) - if (!result.passes && cmdFullName === 'update') { + if (!result.passes && cmdFullName === 'update' && opts.depth === 0) { throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', 'None of the specified packages were found in the dependencies of any of the projects.') } diff --git a/packages/plugin-commands-installation/test/update/recursive.ts b/packages/plugin-commands-installation/test/update/recursive.ts index 1147a95826..b303f9081b 100644 --- a/packages/plugin-commands-installation/test/update/recursive.ts +++ b/packages/plugin-commands-installation/test/update/recursive.ts @@ -217,6 +217,7 @@ test('recursive update with pattern and name in project', async () => { await update.handler({ ...DEFAULT_OPTS, allProjects, + depth: 0, dir: process.cwd(), latest: true, lockfileDir, @@ -230,6 +231,18 @@ test('recursive update with pattern and name in project', async () => { expect(err).toBeTruthy() expect(err.code).toBe('ERR_PNPM_NO_PACKAGE_IN_DEPENDENCIES') + // This should not fail because depth=0 is not specified + await update.handler({ + ...DEFAULT_OPTS, + allProjects, + dir: process.cwd(), + latest: true, + lockfileDir, + recursive: true, + selectedProjectsGraph, + workspaceDir: process.cwd(), + }, ['this-does-not-exist']) + await update.handler({ ...DEFAULT_OPTS, allProjects, @@ -388,6 +401,7 @@ test('recursive update in workspace should not add new dependencies', async () = await update.handler({ ...DEFAULT_OPTS, ...await readProjects(process.cwd(), []), + depth: 0, dir: process.cwd(), recursive: true, workspaceDir: process.cwd(), diff --git a/packages/plugin-commands-installation/test/update/update.ts b/packages/plugin-commands-installation/test/update/update.ts index 449833dcdf..944991ad2e 100644 --- a/packages/plugin-commands-installation/test/update/update.ts +++ b/packages/plugin-commands-installation/test/update/update.ts @@ -70,33 +70,44 @@ test('update: fail when both "latest" and "workspace" are true', async () => { expect(err.message).toBe('Cannot use --latest with --workspace simultaneously') }) -test('update: fail when package not in dependencies', async () => { - prepare({ - dependencies: { - 'peer-a': '1.0.0', - 'peer-c': '1.0.0', - }, +describe('update by package name', () => { + beforeAll(async () => { + prepare({ + dependencies: { + 'peer-a': '1.0.0', + 'peer-c': '1.0.0', + }, + }) + await install.handler({ + ...DEFAULT_OPTS, + dir: process.cwd(), + workspaceDir: process.cwd(), + }) }) - - await install.handler({ - ...DEFAULT_OPTS, - dir: process.cwd(), - workspaceDir: process.cwd(), + it("should fail when the package isn't in the direct dependencies and depth is 0", async () => { + let err!: PnpmError + try { + await update.handler({ + ...DEFAULT_OPTS, + depth: 0, + dir: process.cwd(), + sharedWorkspaceLockfile: true, + workspaceDir: process.cwd(), + }, ['peer-b']) + } catch (_err: any) { // eslint-disable-line + err = _err + } + expect(err.code).toBe('ERR_PNPM_NO_PACKAGE_IN_DEPENDENCIES') + expect(err.message).toBe('None of the specified packages were found in the dependencies of any of the projects.') }) - - let err!: PnpmError - try { + it("shouldn't fail when the package isn't in the direct dependencies", async () => { await update.handler({ ...DEFAULT_OPTS, dir: process.cwd(), sharedWorkspaceLockfile: true, workspaceDir: process.cwd(), }, ['peer-b']) - } catch (_err: any) { // eslint-disable-line - err = _err - } - expect(err.code).toBe('ERR_PNPM_NO_PACKAGE_IN_DEPENDENCIES') - expect(err.message).toBe('None of the specified packages were found in the dependencies of any of the projects.') + }) }) test('update --no-save should not update package.json and pnpm-lock.yaml', async () => { diff --git a/packages/pnpm/test/update.ts b/packages/pnpm/test/update.ts index f21b28dd55..12a88ccc08 100644 --- a/packages/pnpm/test/update.ts +++ b/packages/pnpm/test/update.ts @@ -137,20 +137,6 @@ test('recursive update --no-shared-workspace-lockfile', async function () { expect(pkg.dependencies?.['foo']).toBe('^100.1.0') }) -test('update should not install the dependency if it is not present already', async () => { - const project = prepare() - - let err!: Error - try { - await execPnpm(['update', 'is-positive']) - } catch (_err: any) { // eslint-disable-line - err = _err - } - expect(err).toBeTruthy() - - await project.hasNot('is-positive') -}) - test('update --latest', async function () { const project = prepare()