fix(update): allow to update subdependencies (#4133)

close #4122
This commit is contained in:
Zoltan Kochan authored and GitHub committed 2021-12-18 02:24:04 +02:00
1 parent 7962c042ea
commit 40dc2f954f
6 files changed
+52 -36

No files matched your search

+5
View File
@@ -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).
@@ -197,7 +197,7 @@ when running add/update with the --workspace option')
const updateMatch = opts.update && (params.length > 0) ? createMatcher(params) : null const updateMatch = opts.update && (params.length > 0) ? createMatcher(params) : null
if (updateMatch != null) { if (updateMatch != null) {
params = matchDependencies(updateMatch, manifest, includeDirect) params = matchDependencies(updateMatch, manifest, includeDirect)
if (params.length === 0) { if (params.length === 0 && opts.depth === 0) {
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies.') 'None of the specified packages were found in the dependencies.')
} }
@@ -275,7 +275,7 @@ export default async function recursive (
rootDir: opts.workspaceDir, rootDir: opts.workspaceDir,
} as MutatedProject) } as MutatedProject)
} }
if ((mutatedImporters.length === 0) && cmdFullName === 'update') { if ((mutatedImporters.length === 0) && cmdFullName === 'update' && opts.depth === 0) {
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies of any of the projects.') '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) throwOnFail(result)
if (!result.passes && cmdFullName === 'update') { if (!result.passes && cmdFullName === 'update' && opts.depth === 0) {
throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES', throw new PnpmError('NO_PACKAGE_IN_DEPENDENCIES',
'None of the specified packages were found in the dependencies of any of the projects.') 'None of the specified packages were found in the dependencies of any of the projects.')
} }
@@ -217,6 +217,7 @@ test('recursive update with pattern and name in project', async () => {
await update.handler({ await update.handler({
...DEFAULT_OPTS, ...DEFAULT_OPTS,
allProjects, allProjects,
depth: 0,
dir: process.cwd(), dir: process.cwd(),
latest: true, latest: true,
lockfileDir, lockfileDir,
@@ -230,6 +231,18 @@ test('recursive update with pattern and name in project', async () => {
expect(err).toBeTruthy() expect(err).toBeTruthy()
expect(err.code).toBe('ERR_PNPM_NO_PACKAGE_IN_DEPENDENCIES') 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({ await update.handler({
...DEFAULT_OPTS, ...DEFAULT_OPTS,
allProjects, allProjects,
@@ -388,6 +401,7 @@ test('recursive update in workspace should not add new dependencies', async () =
await update.handler({ await update.handler({
...DEFAULT_OPTS, ...DEFAULT_OPTS,
...await readProjects(process.cwd(), []), ...await readProjects(process.cwd(), []),
depth: 0,
dir: process.cwd(), dir: process.cwd(),
recursive: true, recursive: true,
workspaceDir: process.cwd(), workspaceDir: process.cwd(),
@@ -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') expect(err.message).toBe('Cannot use --latest with --workspace simultaneously')
}) })
test('update: fail when package not in dependencies', async () => { describe('update by package name', () => {
prepare({ beforeAll(async () => {
dependencies: { prepare({
'peer-a': '1.0.0', dependencies: {
'peer-c': '1.0.0', 'peer-a': '1.0.0',
}, 'peer-c': '1.0.0',
},
})
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 () => {
await install.handler({ let err!: PnpmError
...DEFAULT_OPTS, try {
dir: process.cwd(), await update.handler({
workspaceDir: process.cwd(), ...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.')
}) })
it("shouldn't fail when the package isn't in the direct dependencies", async () => {
let err!: PnpmError
try {
await update.handler({ await update.handler({
...DEFAULT_OPTS, ...DEFAULT_OPTS,
dir: process.cwd(), dir: process.cwd(),
sharedWorkspaceLockfile: true, sharedWorkspaceLockfile: true,
workspaceDir: process.cwd(), workspaceDir: process.cwd(),
}, ['peer-b']) }, ['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 () => { test('update --no-save should not update package.json and pnpm-lock.yaml', async () => {
-14
View File
@@ -137,20 +137,6 @@ test('recursive update --no-shared-workspace-lockfile', async function () {
expect(pkg.dependencies?.['foo']).toBe('^100.1.0') 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 () { test('update --latest', async function () {
const project = prepare() const project = prepare()