Skip to content
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

fix: a modified patch should update the deps on install #4918

Merged
merged 5 commits into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: fix
  • Loading branch information
zkochan committed Jun 24, 2022
commit dae54a8bc256f0d6d9ed53092dd6a2ff1f59803c
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"@pnpm/calc-dep-state": "workspace:3.0.0",
"@pnpm/constants": "workspace:6.1.0",
"@pnpm/core-loggers": "workspace:7.0.4",
"@pnpm/crypto.base32-hash": "workspace:^1.0.0",
"@pnpm/crypto.base32-hash": "workspace:1.0.0",
"@pnpm/error": "workspace:3.0.1",
"@pnpm/filter-lockfile": "workspace:6.0.7",
"@pnpm/get-context": "workspace:6.2.1",
Expand Down Expand Up @@ -141,7 +141,7 @@
"commitmsg": "commitlint -e",
"lint": "eslint src/**/*.ts test/**/*.ts",
"registry-mock": "registry-mock",
"test:jest": "jest test/install/patch.ts",
"test:jest": "jest",
"test:e2e": "registry-mock prepare && run-p -r registry-mock test:jest",
"test-with-preview": "preview && pnpm run test:e2e",
"_test": "cross-env PNPM_REGISTRY_MOCK_PORT=4873 pnpm run test:e2e",
Expand Down
28 changes: 17 additions & 11 deletions packages/core/src/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,25 +235,30 @@ export async function mutateModules (
)
}
const packageExtensionsChecksum = isEmpty(opts.packageExtensions ?? {}) ? undefined : createObjectChecksum(opts.packageExtensions!)
const patchedDependencies = opts.patchedDependencies ? await resolvePatches(opts.patchedDependencies, opts.lockfileDir) : {}
const patchedDependenciesHashes = patchedDependencies
? fromPairs(Object.entries(patchedDependencies).map(([key, { hash }]) => [key, hash]))
const patchedDependencies = opts.ignorePackageManifest
? ctx.wantedLockfile.patchedDependencies
: (opts.patchedDependencies ? await calcPatchHashes(opts.patchedDependencies, opts.lockfileDir) : {})
const patchedDependenciesWithResolvedPath = patchedDependencies
? fromPairs(Object.entries(patchedDependencies).map(([key, patchFile]) => [key, {
hash: patchFile.hash,
path: path.join(opts.lockfileDir, patchFile.path),
}]))
: undefined
let needsFullResolution = !maybeOpts.ignorePackageManifest &&
lockfileIsUpToDate(ctx.wantedLockfile, {
overrides: opts.overrides,
neverBuiltDependencies: opts.neverBuiltDependencies,
onlyBuiltDependencies: opts.onlyBuiltDependencies,
packageExtensionsChecksum,
patchedDependencies: patchedDependenciesHashes,
patchedDependencies,
}) ||
opts.fixLockfile
if (needsFullResolution) {
ctx.wantedLockfile.overrides = opts.overrides
ctx.wantedLockfile.neverBuiltDependencies = opts.neverBuiltDependencies
ctx.wantedLockfile.onlyBuiltDependencies = opts.onlyBuiltDependencies
ctx.wantedLockfile.packageExtensionsChecksum = packageExtensionsChecksum
ctx.wantedLockfile.patchedDependencies = patchedDependenciesHashes
ctx.wantedLockfile.patchedDependencies = patchedDependencies
}
const frozenLockfile = opts.frozenLockfile ||
opts.frozenLockfileIfExists && ctx.existsWantedLockfile
Expand Down Expand Up @@ -301,6 +306,7 @@ export async function mutateModules (
nodeVersion: opts.nodeVersion,
pnpmVersion: opts.packageManager.name === 'pnpm' ? opts.packageManager.version : '',
},
patchedDependenciesWithResolvedPath,
projects: ctx.projects as Project[],
prunedAt: ctx.modulesFile?.prunedAt,
pruneVirtualStore,
Expand Down Expand Up @@ -484,22 +490,22 @@ export async function mutateModules (
pruneVirtualStore,
scriptsOpts,
updateLockfileMinorVersion: true,
patchedDependenciesWithHashes: patchedDependencies,
patchedDependenciesWithResolvedPath,
})

