diff --git a/.changeset/nasty-games-grab.md b/.changeset/nasty-games-grab.md new file mode 100644 index 0000000000..3a4a892418 --- /dev/null +++ b/.changeset/nasty-games-grab.md @@ -0,0 +1,6 @@ +--- +"@pnpm/outdated": patch +"pnpm": patch +--- + +Fix error as in `update -i -r` with git specifiers [#7415](https://github.com/pnpm/pnpm/issues/7415). diff --git a/pkg-manager/plugin-commands-installation/test/update/issue-7415.ts b/pkg-manager/plugin-commands-installation/test/update/issue-7415.ts new file mode 100644 index 0000000000..005bfe2bfa --- /dev/null +++ b/pkg-manager/plugin-commands-installation/test/update/issue-7415.ts @@ -0,0 +1,96 @@ +import path from 'path' +import { preparePackages } from '@pnpm/prepare' +import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock' +import { update, install } from '@pnpm/plugin-commands-installation' +import * as enquirer from 'enquirer' +import { readProjects } from '@pnpm/filter-workspace-packages' + +jest.mock('enquirer', () => ({ prompt: jest.fn() })) + +// eslint-disable-next-line +const prompt = enquirer.prompt as any as jest.Mock + +const REGISTRY_URL = `http://localhost:${REGISTRY_MOCK_PORT}` + +const DEFAULT_OPTIONS = { + argv: { + original: [], + }, + bail: false, + bin: 'node_modules/.bin', + extraEnv: {}, + cliOptions: {}, + deployAllFiles: false, + include: { + dependencies: true, + devDependencies: true, + optionalDependencies: true, + }, + lock: true, + pnpmfile: '.pnpmfile.cjs', + pnpmHomeDir: '', + rawConfig: { registry: REGISTRY_URL }, + rawLocalConfig: { registry: REGISTRY_URL }, + registries: { + default: REGISTRY_URL, + }, + rootProjectManifestDir: '', + sort: true, + userConfig: {}, + workspaceConcurrency: 1, +} + +test('interactive recursive should not error on git specifier override', async () => { + preparePackages([ + { + location: '.', + package: { + pnpm: { + overrides: { + 'is-negative': 'github:kevva/is-negative#2.1.0', + }, + }, + }, + }, + { + location: './project-1', + package: { + dependencies: { + 'is-negative': '2.1.0', + }, + }, + }, + ]) + + prompt.mockResolvedValue({ + updateDependencies: [], + }) + + const { allProjects, selectedProjectsGraph } = await readProjects(process.cwd(), []) + const sharedOptions = { + ...DEFAULT_OPTIONS, + allProjects, + selectedProjectsGraph, + recursive: true, + linkWorkspacePackages: true, + cacheDir: path.resolve('cache'), + storeDir: path.resolve('store'), + dir: process.cwd(), + lockfileDir: process.cwd(), + workspaceDir: process.cwd(), + } + + await install.handler({ + ...sharedOptions, + }) + await update.handler({ + ...sharedOptions, + interactive: true, + latest: true, + cliOptions: { + dev: true, + optional: true, + production: true, + }, + }) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b46aaa8cdb..32af664d83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5261,6 +5261,9 @@ importers: '@pnpm/error': specifier: workspace:* version: link:../../packages/error + '@pnpm/hooks.read-package-hook': + specifier: workspace:* + version: link:../../hooks/read-package-hook '@pnpm/lockfile-file': specifier: workspace:* version: link:../../lockfile/lockfile-file @@ -9377,7 +9380,7 @@ packages: resolution: {integrity: sha512-YmG+oTBCyrAoMIx5g2I9CfyurSpHyoan+9SCj7laaFKseOe3lFEyIVKvwRBQMmSt8uzh+eY5RWeQnoyyOs6AbA==} engines: {node: '>=14.15.0'} peerDependencies: - '@yarnpkg/fslib': ^3.0.0-rc.25 + '@yarnpkg/fslib': 3.0.0-rc.25 dependencies: '@types/emscripten': 1.39.10 '@yarnpkg/fslib': 3.0.0-rc.25 diff --git a/reviewing/outdated/package.json b/reviewing/outdated/package.json index b0e667f918..dfc6ccf98c 100644 --- a/reviewing/outdated/package.json +++ b/reviewing/outdated/package.json @@ -37,6 +37,7 @@ "@pnpm/constants": "workspace:*", "@pnpm/dependency-path": "workspace:*", "@pnpm/error": "workspace:*", + "@pnpm/hooks.read-package-hook": "workspace:*", "@pnpm/lockfile-file": "workspace:*", "@pnpm/lockfile-utils": "workspace:*", "@pnpm/manifest-utils": "workspace:*", diff --git a/reviewing/outdated/src/outdated.ts b/reviewing/outdated/src/outdated.ts index f65d7028f3..59dd27995a 100644 --- a/reviewing/outdated/src/outdated.ts +++ b/reviewing/outdated/src/outdated.ts @@ -20,6 +20,7 @@ import { import * as dp from '@pnpm/dependency-path' import semver from 'semver' import { createMatcher } from '@pnpm/matcher' +import { createReadPackageHook } from '@pnpm/hooks.read-package-hook' export * from './createManifestGetter' @@ -54,7 +55,22 @@ export async function outdated ( if (opts.wantedLockfile == null) { throw new PnpmError('OUTDATED_NO_LOCKFILE', `No lockfile in directory "${opts.lockfileDir}". Run \`pnpm install\` to generate one.`) } - const allDeps = getAllDependenciesFromManifest(opts.manifest) + + async function getOverriddenManifest () { + const overrides = opts.currentLockfile?.overrides ?? opts.wantedLockfile?.overrides + if (overrides) { + const readPackageHook = createReadPackageHook({ + lockfileDir: opts.lockfileDir, + overrides, + }) + const manifest = await readPackageHook?.(opts.manifest, opts.lockfileDir) + if (manifest) return manifest + } + + return opts.manifest + } + + const allDeps = getAllDependenciesFromManifest(await getOverriddenManifest()) const importerId = getLockfileImporterId(opts.lockfileDir, opts.prefix) const currentLockfile = opts.currentLockfile ?? { importers: { [importerId]: {} } } diff --git a/reviewing/outdated/tsconfig.json b/reviewing/outdated/tsconfig.json index ca2e85c38d..db386bb49f 100644 --- a/reviewing/outdated/tsconfig.json +++ b/reviewing/outdated/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../../config/pick-registry-for-package" }, + { + "path": "../../hooks/read-package-hook" + }, { "path": "../../lockfile/lockfile-file" },