Skip to content

Preserve patches for transitive dependencies via internal packages#177

Merged
0x80 merged 2 commits intomainfrom
thijs/0422-transative-patched-dependencies
Apr 22, 2026
Merged

Preserve patches for transitive dependencies via internal packages#177
0x80 merged 2 commits intomainfrom
thijs/0422-transative-patched-dependencies

Conversation

@0x80
Copy link
Copy Markdown
Owner

@0x80 0x80 commented Apr 22, 2026

Fixes #167.

When a workspace declares pnpm.patchedDependencies for a package that is not a direct dependency of the isolate target but is reachable through an internal workspace package, the patch was silently dropped from the isolated output. filterPatchedDependencies checked only the target's own dependencies/devDependencies, so e.g. a patch on tslib (a dep of an internal firebase-package) never made it into the isolated package.json or the patches/ folder.

copyPatches now computes the set of dependency names reachable from the target by walking the target manifest plus the manifests of every internal workspace package it can reach. That set is passed to filterPatchedDependencies as a third matching fallback after direct prod and direct dev deps: if the patch's package name is in the reachable set, the patch is preserved. Internal packages' devDependencies are intentionally not followed since they aren't installed in the isolate.

Limitation: this does not cover patches on deeper external-to-external transitives (target → externalA → externalB-patched). Addressing those requires lockfile-based pruning, which hasn't been observed as a practical need yet.

Scope: packages (isolate-package)
Visibility: user-facing

When a workspace has pnpm.patchedDependencies for a package that is
not a direct dependency of the isolate target but is reachable through
an internal workspace package, the patch was silently dropped.

filterPatchedDependencies now also accepts a set of dependency names
reachable via internal workspace manifests, computed by the new
collectReachablePackageNames helper. Patches for names in this set
are preserved so pnpm can apply them at install time.
Copilot AI review requested due to automatic review settings April 22, 2026 07:33
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 883753b. Configure here.

Comment thread src/lib/utils/filter-patched-dependencies.ts
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes an isolation bug where workspace-level pnpm.patchedDependencies entries targeting transitives introduced via internal workspace packages were omitted from the isolated output.

Changes:

  • Extend filterPatchedDependencies to preserve patches for package names reachable via internal workspace packages.
  • Add collectReachablePackageNames to compute reachable dependency names by walking the target + internal workspace manifests.
  • Plumb packagesRegistry into copyPatches so it can compute reachability and pass it into the filter, with regression tests.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/lib/utils/filter-patched-dependencies.ts Adds reachableDependencyNames fallback when filtering patched deps.
src/lib/utils/filter-patched-dependencies.test.ts Adds tests for reachability-based inclusion/exclusion behavior.
src/lib/registry/index.ts Re-exports the new reachability collector.
src/lib/registry/collect-reachable-package-names.ts New helper to walk target + internal workspace manifests and collect reachable dep names.
src/lib/registry/collect-reachable-package-names.test.ts Unit tests for reachability collection (direct deps, recursion, cycles, devDep rules).
src/lib/patches/copy-patches.ts Computes reachable names and passes them into filterPatchedDependencies; adds packagesRegistry param.
src/lib/patches/copy-patches.test.ts Updates tests for the new packagesRegistry arg + regression coverage for issue #167 plumbing.
src/isolate.ts Passes packagesRegistry into copyPatches.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/utils/filter-patched-dependencies.ts Outdated
Comment thread src/lib/utils/filter-patched-dependencies.test.ts Outdated
Comment thread src/lib/registry/collect-reachable-package-names.ts
Address three issues raised by review bots on PR #177:

- filterPatchedDependencies: when a patch target is listed in the target's
  devDependencies with includeDevDependencies=false, still check the
  reachable set before excluding. A package can be both a target devDep and
  a prod transitive via an internal workspace package, in which case the
  patch still applies.
- collectReachablePackageNames: also walk optionalDependencies and
  peerDependencies. Both can lead to packages being installed in the
  isolate (pnpm installs peers by default via autoInstallPeers), so
  patches on them should be preserved.
- Replace the test that codified the buggy devDep-over-reachable behavior
  with one covering the correct prod-transitive override case, and add
  tests for optional/peer deps.
@0x80 0x80 merged commit 3d66d6f into main Apr 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Upstream/transitive patched dependencies are omitted during isolation

2 participants