mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-25 23:17:08 -04:00
refactor: extract some logics from core/install (#8597)
This commit is contained in:
5
.changeset/nervous-baboons-grow.md
Normal file
5
.changeset/nervous-baboons-grow.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/lockfile.settings-checker": major
|
||||
---
|
||||
|
||||
Initial Release
|
||||
13
lockfile/settings-checker/README.md
Normal file
13
lockfile/settings-checker/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# @pnpm/lockfile.settings-checker
|
||||
|
||||
> Utilities to check if lockfile settings are out-of-date.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
pnpm add @pnpm/lockfile.settings-checker
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
3
lockfile/settings-checker/jest.config.js
Normal file
3
lockfile/settings-checker/jest.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
const config = require('../../jest.config.js');
|
||||
|
||||
module.exports = Object.assign({}, config, {});
|
||||
49
lockfile/settings-checker/package.json
Normal file
49
lockfile/settings-checker/package.json
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "@pnpm/lockfile.settings-checker",
|
||||
"version": "0.0.0",
|
||||
"description": "Utilities to check if lockfile settings are out-of-date",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib",
|
||||
"!*.map"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"test": "pnpm run compile",
|
||||
"prepublishOnly": "pnpm run compile",
|
||||
"compile": "tsc --build && pnpm run lint --fix"
|
||||
},
|
||||
"repository": "https://github.com/pnpm/pnpm/blob/main/lockfile/settings-checker",
|
||||
"keywords": [
|
||||
"pnpm9",
|
||||
"hash",
|
||||
"crypto",
|
||||
"base32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18.12"
|
||||
},
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/pnpm/pnpm/issues"
|
||||
},
|
||||
"homepage": "https://github.com/pnpm/pnpm/blob/main/lockfile/settings-checker#readme",
|
||||
"dependencies": {
|
||||
"@pnpm/crypto.base32-hash": "workspace:*",
|
||||
"@pnpm/lockfile.types": "workspace:*",
|
||||
"@pnpm/parse-overrides": "workspace:*",
|
||||
"p-map-values": "catalog:",
|
||||
"ramda": "catalog:",
|
||||
"sort-keys": "catalog:"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pnpm/lockfile.settings-checker": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@types/ramda": "catalog:"
|
||||
},
|
||||
"funding": "https://opencollective.com/pnpm",
|
||||
"exports": {
|
||||
".": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
13
lockfile/settings-checker/src/calcPatchHashes.ts
Normal file
13
lockfile/settings-checker/src/calcPatchHashes.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import path from 'path'
|
||||
import pMapValues from 'p-map-values'
|
||||
import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash'
|
||||
import { type PatchFile } from '@pnpm/lockfile.types'
|
||||
|
||||
export async function calcPatchHashes (patches: Record<string, string>, lockfileDir: string): Promise<Record<string, PatchFile>> {
|
||||
return pMapValues(async (patchFilePath) => {
|
||||
return {
|
||||
hash: await createBase32HashFromFile(patchFilePath),
|
||||
path: path.relative(lockfileDir, patchFilePath).replaceAll('\\', '/'),
|
||||
}
|
||||
}, patches)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { type VersionOverride } from '@pnpm/parse-overrides'
|
||||
|
||||
export function createOverridesMapFromParsed (parsedOverrides: VersionOverride[] | undefined): Record<string, string> {
|
||||
if (!parsedOverrides) return {}
|
||||
const overridesMap: Record<string, string> = {}
|
||||
for (const { selector, newPref } of parsedOverrides) {
|
||||
overridesMap[selector] = newPref
|
||||
}
|
||||
return overridesMap
|
||||
}
|
||||
64
lockfile/settings-checker/src/getOutdatedLockfileSetting.ts
Normal file
64
lockfile/settings-checker/src/getOutdatedLockfileSetting.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { type Lockfile, type PatchFile } from '@pnpm/lockfile.types'
|
||||
import equals from 'ramda/src/equals'
|
||||
|
||||
export type ChangedField =
|
||||
| 'patchedDependencies'
|
||||
| 'overrides'
|
||||
| 'packageExtensionsChecksum'
|
||||
| 'ignoredOptionalDependencies'
|
||||
| 'settings.autoInstallPeers'
|
||||
| 'settings.excludeLinksFromLockfile'
|
||||
| 'settings.peersSuffixMaxLength'
|
||||
| 'pnpmfileChecksum'
|
||||
|
||||
export function getOutdatedLockfileSetting (
|
||||
lockfile: Lockfile,
|
||||
{
|
||||
overrides,
|
||||
packageExtensionsChecksum,
|
||||
ignoredOptionalDependencies,
|
||||
patchedDependencies,
|
||||
autoInstallPeers,
|
||||
excludeLinksFromLockfile,
|
||||
peersSuffixMaxLength,
|
||||
pnpmfileChecksum,
|
||||
}: {
|
||||
overrides?: Record<string, string>
|
||||
packageExtensionsChecksum?: string
|
||||
patchedDependencies?: Record<string, PatchFile>
|
||||
ignoredOptionalDependencies?: string[]
|
||||
autoInstallPeers?: boolean
|
||||
excludeLinksFromLockfile?: boolean
|
||||
peersSuffixMaxLength?: number
|
||||
pnpmfileChecksum?: string
|
||||
}
|
||||
): ChangedField | null {
|
||||
if (!equals(lockfile.overrides ?? {}, overrides ?? {})) {
|
||||
return 'overrides'
|
||||
}
|
||||
if (lockfile.packageExtensionsChecksum !== packageExtensionsChecksum) {
|
||||
return 'packageExtensionsChecksum'
|
||||
}
|
||||
if (!equals(lockfile.ignoredOptionalDependencies?.sort() ?? [], ignoredOptionalDependencies?.sort() ?? [])) {
|
||||
return 'ignoredOptionalDependencies'
|
||||
}
|
||||
if (!equals(lockfile.patchedDependencies ?? {}, patchedDependencies ?? {})) {
|
||||
return 'patchedDependencies'
|
||||
}
|
||||
if ((lockfile.settings?.autoInstallPeers != null && lockfile.settings.autoInstallPeers !== autoInstallPeers)) {
|
||||
return 'settings.autoInstallPeers'
|
||||
}
|
||||
if (lockfile.settings?.excludeLinksFromLockfile != null && lockfile.settings.excludeLinksFromLockfile !== excludeLinksFromLockfile) {
|
||||
return 'settings.excludeLinksFromLockfile'
|
||||
}
|
||||
if (
|
||||
lockfile.settings?.peersSuffixMaxLength != null && lockfile.settings.peersSuffixMaxLength !== peersSuffixMaxLength ||
|
||||
lockfile.settings?.peersSuffixMaxLength == null && peersSuffixMaxLength !== 1000
|
||||
) {
|
||||
return 'settings.peersSuffixMaxLength'
|
||||
}
|
||||
if (lockfile.pnpmfileChecksum !== pnpmfileChecksum) {
|
||||
return 'pnpmfileChecksum'
|
||||
}
|
||||
return null
|
||||
}
|
||||
3
lockfile/settings-checker/src/index.ts
Normal file
3
lockfile/settings-checker/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { calcPatchHashes } from './calcPatchHashes'
|
||||
export { createOverridesMapFromParsed } from './createOverridesMapFromParsed'
|
||||
export { type ChangedField, getOutdatedLockfileSetting } from './getOutdatedLockfileSetting'
|
||||
25
lockfile/settings-checker/tsconfig.json
Normal file
25
lockfile/settings-checker/tsconfig.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"extends": "@pnpm/tsconfig",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"../../__typings__/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../__utils__/prepare"
|
||||
},
|
||||
{
|
||||
"path": "../../config/parse-overrides"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/crypto.base32-hash"
|
||||
},
|
||||
{
|
||||
"path": "../types"
|
||||
}
|
||||
]
|
||||
}
|
||||
8
lockfile/settings-checker/tsconfig.lint.json
Normal file
8
lockfile/settings-checker/tsconfig.lint.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"test/**/*.ts",
|
||||
"../../__typings__/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
"@pnpm/lockfile.fs": "workspace:*",
|
||||
"@pnpm/lockfile.preferred-versions": "workspace:*",
|
||||
"@pnpm/lockfile.pruner": "workspace:*",
|
||||
"@pnpm/lockfile.settings-checker": "workspace:*",
|
||||
"@pnpm/lockfile.utils": "workspace:*",
|
||||
"@pnpm/lockfile.verification": "workspace:*",
|
||||
"@pnpm/lockfile.walker": "workspace:*",
|
||||
@@ -68,7 +69,6 @@
|
||||
"normalize-path": "catalog:",
|
||||
"p-filter": "catalog:",
|
||||
"p-limit": "catalog:",
|
||||
"p-map-values": "catalog:",
|
||||
"path-exists": "catalog:",
|
||||
"ramda": "catalog:",
|
||||
"run-groups": "catalog:",
|
||||
|
||||
@@ -14,7 +14,11 @@ import {
|
||||
stageLogger,
|
||||
summaryLogger,
|
||||
} from '@pnpm/core-loggers'
|
||||
import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash'
|
||||
import {
|
||||
calcPatchHashes,
|
||||
createOverridesMapFromParsed,
|
||||
getOutdatedLockfileSetting,
|
||||
} from '@pnpm/lockfile.settings-checker'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { getContext, type PnpmContext } from '@pnpm/get-context'
|
||||
import { headlessInstall, type InstallationResultStats } from '@pnpm/headless'
|
||||
@@ -71,10 +75,8 @@ import isInnerLink from 'is-inner-link'
|
||||
import isSubdir from 'is-subdir'
|
||||
import pFilter from 'p-filter'
|
||||
import pLimit from 'p-limit'
|
||||
import pMapValues from 'p-map-values'
|
||||
import mapValues from 'ramda/src/map'
|
||||
import clone from 'ramda/src/clone'
|
||||
import equals from 'ramda/src/equals'
|
||||
import isEmpty from 'ramda/src/isEmpty'
|
||||
import pipeWith from 'ramda/src/pipeWith'
|
||||
import props from 'ramda/src/props'
|
||||
@@ -342,7 +344,7 @@ export async function mutateModules (
|
||||
const frozenLockfile = opts.frozenLockfile ||
|
||||
opts.frozenLockfileIfExists && ctx.existsNonEmptyWantedLockfile
|
||||
let outdatedLockfileSettings = false
|
||||
const overridesMap = Object.fromEntries((opts.parsedOverrides ?? []).map(({ selector, newPref }) => [selector, newPref]))
|
||||
const overridesMap = createOverridesMapFromParsed(opts.parsedOverrides)
|
||||
if (!opts.ignorePackageManifest) {
|
||||
const outdatedLockfileSettingName = getOutdatedLockfileSetting(ctx.wantedLockfile, {
|
||||
autoInstallPeers: opts.autoInstallPeers,
|
||||
@@ -742,82 +744,6 @@ Note that in CI environments, this setting is enabled by default.`,
|
||||
}
|
||||
}
|
||||
|
||||
interface PatchHash {
|
||||
hash: string
|
||||
path: string
|
||||
}
|
||||
|
||||
async function calcPatchHashes (patches: Record<string, string>, lockfileDir: string): Promise<Record<string, PatchHash>> {
|
||||
return pMapValues(async (patchFilePath) => {
|
||||
return {
|
||||
hash: await createBase32HashFromFile(patchFilePath),
|
||||
path: path.relative(lockfileDir, patchFilePath).replaceAll('\\', '/'),
|
||||
}
|
||||
}, patches)
|
||||
}
|
||||
|
||||
type ChangedField =
|
||||
| 'patchedDependencies'
|
||||
| 'overrides'
|
||||
| 'packageExtensionsChecksum'
|
||||
| 'ignoredOptionalDependencies'
|
||||
| 'settings.autoInstallPeers'
|
||||
| 'settings.excludeLinksFromLockfile'
|
||||
| 'settings.peersSuffixMaxLength'
|
||||
| 'pnpmfileChecksum'
|
||||
|
||||
function getOutdatedLockfileSetting (
|
||||
lockfile: Lockfile,
|
||||
{
|
||||
overrides,
|
||||
packageExtensionsChecksum,
|
||||
ignoredOptionalDependencies,
|
||||
patchedDependencies,
|
||||
autoInstallPeers,
|
||||
excludeLinksFromLockfile,
|
||||
peersSuffixMaxLength,
|
||||
pnpmfileChecksum,
|
||||
}: {
|
||||
overrides?: Record<string, string>
|
||||
packageExtensionsChecksum?: string
|
||||
patchedDependencies?: Record<string, PatchFile>
|
||||
ignoredOptionalDependencies?: string[]
|
||||
autoInstallPeers?: boolean
|
||||
excludeLinksFromLockfile?: boolean
|
||||
peersSuffixMaxLength?: number
|
||||
pnpmfileChecksum?: string
|
||||
}
|
||||
): ChangedField | null {
|
||||
if (!equals(lockfile.overrides ?? {}, overrides ?? {})) {
|
||||
return 'overrides'
|
||||
}
|
||||
if (lockfile.packageExtensionsChecksum !== packageExtensionsChecksum) {
|
||||
return 'packageExtensionsChecksum'
|
||||
}
|
||||
if (!equals(lockfile.ignoredOptionalDependencies?.sort() ?? [], ignoredOptionalDependencies?.sort() ?? [])) {
|
||||
return 'ignoredOptionalDependencies'
|
||||
}
|
||||
if (!equals(lockfile.patchedDependencies ?? {}, patchedDependencies ?? {})) {
|
||||
return 'patchedDependencies'
|
||||
}
|
||||
if ((lockfile.settings?.autoInstallPeers != null && lockfile.settings.autoInstallPeers !== autoInstallPeers)) {
|
||||
return 'settings.autoInstallPeers'
|
||||
}
|
||||
if (lockfile.settings?.excludeLinksFromLockfile != null && lockfile.settings.excludeLinksFromLockfile !== excludeLinksFromLockfile) {
|
||||
return 'settings.excludeLinksFromLockfile'
|
||||
}
|
||||
if (
|
||||
lockfile.settings?.peersSuffixMaxLength != null && lockfile.settings.peersSuffixMaxLength !== peersSuffixMaxLength ||
|
||||
lockfile.settings?.peersSuffixMaxLength == null && peersSuffixMaxLength !== 1000
|
||||
) {
|
||||
return 'settings.peersSuffixMaxLength'
|
||||
}
|
||||
if (lockfile.pnpmfileChecksum !== pnpmfileChecksum) {
|
||||
return 'pnpmfileChecksum'
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function createObjectChecksum (obj: Record<string, unknown>): string {
|
||||
const s = JSON.stringify(sortKeys(obj, { deep: true }))
|
||||
return crypto.createHash('md5').update(s).digest('hex')
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
{
|
||||
"path": "../../lockfile/pruner"
|
||||
},
|
||||
{
|
||||
"path": "../../lockfile/settings-checker"
|
||||
},
|
||||
{
|
||||
"path": "../../lockfile/types"
|
||||
},
|
||||
|
||||
37
pnpm-lock.yaml
generated
37
pnpm-lock.yaml
generated
@@ -3240,6 +3240,37 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 1.1.0
|
||||
|
||||
lockfile/settings-checker:
|
||||
dependencies:
|
||||
'@pnpm/crypto.base32-hash':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/crypto.base32-hash
|
||||
'@pnpm/lockfile.types':
|
||||
specifier: workspace:*
|
||||
version: link:../types
|
||||
'@pnpm/parse-overrides':
|
||||
specifier: workspace:*
|
||||
version: link:../../config/parse-overrides
|
||||
p-map-values:
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.0
|
||||
ramda:
|
||||
specifier: 'catalog:'
|
||||
version: '@pnpm/ramda@0.28.1'
|
||||
sort-keys:
|
||||
specifier: 'catalog:'
|
||||
version: 4.2.0
|
||||
devDependencies:
|
||||
'@pnpm/lockfile.settings-checker':
|
||||
specifier: workspace:*
|
||||
version: 'link:'
|
||||
'@pnpm/prepare':
|
||||
specifier: workspace:*
|
||||
version: link:../../__utils__/prepare
|
||||
'@types/ramda':
|
||||
specifier: 'catalog:'
|
||||
version: 0.29.12
|
||||
|
||||
lockfile/types:
|
||||
dependencies:
|
||||
'@pnpm/patching.types':
|
||||
@@ -4076,6 +4107,9 @@ importers:
|
||||
'@pnpm/lockfile.pruner':
|
||||
specifier: workspace:*
|
||||
version: link:../../lockfile/pruner
|
||||
'@pnpm/lockfile.settings-checker':
|
||||
specifier: workspace:*
|
||||
version: link:../../lockfile/settings-checker
|
||||
'@pnpm/lockfile.utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../lockfile/utils
|
||||
@@ -4166,9 +4200,6 @@ importers:
|
||||
p-limit:
|
||||
specifier: 'catalog:'
|
||||
version: 3.1.0
|
||||
p-map-values:
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.0
|
||||
path-exists:
|
||||
specifier: 'catalog:'
|
||||
version: 4.0.0
|
||||
|
||||
Reference in New Issue
Block a user