From bcffd4d72b08b05cb784df94ef0135a98d1b979b Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 16 Sep 2024 01:19:03 +0200 Subject: [PATCH] feat!: use SHA256 for hashing the pnpmfile content (#8530) --- .changeset/nine-cups-smash.md | 6 ++++++ crypto/hash/src/index.ts | 12 ++++++++++++ hooks/pnpmfile/package.json | 2 +- hooks/pnpmfile/src/requireHooks.ts | 4 ++-- hooks/pnpmfile/tsconfig.json | 6 +++--- pnpm-lock.yaml | 7 +++++-- pnpm/package.json | 1 + pnpm/test/hooks.ts | 6 +++--- pnpm/tsconfig.json | 3 +++ 9 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .changeset/nine-cups-smash.md diff --git a/.changeset/nine-cups-smash.md b/.changeset/nine-cups-smash.md new file mode 100644 index 0000000000..25c0a70f1f --- /dev/null +++ b/.changeset/nine-cups-smash.md @@ -0,0 +1,6 @@ +--- +"@pnpm/pnpmfile": major +"pnpm": major +--- + +Use SHA256 for storing the pnpmfile checksum in the lockfile [#8530](https://github.com/pnpm/pnpm/pull/8530). diff --git a/crypto/hash/src/index.ts b/crypto/hash/src/index.ts index fa4410cae5..d0e291bbb4 100644 --- a/crypto/hash/src/index.ts +++ b/crypto/hash/src/index.ts @@ -1,7 +1,19 @@ import crypto from 'crypto' +import fs from 'fs' export function createShortHash (input: string): string { const hash = crypto.createHash('sha256') hash.update(input) return hash.digest('hex').substring(0, 32) } + +export function createHash (input: string): string { + const hash = crypto.createHash('sha256') + hash.update(input) + return `sha256-${hash.digest('base64')}` +} + +export async function createHashFromFile (file: string): Promise { + const content = await fs.promises.readFile(file, 'utf8') + return createHash(content.split('\r\n').join('\n')) +} diff --git a/hooks/pnpmfile/package.json b/hooks/pnpmfile/package.json index a7d866b846..d1462073d9 100644 --- a/hooks/pnpmfile/package.json +++ b/hooks/pnpmfile/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@pnpm/core-loggers": "workspace:*", - "@pnpm/crypto.base32-hash": "workspace:*", + "@pnpm/crypto.hash": "workspace:*", "@pnpm/error": "workspace:*", "@pnpm/hooks.types": "workspace:*", "@pnpm/lockfile.types": "workspace:*", diff --git a/hooks/pnpmfile/src/requireHooks.ts b/hooks/pnpmfile/src/requireHooks.ts index fa11d2e3fc..e7c117109a 100644 --- a/hooks/pnpmfile/src/requireHooks.ts +++ b/hooks/pnpmfile/src/requireHooks.ts @@ -1,6 +1,6 @@ import type { PreResolutionHookContext, PreResolutionHookLogger } from '@pnpm/hooks.types' import { hookLogger } from '@pnpm/core-loggers' -import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash' +import { createHashFromFile } from '@pnpm/crypto.hash' import pathAbsolute from 'path-absolute' import type { CustomFetchers } from '@pnpm/fetcher-base' import { type ImportIndexedPackageAsync } from '@pnpm/store-controller-types' @@ -40,7 +40,7 @@ export function requireHooks ( let hooks: Hooks | undefined = pnpmFile?.hooks if (!globalHooks && !hooks) return { afterAllResolved: [], filterLog: [], readPackage: [] } - const calculatePnpmfileChecksum = hooks ? () => createBase32HashFromFile(pnpmfilePath) : undefined + const calculatePnpmfileChecksum = hooks ? () => createHashFromFile(pnpmfilePath) : undefined globalHooks = globalHooks ?? {} hooks = hooks ?? {} const cookedHooks: CookedHooks & Required> = { diff --git a/hooks/pnpmfile/tsconfig.json b/hooks/pnpmfile/tsconfig.json index 0e2d9e2a63..abeca86053 100644 --- a/hooks/pnpmfile/tsconfig.json +++ b/hooks/pnpmfile/tsconfig.json @@ -9,6 +9,9 @@ "../../__typings__/**/*.d.ts" ], "references": [ + { + "path": "../../crypto/hash" + }, { "path": "../../fetching/fetcher-base" }, @@ -18,9 +21,6 @@ { "path": "../../packages/core-loggers" }, - { - "path": "../../packages/crypto.base32-hash" - }, { "path": "../../packages/error" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ae51addeb..2c20c7fd13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2667,9 +2667,9 @@ importers: '@pnpm/core-loggers': specifier: workspace:* version: link:../../packages/core-loggers - '@pnpm/crypto.base32-hash': + '@pnpm/crypto.hash': specifier: workspace:* - version: link:../../packages/crypto.base32-hash + version: link:../../crypto/hash '@pnpm/error': specifier: workspace:* version: link:../../packages/error @@ -5494,6 +5494,9 @@ importers: '@pnpm/crypto.base32-hash': specifier: workspace:* version: link:../packages/crypto.base32-hash + '@pnpm/crypto.hash': + specifier: workspace:* + version: link:../crypto/hash '@pnpm/default-reporter': specifier: workspace:* version: link:../cli/default-reporter diff --git a/pnpm/package.json b/pnpm/package.json index 13120ae490..744bf5fd3b 100644 --- a/pnpm/package.json +++ b/pnpm/package.json @@ -32,6 +32,7 @@ "@pnpm/config": "workspace:*", "@pnpm/constants": "workspace:*", "@pnpm/core-loggers": "workspace:*", + "@pnpm/crypto.hash": "workspace:*", "@pnpm/crypto.base32-hash": "workspace:*", "@pnpm/default-reporter": "workspace:*", "@pnpm/dependency-path": "workspace:*", diff --git a/pnpm/test/hooks.ts b/pnpm/test/hooks.ts index bffe8caed5..af0c05386e 100644 --- a/pnpm/test/hooks.ts +++ b/pnpm/test/hooks.ts @@ -1,6 +1,6 @@ import fs from 'fs' import path from 'path' -import { createBase32Hash } from '@pnpm/crypto.base32-hash' +import { createHash } from '@pnpm/crypto.hash' import { type PackageManifest } from '@pnpm/types' import { prepare, preparePackages } from '@pnpm/prepare' import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock' @@ -253,7 +253,7 @@ test('adding or changing pnpmfile should change pnpmfileChecksum and module stru await execPnpm(['install']) const lockfile1 = project.readLockfile() - expect(lockfile1.pnpmfileChecksum).toBe(createBase32Hash(pnpmfile1)) + expect(lockfile1.pnpmfileChecksum).toBe(createHash(pnpmfile1)) expect(lockfile1.packages).toHaveProperty(['@pnpm.e2e/pkg-with-good-optional@1.0.0']) expect(lockfile1.packages).not.toHaveProperty(['is-positive@1.0.0']) // this should be removed due to being optional dependency @@ -274,7 +274,7 @@ test('adding or changing pnpmfile should change pnpmfileChecksum and module stru await execPnpm(['install']) const lockfile2 = project.readLockfile() - expect(lockfile2.pnpmfileChecksum).toBe(createBase32Hash(pnpmfile2)) + expect(lockfile2.pnpmfileChecksum).toBe(createHash(pnpmfile2)) expect(lockfile2.snapshots).toMatchObject({ '@pnpm.e2e/foo@100.0.0': expect.any(Object), '@pnpm.e2e/bar@100.0.0': expect.any(Object), diff --git a/pnpm/tsconfig.json b/pnpm/tsconfig.json index cd1babe03a..ec72c10f7a 100644 --- a/pnpm/tsconfig.json +++ b/pnpm/tsconfig.json @@ -54,6 +54,9 @@ { "path": "../config/plugin-commands-config" }, + { + "path": "../crypto/hash" + }, { "path": "../env/path" },