-
Notifications
You must be signed in to change notification settings - Fork 19
copy patches with pnpm #142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,11 +13,83 @@ import { | |
| import { pruneLockfile as pruneLockfile_v8 } from "pnpm_prune_lockfile_v8"; | ||
| import { pruneLockfile as pruneLockfile_v9 } from "pnpm_prune_lockfile_v9"; | ||
| import { pick } from "remeda"; | ||
| import type { Logger } from "~/lib/logger"; | ||
| import { useLogger } from "~/lib/logger"; | ||
| import type { PackageManifest, PackagesRegistry } from "~/lib/types"; | ||
| import { getErrorMessage, isRushWorkspace } from "~/lib/utils"; | ||
| import { pnpmMapImporter } from "./pnpm-map-importer"; | ||
|
|
||
| function filterPatchedDependencies( | ||
| originalPatchedDependencies: any, | ||
| targetPackageManifest: PackageManifest, | ||
| includeDevDependencies: boolean, | ||
| log: Logger | ||
| ): any { | ||
|
||
| if ( | ||
| !originalPatchedDependencies || | ||
| typeof originalPatchedDependencies !== "object" | ||
| ) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const getPackageName = (packageSpec: string): string => { | ||
| // Handle scoped packages: @scope/package@version -> @scope/package | ||
| if (packageSpec.startsWith("@")) { | ||
| const parts = packageSpec.split("@"); | ||
| return `@${parts[1]}`; | ||
| } | ||
| // Handle regular packages: package@version -> package | ||
| return packageSpec.split("@")[0]; | ||
| }; | ||
|
|
||
| const filteredPatches: any = {}; | ||
|
||
| let includedCount = 0; | ||
| let excludedCount = 0; | ||
|
|
||
| for (const [packageSpec, patchInfo] of Object.entries( | ||
| originalPatchedDependencies | ||
| )) { | ||
| const packageName = getPackageName(packageSpec); | ||
|
|
||
| // Check if it's a regular dependency | ||
| if (targetPackageManifest.dependencies?.[packageName]) { | ||
| filteredPatches[packageSpec] = patchInfo; | ||
| includedCount++; | ||
| log.debug( | ||
| `Including production dependency patch in lockfile: ${packageSpec}` | ||
| ); | ||
| continue; | ||
| } | ||
|
|
||
| // Check if it's a dev dependency and we should include dev dependencies | ||
| if (targetPackageManifest.devDependencies?.[packageName]) { | ||
| if (includeDevDependencies) { | ||
| filteredPatches[packageSpec] = patchInfo; | ||
| includedCount++; | ||
| log.debug(`Including dev dependency patch in lockfile: ${packageSpec}`); | ||
| } else { | ||
| excludedCount++; | ||
| log.debug( | ||
| `Excluding dev dependency patch from lockfile: ${packageSpec}` | ||
| ); | ||
| } | ||
| continue; | ||
| } | ||
|
|
||
| // Package not found in dependencies or devDependencies | ||
| log.debug( | ||
| `Excluding patch from lockfile: ${packageSpec} (package "${packageName}" not found in target dependencies)` | ||
| ); | ||
| excludedCount++; | ||
| } | ||
|
|
||
| log.debug( | ||
| `Filtered patched dependencies: ${includedCount} included, ${excludedCount} excluded` | ||
| ); | ||
|
|
||
| return Object.keys(filteredPatches).length > 0 ? filteredPatches : undefined; | ||
| } | ||
|
|
||
| export async function generatePnpmLockfile({ | ||
| workspaceRootDir, | ||
| targetPackageDir, | ||
|
|
@@ -40,14 +112,22 @@ export async function generatePnpmLockfile({ | |
| includePatchedDependencies: boolean; | ||
| }) { | ||
| /** | ||
| * For now we will assume that the lockfile format might not change in the | ||
| * versions after 9, because we might get lucky. If it does change, things | ||
| * would break either way. | ||
| * PNPM 10+ uses the same lockfile format as version 9, but with | ||
| * lockfileVersion: '10.0' Since @pnpm/lockfile-file v10 packages don't exist | ||
| * yet, we use v9 packages for PNPM 10+. This should work because PNPM | ||
| * maintains backward compatibility, but we log a warning to alert users of | ||
| * potential edge cases. | ||
| */ | ||
| const useVersion9 = majorVersion >= 9; | ||
|
|
||
| const log = useLogger(); | ||
|
|
||
| if (majorVersion >= 10) { | ||
| log.debug( | ||
| `Using PNPM v${majorVersion} with v9 lockfile packages - this should work but may have limitations` | ||
| ); | ||
| } | ||
|
|
||
| log.debug("Generating PNPM lockfile..."); | ||
|
|
||
| try { | ||
|
|
@@ -163,13 +243,18 @@ export async function generatePnpmLockfile({ | |
| } | ||
|
|
||
| /** | ||
| * Don't know how to map the patched dependencies yet, so we just include | ||
| * them but I don't think it would work like this. The important thing for | ||
| * now is that they are omitted by default, because that is the most common | ||
| * use case. | ||
| * Filter patched dependencies to only include patches for packages that | ||
| * will actually be present in the isolated lockfile based on dependency | ||
| * type. We read patchedDependencies from workspace root, but filter based | ||
| * on target package dependencies. | ||
| */ | ||
| const patchedDependencies = includePatchedDependencies | ||
| ? lockfile.patchedDependencies | ||
| ? filterPatchedDependencies( | ||
| lockfile.patchedDependencies, | ||
| targetPackageManifest, | ||
| includeDevDependencies, | ||
| log | ||
| ) | ||
| : undefined; | ||
|
|
||
| useVersion9 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
anytype should be replaced with a more specific type. Consider usingRecord<string, string>or defining a proper type for patchedDependencies based on the pnpm specification.