return result.projects
}
}

async function resolvePatches (patches: Record<string, string>, lockfileDir: string) {
async function calcPatchHashes (patches: Record<string, string>, lockfileDir: string) {
return fromPairs(await Promise.all(
Object.entries(patches).map(async ([key, patchFileRelativePath]) => {
const patchFilePath = path.join(lockfileDir, patchFileRelativePath)
return [
key,
{
hash: await createBase32HashFromFile(patchFilePath),
path: patchFilePath,
path: patchFileRelativePath,
},
]
})
Expand All @@ -519,7 +525,7 @@ function lockfileIsUpToDate (
onlyBuiltDependencies?: string[]
overrides?: Record<string, string>
packageExtensionsChecksum?: string
patchedDependencies?: Record<string, string>
patchedDependencies?: Record<string, { path: string, hash: string }>
}) {
return !equals(lockfile.overrides ?? {}, overrides ?? {}) ||
!equals((lockfile.neverBuiltDependencies ?? []).sort(), (neverBuiltDependencies ?? []).sort()) ||
Expand Down Expand Up @@ -674,7 +680,7 @@ type InstallFunction = (
projects: ImporterToUpdate[],
ctx: PnpmContext<DependenciesMutation>,
opts: StrictInstallOptions & {
patchedDependenciesWithHashes: Record<string, { path: string, hash: string }>
patchedDependenciesWithResolvedPath?: Record<string, { path: string, hash: string }>
makePartialCurrentLockfile: boolean
needsFullResolution: boolean
neverBuiltDependencies?: string[]
Expand Down Expand Up @@ -800,7 +806,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
virtualStoreDir: ctx.virtualStoreDir,
wantedLockfile: ctx.wantedLockfile,
workspacePackages: opts.workspacePackages,
patchedDependencies: opts.patchedDependenciesWithHashes,
patchedDependencies: opts.patchedDependenciesWithResolvedPath,
}
)

Expand Down
9 changes: 7 additions & 2 deletions packages/core/test/install/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ test('patch package', async () => {

const patchFileHash = 'jnbpamcxayl5i4ehrkoext3any'
const lockfile = await project.readLockfile()
expect(lockfile.patchedDependencies).toStrictEqual(patchedDependencies)
expect(lockfile.patchedDependencies).toStrictEqual({
'is-positive@1.0.0': {
path: patchedDependencies['is-positive@1.0.0'],
hash: patchFileHash,
},
})
expect(lockfile.packages[`/is-positive/1.0.0_${patchFileHash}`]).toBeTruthy()

const filesIndexFile = path.join(opts.storeDir, 'files/c7/1ccf199e0fdae37aad13946b937d67bcd35fa111b84d21b3a19439cfdc2812c5d8da8a735e94c2a1ccb77b4583808ee8405313951e7146ac83ede3671dc292-index.json')
Expand Down Expand Up @@ -114,7 +119,7 @@ test('patch package throws an exception if not all patches are applied', async (
).rejects.toThrow('The following patches were not applied: is-negative@1.0.0')
})

test.only('the patched package is updated if the patch is modified', async () => {
test('the patched package is updated if the patch is modified', async () => {
prepareEmpty()
f.copy('patch-pkg', 'patches')
const patchPath = path.resolve('patches', 'is-positive@1.0.0.patch')
Expand Down
3 changes: 3 additions & 0 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
{
"path": "../core-loggers"
},
{
"path": "../crypto.base32-hash"
},
{
"path": "../dependency-path"
},
Expand Down
1 change: 1 addition & 0 deletions packages/headless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export interface HeadlessOptions {
lockfileDir: string
modulesDir?: string
virtualStoreDir?: string
patchedDependenciesWithResolvedPath?: Record<string, { path: string, hash: string }>
scriptsPrependNodePath?: boolean | 'warn-only'
scriptShell?: string
shellEmulator?: boolean
Expand Down
16 changes: 2 additions & 14 deletions packages/headless/src/lockfileToDepGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { WANTED_LOCKFILE } from '@pnpm/constants'
import {
progressLogger,
} from '@pnpm/core-loggers'
import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash'
import {
Lockfile,
PackageSnapshot,
Expand Down Expand Up @@ -63,6 +62,7 @@ export interface LockfileToDepGraphOptions {
lockfileDir: string
nodeVersion: string
pnpmVersion: string
patchedDependenciesWithResolvedPath?: Record<string, { path: string, hash: string }>
registries: Registries
sideEffectsCacheRead: boolean
skipped: Set<string>
Expand Down Expand Up @@ -180,7 +180,7 @@ export default async function lockfileToDepGraph (
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
prepare: pkgSnapshot.prepare === true,
requiresBuild: pkgSnapshot.requiresBuild === true,
patchFile: await tryReadPatchFile(opts.lockfileDir, lockfile, pkgName, pkgVersion),
patchFile: opts.patchedDependenciesWithResolvedPath?.[`${pkgName}@${pkgVersion}`],
}
pkgSnapshotByLocation[dir] = pkgSnapshot
})
Expand Down Expand Up @@ -220,18 +220,6 @@ export default async function lockfileToDepGraph (
return { graph, directDependenciesByImporterId }
}

export async function tryReadPatchFile (lockfileDir: string, lockfile: Lockfile, pkgName: string, pkgVersion: string) {
const patchFileRelativePath = lockfile.patchedDependencies?.[`${pkgName}@${pkgVersion}`]
if (!patchFileRelativePath) {
return undefined
}
const patchFilePath = path.join(lockfileDir, patchFileRelativePath)
return {
path: patchFilePath,
hash: await createBase32HashFromFile(patchFilePath),
}
}

async function getChildrenPaths (
ctx: {
graph: DependenciesGraph
Expand Down
4 changes: 2 additions & 2 deletions packages/headless/src/lockfileToHoistedDepGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
DepHierarchy,
DirectDependenciesByImporterId,
LockfileToDepGraphResult,
tryReadPatchFile,
} from './lockfileToDepGraph'

export interface LockfileToHoistedDepGraphOptions {
Expand All @@ -36,6 +35,7 @@ export interface LockfileToHoistedDepGraphOptions {
nodeVersion: string
pnpmVersion: string
registries: Registries
patchedDependenciesWithResolvedPath?: Record<string, { path: string, hash: string }>
sideEffectsCacheRead: boolean
skipped: Set<string>
storeController: StoreController
Expand Down Expand Up @@ -209,7 +209,7 @@ async function fetchDeps (
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
prepare: pkgSnapshot.prepare === true,
requiresBuild: pkgSnapshot.requiresBuild === true,
patchFile: await tryReadPatchFile(opts.lockfileDir, opts.lockfile, pkgName, pkgVersion),
patchFile: opts.patchedDependenciesWithResolvedPath?.[`${pkgName}@${pkgVersion}`],
}
opts.pkgLocationByDepPath[depPath] = dir
depHierarchy[dir] = await fetchDeps(opts, path.join(dir, 'node_modules'), dep.dependencies)
Expand Down
7 changes: 6 additions & 1 deletion packages/lockfile-types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { DependenciesMeta } from '@pnpm/types'

export interface PatchFile {
path: string
hash: string
}

export interface Lockfile {
importers: Record<string, ProjectSnapshot>
lockfileVersion: number
Expand All @@ -8,7 +13,7 @@ export interface Lockfile {
onlyBuiltDependencies?: string[]
overrides?: Record<string, string>
packageExtensionsChecksum?: string
patchedDependencies?: Record<string, string>
patchedDependencies?: Record<string, PatchFile>
}

export interface ProjectSnapshot {
Expand Down
2 changes: 1 addition & 1 deletion packages/resolve-dependencies/src/resolveDependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ async function resolveDependency (
})

const nameAndVersion = `${pkg.name}@${pkg.version}`
let patchFile = ctx.patchedDependencies?.[nameAndVersion]
const patchFile = ctx.patchedDependencies?.[nameAndVersion]
if (patchFile) {
ctx.appliedPatches.add(nameAndVersion)
}
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.