mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-12 10:11:42 -04:00
23
.changeset/bright-lemons-arrive.md
Normal file
23
.changeset/bright-lemons-arrive.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/core": minor
|
||||||
|
"@pnpm/headless": minor
|
||||||
|
"@pnpm/types": minor
|
||||||
|
"pnpm": minor
|
||||||
|
"@pnpm/resolve-dependencies": minor
|
||||||
|
"@pnpm/lockfile-types": minor
|
||||||
|
"@pnpm/lifecycle": minor
|
||||||
|
"@pnpm/plugin-commands-installation": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Dependencies patching is possible via the `pnpm.patchedDependencies` field of the `package.json`.
|
||||||
|
To patch a package, the package name, exact version, and the relative path to the patch file should be specified. For instance:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pnpm": {
|
||||||
|
"patchedDependencies": {
|
||||||
|
"eslint@1.0.0": "./patches/eslint@1.0.0.patch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
5
.changeset/four-poems-leave.md
Normal file
5
.changeset/four-poems-leave.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/calc-dep-state": major
|
||||||
|
---
|
||||||
|
|
||||||
|
Changed the order of arguments in calcDepState and added an optional last argument for patchFileHash.
|
||||||
9
.changeset/shiny-countries-behave.md
Normal file
9
.changeset/shiny-countries-behave.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/create-cafs-store": major
|
||||||
|
"@pnpm/fetcher-base": major
|
||||||
|
"@pnpm/package-store": major
|
||||||
|
"@pnpm/server": major
|
||||||
|
"@pnpm/store-controller-types": major
|
||||||
|
---
|
||||||
|
|
||||||
|
Rename engine and targetEngine fields to sideEffectsCacheKey.
|
||||||
5
.changeset/tasty-cobras-reflect.md
Normal file
5
.changeset/tasty-cobras-reflect.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@pnpm/build-modules": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Support packages patching.
|
||||||
@@ -16,6 +16,10 @@ export interface DependenciesGraphNode {
|
|||||||
optionalDependencies: Set<string>
|
optionalDependencies: Set<string>
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
requiresBuild?: boolean | any // this is a durty workaround added in https://github.com/pnpm/pnpm/pull/4898
|
requiresBuild?: boolean | any // this is a durty workaround added in https://github.com/pnpm/pnpm/pull/4898
|
||||||
|
patchFile?: {
|
||||||
|
hash: string
|
||||||
|
path: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DependenciesGraph {
|
export interface DependenciesGraph {
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ async function buildDependency (
|
|||||||
extraEnv: opts.extraEnv,
|
extraEnv: opts.extraEnv,
|
||||||
initCwd: opts.lockfileDir,
|
initCwd: opts.lockfileDir,
|
||||||
optional: depNode.optional,
|
optional: depNode.optional,
|
||||||
|
patchPath: depNode.patchFile?.path,
|
||||||
pkgRoot: depNode.dir,
|
pkgRoot: depNode.dir,
|
||||||
rawConfig: opts.rawConfig,
|
rawConfig: opts.rawConfig,
|
||||||
rootModulesDir: opts.rootModulesDir,
|
rootModulesDir: opts.rootModulesDir,
|
||||||
@@ -93,8 +94,9 @@ async function buildDependency (
|
|||||||
})
|
})
|
||||||
if (hasSideEffects && opts.sideEffectsCacheWrite) {
|
if (hasSideEffects && opts.sideEffectsCacheWrite) {
|
||||||
try {
|
try {
|
||||||
|
const sideEffectsCacheKey = calcDepState(depGraph, opts.depsStateCache, depPath, depNode.patchFile?.hash)
|
||||||
await opts.storeController.upload(depNode.dir, {
|
await opts.storeController.upload(depNode.dir, {
|
||||||
engine: calcDepState(depPath, depGraph, opts.depsStateCache),
|
sideEffectsCacheKey,
|
||||||
filesIndexFile: depNode.filesIndexFile,
|
filesIndexFile: depNode.filesIndexFile,
|
||||||
})
|
})
|
||||||
} catch (err: any) { // eslint-disable-line
|
} catch (err: any) { // eslint-disable-line
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export interface DepsGraphNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DepsStateCache {
|
export interface DepsStateCache {
|
||||||
[nodeId: string]: DepStateObj
|
[depPath: string]: DepStateObj
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DepStateObj {
|
export interface DepStateObj {
|
||||||
@@ -19,22 +19,27 @@ export interface DepStateObj {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function calcDepState (
|
export function calcDepState (
|
||||||
nodeId: string,
|
|
||||||
depsGraph: DepsGraph,
|
depsGraph: DepsGraph,
|
||||||
cache: DepsStateCache
|
cache: DepsStateCache,
|
||||||
|
depPath: string,
|
||||||
|
patchFileHash?: string
|
||||||
): string {
|
): string {
|
||||||
const depStateObj = calcDepStateObj(nodeId, depsGraph, cache, new Set())
|
const depStateObj = calcDepStateObj(depPath, depsGraph, cache, new Set())
|
||||||
return `${ENGINE_NAME}-${JSON.stringify(depStateObj)}`
|
let result = `${ENGINE_NAME}-${JSON.stringify(depStateObj)}`
|
||||||
|
if (patchFileHash) {
|
||||||
|
result += `-${patchFileHash}`
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcDepStateObj (
|
function calcDepStateObj (
|
||||||
nodeId: string,
|
depPath: string,
|
||||||
depsGraph: DepsGraph,
|
depsGraph: DepsGraph,
|
||||||
cache: DepsStateCache,
|
cache: DepsStateCache,
|
||||||
parents: Set<string>
|
parents: Set<string>
|
||||||
): DepStateObj {
|
): DepStateObj {
|
||||||
if (cache[nodeId]) return cache[nodeId]
|
if (cache[depPath]) return cache[depPath]
|
||||||
const node = depsGraph[nodeId]
|
const node = depsGraph[depPath]
|
||||||
if (!node) return {}
|
if (!node) return {}
|
||||||
const nextParents = new Set([...Array.from(parents), node.depPath])
|
const nextParents = new Set([...Array.from(parents), node.depPath])
|
||||||
const state: DepStateObj = {}
|
const state: DepStateObj = {}
|
||||||
@@ -47,6 +52,6 @@ function calcDepStateObj (
|
|||||||
}
|
}
|
||||||
state[child.depPath] = calcDepStateObj(childId, depsGraph, cache, nextParents)
|
state[child.depPath] = calcDepStateObj(childId, depsGraph, cache, nextParents)
|
||||||
}
|
}
|
||||||
cache[nodeId] = sortKeys(state)
|
cache[depPath] = sortKeys(state)
|
||||||
return cache[nodeId]
|
return cache[depPath]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { calcDepState } from '@pnpm/calc-dep-state'
|
|||||||
import { ENGINE_NAME } from '@pnpm/constants'
|
import { ENGINE_NAME } from '@pnpm/constants'
|
||||||
|
|
||||||
test('calcDepState()', () => {
|
test('calcDepState()', () => {
|
||||||
expect(calcDepState('/registry/foo/1.0.0', {
|
expect(calcDepState({
|
||||||
'registry/foo/1.0.0': {
|
'registry/foo/1.0.0': {
|
||||||
depPath: '/foo/1.0.0',
|
depPath: '/foo/1.0.0',
|
||||||
children: {
|
children: {
|
||||||
@@ -15,5 +15,5 @@ test('calcDepState()', () => {
|
|||||||
foo: 'registry/foo/1.0.0',
|
foo: 'registry/foo/1.0.0',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {})).toBe(`${ENGINE_NAME}-{}`)
|
}, {}, '/registry/foo/1.0.0')).toBe(`${ENGINE_NAME}-{}`)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export interface StrictInstallOptions {
|
|||||||
|
|
||||||
global: boolean
|
global: boolean
|
||||||
globalBin?: string
|
globalBin?: string
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type InstallOptions =
|
export type InstallOptions =
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ export async function mutateModules (
|
|||||||
neverBuiltDependencies: opts.neverBuiltDependencies,
|
neverBuiltDependencies: opts.neverBuiltDependencies,
|
||||||
onlyBuiltDependencies: opts.onlyBuiltDependencies,
|
onlyBuiltDependencies: opts.onlyBuiltDependencies,
|
||||||
packageExtensionsChecksum,
|
packageExtensionsChecksum,
|
||||||
|
patchedDependencies: opts.patchedDependencies,
|
||||||
}) ||
|
}) ||
|
||||||
opts.fixLockfile
|
opts.fixLockfile
|
||||||
if (needsFullResolution) {
|
if (needsFullResolution) {
|
||||||
@@ -247,6 +248,7 @@ export async function mutateModules (
|
|||||||
ctx.wantedLockfile.neverBuiltDependencies = opts.neverBuiltDependencies
|
ctx.wantedLockfile.neverBuiltDependencies = opts.neverBuiltDependencies
|
||||||
ctx.wantedLockfile.onlyBuiltDependencies = opts.onlyBuiltDependencies
|
ctx.wantedLockfile.onlyBuiltDependencies = opts.onlyBuiltDependencies
|
||||||
ctx.wantedLockfile.packageExtensionsChecksum = packageExtensionsChecksum
|
ctx.wantedLockfile.packageExtensionsChecksum = packageExtensionsChecksum
|
||||||
|
ctx.wantedLockfile.patchedDependencies = opts.patchedDependencies
|
||||||
}
|
}
|
||||||
const frozenLockfile = opts.frozenLockfile ||
|
const frozenLockfile = opts.frozenLockfile ||
|
||||||
opts.frozenLockfileIfExists && ctx.existsWantedLockfile
|
opts.frozenLockfileIfExists && ctx.existsWantedLockfile
|
||||||
@@ -490,16 +492,19 @@ function lockfileIsUpToDate (
|
|||||||
onlyBuiltDependencies,
|
onlyBuiltDependencies,
|
||||||
overrides,
|
overrides,
|
||||||
packageExtensionsChecksum,
|
packageExtensionsChecksum,
|
||||||
|
patchedDependencies,
|
||||||
}: {
|
}: {
|
||||||
neverBuiltDependencies?: string[]
|
neverBuiltDependencies?: string[]
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
packageExtensionsChecksum?: string
|
packageExtensionsChecksum?: string
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
}) {
|
}) {
|
||||||
return !equals(lockfile.overrides ?? {}, overrides ?? {}) ||
|
return !equals(lockfile.overrides ?? {}, overrides ?? {}) ||
|
||||||
!equals((lockfile.neverBuiltDependencies ?? []).sort(), (neverBuiltDependencies ?? []).sort()) ||
|
!equals((lockfile.neverBuiltDependencies ?? []).sort(), (neverBuiltDependencies ?? []).sort()) ||
|
||||||
!equals(onlyBuiltDependencies?.sort(), lockfile.onlyBuiltDependencies) ||
|
!equals(onlyBuiltDependencies?.sort(), lockfile.onlyBuiltDependencies) ||
|
||||||
lockfile.packageExtensionsChecksum !== packageExtensionsChecksum
|
lockfile.packageExtensionsChecksum !== packageExtensionsChecksum ||
|
||||||
|
!equals(lockfile.patchedDependencies ?? {}, patchedDependencies ?? {})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createObjectChecksum (obj: Object) {
|
export function createObjectChecksum (obj: Object) {
|
||||||
@@ -773,6 +778,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
|||||||
virtualStoreDir: ctx.virtualStoreDir,
|
virtualStoreDir: ctx.virtualStoreDir,
|
||||||
wantedLockfile: ctx.wantedLockfile,
|
wantedLockfile: ctx.wantedLockfile,
|
||||||
workspacePackages: opts.workspacePackages,
|
workspacePackages: opts.workspacePackages,
|
||||||
|
patchedDependencies: opts.patchedDependencies,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -404,9 +404,9 @@ async function linkAllPkgs (
|
|||||||
depNodes.map(async (depNode) => {
|
depNodes.map(async (depNode) => {
|
||||||
const filesResponse = await depNode.fetchingFiles()
|
const filesResponse = await depNode.fetchingFiles()
|
||||||
|
|
||||||
let targetEngine: string | undefined
|
let sideEffectsCacheKey: string | undefined
|
||||||
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
||||||
targetEngine = calcDepState(depNode.depPath, opts.depGraph, opts.depsStateCache)
|
sideEffectsCacheKey = calcDepState(opts.depGraph, opts.depsStateCache, depNode.depPath, depNode.patchFile?.hash)
|
||||||
}
|
}
|
||||||
if (typeof depNode.requiresBuild === 'function') {
|
if (typeof depNode.requiresBuild === 'function') {
|
||||||
depNode.requiresBuild = await depNode.requiresBuild()
|
depNode.requiresBuild = await depNode.requiresBuild()
|
||||||
@@ -414,7 +414,7 @@ async function linkAllPkgs (
|
|||||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||||
filesResponse,
|
filesResponse,
|
||||||
force: opts.force,
|
force: opts.force,
|
||||||
targetEngine,
|
sideEffectsCacheKey,
|
||||||
requiresBuild: depNode.requiresBuild,
|
requiresBuild: depNode.requiresBuild,
|
||||||
})
|
})
|
||||||
if (importMethod) {
|
if (importMethod) {
|
||||||
|
|||||||
12
packages/core/test/fixtures/patch-pkg/is-positive@1.0.0.patch
vendored
Normal file
12
packages/core/test/fixtures/patch-pkg/is-positive@1.0.0.patch
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
diff --git a/index.js b/index.js
|
||||||
|
index 8e020ca..ff3aee4 100644
|
||||||
|
--- a/index.js
|
||||||
|
+++ b/index.js
|
||||||
|
@@ -5,5 +5,6 @@ module.exports = function (n) {
|
||||||
|
throw new TypeError('Expected a number');
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // patched
|
||||||
|
return n >= 0;
|
||||||
|
};
|
||||||
|
|
||||||
90
packages/core/test/install/patch.ts
Normal file
90
packages/core/test/install/patch.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { PackageFilesIndex } from '@pnpm/cafs'
|
||||||
|
import { ENGINE_NAME } from '@pnpm/constants'
|
||||||
|
import { install } from '@pnpm/core'
|
||||||
|
import { prepareEmpty } from '@pnpm/prepare'
|
||||||
|
import fixtures from '@pnpm/test-fixtures'
|
||||||
|
import rimraf from '@zkochan/rimraf'
|
||||||
|
import loadJsonFile from 'load-json-file'
|
||||||
|
import { testDefaults } from '../utils'
|
||||||
|
|
||||||
|
const f = fixtures(__dirname)
|
||||||
|
|
||||||
|
test('patch package', async () => {
|
||||||
|
const project = prepareEmpty()
|
||||||
|
const patchPath = path.join(f.find('patch-pkg'), 'is-positive@1.0.0.patch')
|
||||||
|
|
||||||
|
const patchedDependencies = {
|
||||||
|
'is-positive@1.0.0': path.relative(process.cwd(), patchPath),
|
||||||
|
}
|
||||||
|
const opts = await testDefaults({
|
||||||
|
fastUnpack: false,
|
||||||
|
sideEffectsCacheRead: true,
|
||||||
|
sideEffectsCacheWrite: true,
|
||||||
|
patchedDependencies,
|
||||||
|
}, {}, {}, { packageImportMethod: 'hardlink' })
|
||||||
|
await install({
|
||||||
|
dependencies: {
|
||||||
|
'is-positive': '1.0.0',
|
||||||
|
},
|
||||||
|
}, opts)
|
||||||
|
|
||||||
|
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).toContain('// patched')
|
||||||
|
|
||||||
|
const lockfile = await project.readLockfile()
|
||||||
|
expect(lockfile.patchedDependencies).toStrictEqual(patchedDependencies)
|
||||||
|
|
||||||
|
const filesIndexFile = path.join(opts.storeDir, 'files/c7/1ccf199e0fdae37aad13946b937d67bcd35fa111b84d21b3a19439cfdc2812c5d8da8a735e94c2a1ccb77b4583808ee8405313951e7146ac83ede3671dc292-index.json')
|
||||||
|
const filesIndex = await loadJsonFile<PackageFilesIndex>(filesIndexFile)
|
||||||
|
const sideEffectsKey = `${ENGINE_NAME}-{}-meyqmf5tej4bwn3gxydpfig6pe`
|
||||||
|
const patchedFileIntegrity = filesIndex.sideEffects?.[sideEffectsKey]['index.js']?.integrity
|
||||||
|
expect(patchedFileIntegrity).toBeTruthy()
|
||||||
|
const originalFileIntegrity = filesIndex.files['index.js'].integrity
|
||||||
|
expect(originalFileIntegrity).toBeTruthy()
|
||||||
|
// The integrity of the original file differs from the integrity of the patched file
|
||||||
|
expect(originalFileIntegrity).not.toEqual(patchedFileIntegrity)
|
||||||
|
|
||||||
|
// The same with frozen lockfile
|
||||||
|
await rimraf('node_modules')
|
||||||
|
await install({
|
||||||
|
dependencies: {
|
||||||
|
'is-positive': '1.0.0',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
...opts,
|
||||||
|
frozenLockfile: true,
|
||||||
|
})
|
||||||
|
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).toContain('// patched')
|
||||||
|
|
||||||
|
// The same with frozen lockfile and hoisted node_modules
|
||||||
|
await rimraf('node_modules')
|
||||||
|
await install({
|
||||||
|
dependencies: {
|
||||||
|
'is-positive': '1.0.0',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
...opts,
|
||||||
|
frozenLockfile: true,
|
||||||
|
nodeLinker: 'hoisted',
|
||||||
|
})
|
||||||
|
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).toContain('// patched')
|
||||||
|
|
||||||
|
process.chdir('..')
|
||||||
|
fs.mkdirSync('project2')
|
||||||
|
process.chdir('project2')
|
||||||
|
|
||||||
|
await install({
|
||||||
|
dependencies: {
|
||||||
|
'is-positive': '1.0.0',
|
||||||
|
},
|
||||||
|
}, await testDefaults({
|
||||||
|
fastUnpack: false,
|
||||||
|
sideEffectsCacheRead: true,
|
||||||
|
sideEffectsCacheWrite: true,
|
||||||
|
offline: true,
|
||||||
|
}, {}, {}, { packageImportMethod: 'hardlink' }))
|
||||||
|
|
||||||
|
// The original file did not break, when a patched version was created
|
||||||
|
expect(fs.readFileSync('node_modules/is-positive/index.js', 'utf8')).not.toContain('// patched')
|
||||||
|
})
|
||||||
@@ -22,7 +22,7 @@ function createPackageImporter (
|
|||||||
const packageImportMethod = opts.packageImportMethod
|
const packageImportMethod = opts.packageImportMethod
|
||||||
const gfm = getFlatMap.bind(null, opts.cafsDir)
|
const gfm = getFlatMap.bind(null, opts.cafsDir)
|
||||||
return async (to, opts) => {
|
return async (to, opts) => {
|
||||||
const { filesMap, isBuilt } = gfm(opts.filesResponse, opts.targetEngine)
|
const { filesMap, isBuilt } = gfm(opts.filesResponse, opts.sideEffectsCacheKey)
|
||||||
const pkgImportMethod = (opts.requiresBuild && !isBuilt)
|
const pkgImportMethod = (opts.requiresBuild && !isBuilt)
|
||||||
? 'clone-or-copy'
|
? 'clone-or-copy'
|
||||||
: (opts.filesResponse.packageImportMethod ?? packageImportMethod)
|
: (opts.filesResponse.packageImportMethod ?? packageImportMethod)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export type PackageFilesResponse = {
|
|||||||
|
|
||||||
export interface ImportPackageOpts {
|
export interface ImportPackageOpts {
|
||||||
requiresBuild?: boolean
|
requiresBuild?: boolean
|
||||||
targetEngine?: string
|
sideEffectsCacheKey?: string
|
||||||
filesResponse: PackageFilesResponse
|
filesResponse: PackageFilesResponse
|
||||||
force: boolean
|
force: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@
|
|||||||
"@pnpm/calc-dep-state": "workspace:2.0.1",
|
"@pnpm/calc-dep-state": "workspace:2.0.1",
|
||||||
"@pnpm/constants": "workspace:6.1.0",
|
"@pnpm/constants": "workspace:6.1.0",
|
||||||
"@pnpm/core-loggers": "workspace:7.0.3",
|
"@pnpm/core-loggers": "workspace:7.0.3",
|
||||||
|
"@pnpm/crypto.base32-hash": "workspace:1.0.0",
|
||||||
"@pnpm/error": "workspace:3.0.1",
|
"@pnpm/error": "workspace:3.0.1",
|
||||||
"@pnpm/filter-lockfile": "workspace:6.0.6",
|
"@pnpm/filter-lockfile": "workspace:6.0.6",
|
||||||
"@pnpm/hoist": "workspace:6.1.4",
|
"@pnpm/hoist": "workspace:6.1.4",
|
||||||
|
|||||||
@@ -679,15 +679,15 @@ async function linkAllPkgs (
|
|||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetEngine: string | undefined
|
let sideEffectsCacheKey: string | undefined
|
||||||
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
||||||
targetEngine = calcDepState(depNode.dir, opts.depGraph, opts.depsStateCache)
|
sideEffectsCacheKey = calcDepState(opts.depGraph, opts.depsStateCache, depNode.dir, depNode.patchFile?.hash)
|
||||||
}
|
}
|
||||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||||
filesResponse,
|
filesResponse,
|
||||||
force: opts.force,
|
force: opts.force,
|
||||||
requiresBuild: depNode.requiresBuild,
|
requiresBuild: depNode.requiresBuild,
|
||||||
targetEngine,
|
sideEffectsCacheKey,
|
||||||
})
|
})
|
||||||
if (importMethod) {
|
if (importMethod) {
|
||||||
progressLogger.debug({
|
progressLogger.debug({
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ async function linkAllPkgsInOrder (
|
|||||||
warn: (message: string) => void
|
warn: (message: string) => void
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
const _calcDepState = calcDepState.bind(null, graph, opts.depsStateCache)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.entries(hierarchy).map(async ([dir, deps]) => {
|
Object.entries(hierarchy).map(async ([dir, deps]) => {
|
||||||
const depNode = graph[dir]
|
const depNode = graph[dir]
|
||||||
@@ -98,15 +99,15 @@ async function linkAllPkgsInOrder (
|
|||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetEngine: string | undefined
|
let sideEffectsCacheKey: string | undefined
|
||||||
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) {
|
||||||
targetEngine = calcDepState(dir, graph, opts.depsStateCache)
|
sideEffectsCacheKey = _calcDepState(dir, depNode.patchFile?.hash)
|
||||||
}
|
}
|
||||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||||
filesResponse,
|
filesResponse,
|
||||||
force: opts.force || depNode.depPath !== prevGraph[dir]?.depPath,
|
force: opts.force || depNode.depPath !== prevGraph[dir]?.depPath,
|
||||||
requiresBuild: depNode.requiresBuild,
|
requiresBuild: depNode.requiresBuild,
|
||||||
targetEngine,
|
sideEffectsCacheKey,
|
||||||
})
|
})
|
||||||
if (importMethod) {
|
if (importMethod) {
|
||||||
progressLogger.debug({
|
progressLogger.debug({
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { WANTED_LOCKFILE } from '@pnpm/constants'
|
|||||||
import {
|
import {
|
||||||
progressLogger,
|
progressLogger,
|
||||||
} from '@pnpm/core-loggers'
|
} from '@pnpm/core-loggers'
|
||||||
|
import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash'
|
||||||
import {
|
import {
|
||||||
Lockfile,
|
Lockfile,
|
||||||
PackageSnapshot,
|
PackageSnapshot,
|
||||||
@@ -44,6 +45,10 @@ export interface DependenciesGraphNode {
|
|||||||
prepare: boolean
|
prepare: boolean
|
||||||
hasBin: boolean
|
hasBin: boolean
|
||||||
filesIndexFile: string
|
filesIndexFile: string
|
||||||
|
patchFile?: {
|
||||||
|
path: string
|
||||||
|
hash: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DependenciesGraph {
|
export interface DependenciesGraph {
|
||||||
@@ -175,6 +180,7 @@ export default async function lockfileToDepGraph (
|
|||||||
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
|
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
|
||||||
prepare: pkgSnapshot.prepare === true,
|
prepare: pkgSnapshot.prepare === true,
|
||||||
requiresBuild: pkgSnapshot.requiresBuild === true,
|
requiresBuild: pkgSnapshot.requiresBuild === true,
|
||||||
|
patchFile: await tryReadPatchFile(opts.lockfileDir, lockfile, pkgName, pkgVersion),
|
||||||
}
|
}
|
||||||
pkgSnapshotByLocation[dir] = pkgSnapshot
|
pkgSnapshotByLocation[dir] = pkgSnapshot
|
||||||
})
|
})
|
||||||
@@ -214,6 +220,18 @@ export default async function lockfileToDepGraph (
|
|||||||
return { graph, directDependenciesByImporterId }
|
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 (
|
async function getChildrenPaths (
|
||||||
ctx: {
|
ctx: {
|
||||||
graph: DependenciesGraph
|
graph: DependenciesGraph
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
DepHierarchy,
|
DepHierarchy,
|
||||||
DirectDependenciesByImporterId,
|
DirectDependenciesByImporterId,
|
||||||
LockfileToDepGraphResult,
|
LockfileToDepGraphResult,
|
||||||
|
tryReadPatchFile,
|
||||||
} from './lockfileToDepGraph'
|
} from './lockfileToDepGraph'
|
||||||
|
|
||||||
export interface LockfileToHoistedDepGraphOptions {
|
export interface LockfileToHoistedDepGraphOptions {
|
||||||
@@ -208,6 +209,7 @@ async function fetchDeps (
|
|||||||
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
|
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
|
||||||
prepare: pkgSnapshot.prepare === true,
|
prepare: pkgSnapshot.prepare === true,
|
||||||
requiresBuild: pkgSnapshot.requiresBuild === true,
|
requiresBuild: pkgSnapshot.requiresBuild === true,
|
||||||
|
patchFile: await tryReadPatchFile(opts.lockfileDir, opts.lockfile, pkgName, pkgVersion),
|
||||||
}
|
}
|
||||||
opts.pkgLocationByDepPath[depPath] = dir
|
opts.pkgLocationByDepPath[depPath] = dir
|
||||||
depHierarchy[dir] = await fetchDeps(opts, path.join(dir, 'node_modules'), dep.dependencies)
|
depHierarchy[dir] = await fetchDeps(opts, path.join(dir, 'node_modules'), dep.dependencies)
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
{
|
{
|
||||||
"path": "../core-loggers"
|
"path": "../core-loggers"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../crypto.base32-hash"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../dependency-path"
|
"path": "../dependency-path"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ export async function runPostinstallHooks (
|
|||||||
if (pkg.scripts == null) {
|
if (pkg.scripts == null) {
|
||||||
pkg.scripts = {}
|
pkg.scripts = {}
|
||||||
}
|
}
|
||||||
|
if (opts.patchPath) {
|
||||||
|
pkg.scripts['pnpm:patch'] = `git apply ${opts.patchPath}`
|
||||||
|
await runLifecycleHook('pnpm:patch', pkg, opts)
|
||||||
|
}
|
||||||
|
|
||||||
if (!pkg.scripts.install) {
|
if (!pkg.scripts.install) {
|
||||||
await checkBindingGyp(opts.pkgRoot, pkg.scripts)
|
await checkBindingGyp(opts.pkgRoot, pkg.scripts)
|
||||||
@@ -42,7 +46,8 @@ export async function runPostinstallHooks (
|
|||||||
|
|
||||||
return pkg.scripts.preinstall != null ||
|
return pkg.scripts.preinstall != null ||
|
||||||
pkg.scripts.install != null ||
|
pkg.scripts.install != null ||
|
||||||
pkg.scripts.postinstall != null
|
pkg.scripts.postinstall != null ||
|
||||||
|
Boolean(opts.patchPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export interface RunLifecycleHookOptions {
|
|||||||
extraEnv?: Record<string, string>
|
extraEnv?: Record<string, string>
|
||||||
initCwd?: string
|
initCwd?: string
|
||||||
optional?: boolean
|
optional?: boolean
|
||||||
|
patchPath?: string
|
||||||
pkgRoot: string
|
pkgRoot: string
|
||||||
rawConfig: object
|
rawConfig: object
|
||||||
rootModulesDir: string
|
rootModulesDir: string
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export interface Lockfile {
|
|||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
overrides?: Record<string, string>
|
overrides?: Record<string, string>
|
||||||
packageExtensionsChecksum?: string
|
packageExtensionsChecksum?: string
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProjectSnapshot {
|
export interface ProjectSnapshot {
|
||||||
|
|||||||
@@ -53,23 +53,23 @@ export default async function (
|
|||||||
upload,
|
upload,
|
||||||
}
|
}
|
||||||
|
|
||||||
async function upload (builtPkgLocation: string, opts: {filesIndexFile: string, engine: string}) {
|
async function upload (builtPkgLocation: string, opts: {filesIndexFile: string, sideEffectsCacheKey: string}) {
|
||||||
const sideEffectsIndex = await cafs.addFilesFromDir(builtPkgLocation)
|
const sideEffectsIndex = await cafs.addFilesFromDir(builtPkgLocation)
|
||||||
// TODO: move this to a function
|
// TODO: move this to a function
|
||||||
// This is duplicated in @pnpm/package-requester
|
// This is duplicated in @pnpm/package-requester
|
||||||
const integrity: Record<string, PackageFileInfo> = {}
|
const integrity: Record<string, PackageFileInfo> = {}
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
Object.keys(sideEffectsIndex)
|
Object.entries(sideEffectsIndex)
|
||||||
.map(async (filename) => {
|
.map(async ([filename, { writeResult, mode, size }]) => {
|
||||||
const {
|
const {
|
||||||
checkedAt,
|
checkedAt,
|
||||||
integrity: fileIntegrity,
|
integrity: fileIntegrity,
|
||||||
} = await sideEffectsIndex[filename].writeResult
|
} = await writeResult
|
||||||
integrity[filename] = {
|
integrity[filename] = {
|
||||||
checkedAt,
|
checkedAt,
|
||||||
integrity: fileIntegrity.toString(), // TODO: use the raw Integrity object
|
integrity: fileIntegrity.toString(), // TODO: use the raw Integrity object
|
||||||
mode: sideEffectsIndex[filename].mode,
|
mode,
|
||||||
size: sideEffectsIndex[filename].size,
|
size,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -80,7 +80,7 @@ export default async function (
|
|||||||
filesIndex = { files: integrity }
|
filesIndex = { files: integrity }
|
||||||
}
|
}
|
||||||
filesIndex.sideEffects = filesIndex.sideEffects ?? {}
|
filesIndex.sideEffects = filesIndex.sideEffects ?? {}
|
||||||
filesIndex.sideEffects[opts.engine] = integrity
|
filesIndex.sideEffects[opts.sideEffectsCacheKey] = integrity
|
||||||
await writeJsonFile(opts.filesIndexFile, filesIndex, { indent: undefined })
|
await writeJsonFile(opts.filesIndexFile, filesIndex, { indent: undefined })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export default function getOptionsFromRootManifest (manifest: ProjectManifest):
|
|||||||
neverBuiltDependencies?: string[]
|
neverBuiltDependencies?: string[]
|
||||||
onlyBuiltDependencies?: string[]
|
onlyBuiltDependencies?: string[]
|
||||||
packageExtensions?: Record<string, PackageExtension>
|
packageExtensions?: Record<string, PackageExtension>
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
peerDependencyRules?: PeerDependencyRules
|
peerDependencyRules?: PeerDependencyRules
|
||||||
} {
|
} {
|
||||||
// We read Yarn's resolutions field for compatibility
|
// We read Yarn's resolutions field for compatibility
|
||||||
@@ -22,6 +23,7 @@ export default function getOptionsFromRootManifest (manifest: ProjectManifest):
|
|||||||
const packageExtensions = manifest.pnpm?.packageExtensions
|
const packageExtensions = manifest.pnpm?.packageExtensions
|
||||||
const peerDependencyRules = manifest.pnpm?.peerDependencyRules
|
const peerDependencyRules = manifest.pnpm?.peerDependencyRules
|
||||||
const allowedDeprecatedVersions = manifest.pnpm?.allowedDeprecatedVersions
|
const allowedDeprecatedVersions = manifest.pnpm?.allowedDeprecatedVersions
|
||||||
|
const patchedDependencies = manifest.pnpm?.patchedDependencies
|
||||||
return {
|
return {
|
||||||
allowedDeprecatedVersions,
|
allowedDeprecatedVersions,
|
||||||
overrides,
|
overrides,
|
||||||
@@ -29,5 +31,6 @@ export default function getOptionsFromRootManifest (manifest: ProjectManifest):
|
|||||||
onlyBuiltDependencies,
|
onlyBuiltDependencies,
|
||||||
packageExtensions,
|
packageExtensions,
|
||||||
peerDependencyRules,
|
peerDependencyRules,
|
||||||
|
patchedDependencies,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pnpm/constants": "workspace:6.1.0",
|
"@pnpm/constants": "workspace:6.1.0",
|
||||||
"@pnpm/core-loggers": "workspace:7.0.3",
|
"@pnpm/core-loggers": "workspace:7.0.3",
|
||||||
|
"@pnpm/crypto.base32-hash": "workspace:1.0.0",
|
||||||
"@pnpm/error": "workspace:3.0.1",
|
"@pnpm/error": "workspace:3.0.1",
|
||||||
"@pnpm/lockfile-types": "workspace:4.0.3",
|
"@pnpm/lockfile-types": "workspace:4.0.3",
|
||||||
"@pnpm/lockfile-utils": "workspace:4.0.5",
|
"@pnpm/lockfile-utils": "workspace:4.0.5",
|
||||||
|
|||||||
@@ -256,7 +256,8 @@ async function finishLockfileUpdates (
|
|||||||
Boolean(pkgJson.scripts.postinstall)
|
Boolean(pkgJson.scripts.postinstall)
|
||||||
) ||
|
) ||
|
||||||
filesResponse.filesIndex['binding.gyp'] ||
|
filesResponse.filesIndex['binding.gyp'] ||
|
||||||
Object.keys(filesResponse.filesIndex).some((filename) => !(filename.match(/^[.]hooks[\\/]/) == null)) // TODO: optimize this
|
Object.keys(filesResponse.filesIndex).some((filename) => !(filename.match(/^[.]hooks[\\/]/) == null)) || // TODO: optimize this
|
||||||
|
depNode.patchFile != null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
// This should never ever happen
|
// This should never ever happen
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
progressLogger,
|
progressLogger,
|
||||||
skippedOptionalDependencyLogger,
|
skippedOptionalDependencyLogger,
|
||||||
} from '@pnpm/core-loggers'
|
} from '@pnpm/core-loggers'
|
||||||
|
import { createBase32HashFromFile } from '@pnpm/crypto.base32-hash'
|
||||||
import PnpmError from '@pnpm/error'
|
import PnpmError from '@pnpm/error'
|
||||||
import {
|
import {
|
||||||
Lockfile,
|
Lockfile,
|
||||||
@@ -129,6 +130,7 @@ export interface ResolutionContext {
|
|||||||
resolvedPackagesByDepPath: ResolvedPackagesByDepPath
|
resolvedPackagesByDepPath: ResolvedPackagesByDepPath
|
||||||
outdatedDependencies: {[pkgId: string]: string}
|
outdatedDependencies: {[pkgId: string]: string}
|
||||||
childrenByParentDepPath: ChildrenByParentDepPath
|
childrenByParentDepPath: ChildrenByParentDepPath
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
pendingNodes: PendingNode[]
|
pendingNodes: PendingNode[]
|
||||||
wantedLockfile: Lockfile
|
wantedLockfile: Lockfile
|
||||||
currentLockfile: Lockfile
|
currentLockfile: Lockfile
|
||||||
@@ -195,6 +197,10 @@ export interface ResolvedPackage {
|
|||||||
optionalDependencies: Set<string>
|
optionalDependencies: Set<string>
|
||||||
hasBin: boolean
|
hasBin: boolean
|
||||||
hasBundledDependencies: boolean
|
hasBundledDependencies: boolean
|
||||||
|
patchFile?: {
|
||||||
|
path: string
|
||||||
|
hash: string
|
||||||
|
}
|
||||||
prepare: boolean
|
prepare: boolean
|
||||||
depPath: string
|
depPath: string
|
||||||
requiresBuild: boolean | SafePromiseDefer<boolean>
|
requiresBuild: boolean | SafePromiseDefer<boolean>
|
||||||
@@ -915,12 +921,18 @@ async function resolveDependency (
|
|||||||
status: 'resolved',
|
status: 'resolved',
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.resolvedPackagesByDepPath[depPath] = getResolvedPackage({
|
let patchPath = ctx.patchedDependencies?.[`${pkg.name}@${pkg.version}`]
|
||||||
|
if (patchPath) {
|
||||||
|
patchPath = path.join(ctx.lockfileDir, patchPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.resolvedPackagesByDepPath[depPath] = await getResolvedPackage({
|
||||||
allowBuild: ctx.allowBuild,
|
allowBuild: ctx.allowBuild,
|
||||||
dependencyLockfile: currentPkg.dependencyLockfile,
|
dependencyLockfile: currentPkg.dependencyLockfile,
|
||||||
depPath,
|
depPath,
|
||||||
force: ctx.force,
|
force: ctx.force,
|
||||||
hasBin,
|
hasBin,
|
||||||
|
patchPath,
|
||||||
pkg,
|
pkg,
|
||||||
pkgResponse,
|
pkgResponse,
|
||||||
prepare,
|
prepare,
|
||||||
@@ -1005,19 +1017,20 @@ function pkgIsLeaf (pkg: PackageManifest) {
|
|||||||
isEmpty(pkg.peerDependencies ?? {})
|
isEmpty(pkg.peerDependencies ?? {})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getResolvedPackage (
|
async function getResolvedPackage (
|
||||||
options: {
|
options: {
|
||||||
allowBuild?: (pkgName: string) => boolean
|
allowBuild?: (pkgName: string) => boolean
|
||||||
dependencyLockfile?: PackageSnapshot
|
dependencyLockfile?: PackageSnapshot
|
||||||
depPath: string
|
depPath: string
|
||||||
force: boolean
|
force: boolean
|
||||||
hasBin: boolean
|
hasBin: boolean
|
||||||
|
patchPath?: string
|
||||||
pkg: PackageManifest
|
pkg: PackageManifest
|
||||||
pkgResponse: PackageResponse
|
pkgResponse: PackageResponse
|
||||||
prepare: boolean
|
prepare: boolean
|
||||||
wantedDependency: WantedDependency
|
wantedDependency: WantedDependency
|
||||||
}
|
}
|
||||||
) {
|
): Promise<ResolvedPackage> {
|
||||||
const peerDependencies = peerDependenciesWithoutOwn(options.pkg)
|
const peerDependencies = peerDependenciesWithoutOwn(options.pkg)
|
||||||
|
|
||||||
const requiresBuild = (options.allowBuild == null || options.allowBuild(options.pkg.name))
|
const requiresBuild = (options.allowBuild == null || options.allowBuild(options.pkg.name))
|
||||||
@@ -1046,6 +1059,9 @@ function getResolvedPackage (
|
|||||||
name: options.pkg.name,
|
name: options.pkg.name,
|
||||||
optional: options.wantedDependency.optional,
|
optional: options.wantedDependency.optional,
|
||||||
optionalDependencies: new Set(Object.keys(options.pkg.optionalDependencies ?? {})),
|
optionalDependencies: new Set(Object.keys(options.pkg.optionalDependencies ?? {})),
|
||||||
|
patchFile: options.patchPath
|
||||||
|
? { path: options.patchPath, hash: await createBase32HashFromFile(options.patchPath) }
|
||||||
|
: undefined,
|
||||||
peerDependencies: peerDependencies ?? {},
|
peerDependencies: peerDependencies ?? {},
|
||||||
peerDependenciesMeta: options.pkg.peerDependenciesMeta,
|
peerDependenciesMeta: options.pkg.peerDependenciesMeta,
|
||||||
prepare: options.prepare,
|
prepare: options.prepare,
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export interface ResolveDependenciesOptions {
|
|||||||
}
|
}
|
||||||
nodeVersion: string
|
nodeVersion: string
|
||||||
registries: Registries
|
registries: Registries
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
pnpmVersion: string
|
pnpmVersion: string
|
||||||
preferredVersions?: PreferredVersions
|
preferredVersions?: PreferredVersions
|
||||||
preferWorkspacePackages?: boolean
|
preferWorkspacePackages?: boolean
|
||||||
@@ -103,6 +104,7 @@ export default async function<T> (
|
|||||||
lockfileDir: opts.lockfileDir,
|
lockfileDir: opts.lockfileDir,
|
||||||
nodeVersion: opts.nodeVersion,
|
nodeVersion: opts.nodeVersion,
|
||||||
outdatedDependencies: {} as {[pkgId: string]: string},
|
outdatedDependencies: {} as {[pkgId: string]: string},
|
||||||
|
patchedDependencies: opts.patchedDependencies,
|
||||||
pendingNodes: [] as PendingNode[],
|
pendingNodes: [] as PendingNode[],
|
||||||
pnpmVersion: opts.pnpmVersion,
|
pnpmVersion: opts.pnpmVersion,
|
||||||
preferWorkspacePackages: opts.preferWorkspacePackages,
|
preferWorkspacePackages: opts.preferWorkspacePackages,
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
{
|
{
|
||||||
"path": "../core-loggers"
|
"path": "../core-loggers"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "../crypto.base32-hash"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "../dependency-path"
|
"path": "../dependency-path"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default async function (
|
|||||||
stop: async () => {
|
stop: async () => {
|
||||||
await limitedFetch(`${remotePrefix}/stop`, {})
|
await limitedFetch(`${remotePrefix}/stop`, {})
|
||||||
},
|
},
|
||||||
upload: async (builtPkgLocation: string, opts: {filesIndexFile: string, engine: string}) => {
|
upload: async (builtPkgLocation: string, opts: {filesIndexFile: string, sideEffectsCacheKey: string}) => {
|
||||||
await limitedFetch(`${remotePrefix}/upload`, {
|
await limitedFetch(`${remotePrefix}/upload`, {
|
||||||
builtPkgLocation,
|
builtPkgLocation,
|
||||||
opts,
|
opts,
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ test('server upload', async () => {
|
|||||||
const filesIndexFile = path.join(storeDir, 'test.example.com/fake-pkg/1.0.0.json')
|
const filesIndexFile = path.join(storeDir, 'test.example.com/fake-pkg/1.0.0.json')
|
||||||
|
|
||||||
await storeCtrl.upload(path.join(__dirname, 'side-effect-fake-dir'), {
|
await storeCtrl.upload(path.join(__dirname, 'side-effect-fake-dir'), {
|
||||||
engine: fakeEngine,
|
sideEffectsCacheKey: fakeEngine,
|
||||||
filesIndexFile,
|
filesIndexFile,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ test('disable server upload', async () => {
|
|||||||
let thrown = false
|
let thrown = false
|
||||||
try {
|
try {
|
||||||
await storeCtrl.upload(path.join(__dirname, 'side-effect-fake-dir'), {
|
await storeCtrl.upload(path.join(__dirname, 'side-effect-fake-dir'), {
|
||||||
engine: fakeEngine,
|
sideEffectsCacheKey: fakeEngine,
|
||||||
filesIndexFile,
|
filesIndexFile,
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -35,13 +35,20 @@ DependencyManifest,
|
|||||||
| 'version'
|
| 'version'
|
||||||
>
|
>
|
||||||
|
|
||||||
|
export interface UploadPkgToStoreOpts {
|
||||||
|
filesIndexFile: string
|
||||||
|
sideEffectsCacheKey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UploadPkgToStore = (builtPkgLocation: string, opts: UploadPkgToStoreOpts) => Promise<void>
|
||||||
|
|
||||||
export interface StoreController {
|
export interface StoreController {
|
||||||
requestPackage: RequestPackageFunction
|
requestPackage: RequestPackageFunction
|
||||||
fetchPackage: FetchPackageToStoreFunction
|
fetchPackage: FetchPackageToStoreFunction
|
||||||
importPackage: ImportPackageFunction
|
importPackage: ImportPackageFunction
|
||||||
close: () => Promise<void>
|
close: () => Promise<void>
|
||||||
prune: () => Promise<void>
|
prune: () => Promise<void>
|
||||||
upload: (builtPkgLocation: string, opts: {filesIndexFile: string, engine: string}) => Promise<void>
|
upload: UploadPkgToStore
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FetchPackageToStoreFunction = (
|
export type FetchPackageToStoreFunction = (
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export interface DependenciesMeta {
|
|||||||
[dependencyName: string]: {
|
[dependencyName: string]: {
|
||||||
injected?: boolean
|
injected?: boolean
|
||||||
node?: string
|
node?: string
|
||||||
|
patch?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +127,7 @@ export type ProjectManifest = BaseManifest & {
|
|||||||
packageExtensions?: Record<string, PackageExtension>
|
packageExtensions?: Record<string, PackageExtension>
|
||||||
peerDependencyRules?: PeerDependencyRules
|
peerDependencyRules?: PeerDependencyRules
|
||||||
allowedDeprecatedVersions?: AllowedDeprecatedVersions
|
allowedDeprecatedVersions?: AllowedDeprecatedVersions
|
||||||
|
patchedDependencies?: Record<string, string>
|
||||||
}
|
}
|
||||||
private?: boolean
|
private?: boolean
|
||||||
resolutions?: Record<string, string>
|
resolutions?: Record<string, string>
|
||||||
|
|||||||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
@@ -1125,6 +1125,7 @@ importers:
|
|||||||
'@pnpm/client': workspace:7.1.5
|
'@pnpm/client': workspace:7.1.5
|
||||||
'@pnpm/constants': workspace:6.1.0
|
'@pnpm/constants': workspace:6.1.0
|
||||||
'@pnpm/core-loggers': workspace:7.0.3
|
'@pnpm/core-loggers': workspace:7.0.3
|
||||||
|
'@pnpm/crypto.base32-hash': workspace:1.0.0
|
||||||
'@pnpm/error': workspace:3.0.1
|
'@pnpm/error': workspace:3.0.1
|
||||||
'@pnpm/filter-lockfile': workspace:6.0.6
|
'@pnpm/filter-lockfile': workspace:6.0.6
|
||||||
'@pnpm/headless': workspace:18.2.0
|
'@pnpm/headless': workspace:18.2.0
|
||||||
@@ -1173,6 +1174,7 @@ importers:
|
|||||||
'@pnpm/calc-dep-state': link:../calc-dep-state
|
'@pnpm/calc-dep-state': link:../calc-dep-state
|
||||||
'@pnpm/constants': link:../constants
|
'@pnpm/constants': link:../constants
|
||||||
'@pnpm/core-loggers': link:../core-loggers
|
'@pnpm/core-loggers': link:../core-loggers
|
||||||
|
'@pnpm/crypto.base32-hash': link:../crypto.base32-hash
|
||||||
'@pnpm/error': link:../error
|
'@pnpm/error': link:../error
|
||||||
'@pnpm/filter-lockfile': link:../filter-lockfile
|
'@pnpm/filter-lockfile': link:../filter-lockfile
|
||||||
'@pnpm/hoist': link:../hoist
|
'@pnpm/hoist': link:../hoist
|
||||||
@@ -3211,6 +3213,7 @@ importers:
|
|||||||
specifiers:
|
specifiers:
|
||||||
'@pnpm/constants': workspace:6.1.0
|
'@pnpm/constants': workspace:6.1.0
|
||||||
'@pnpm/core-loggers': workspace:7.0.3
|
'@pnpm/core-loggers': workspace:7.0.3
|
||||||
|
'@pnpm/crypto.base32-hash': workspace:1.0.0
|
||||||
'@pnpm/error': workspace:3.0.1
|
'@pnpm/error': workspace:3.0.1
|
||||||
'@pnpm/lockfile-types': workspace:4.0.3
|
'@pnpm/lockfile-types': workspace:4.0.3
|
||||||
'@pnpm/lockfile-utils': workspace:4.0.5
|
'@pnpm/lockfile-utils': workspace:4.0.5
|
||||||
@@ -3246,6 +3249,7 @@ importers:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@pnpm/constants': link:../constants
|
'@pnpm/constants': link:../constants
|
||||||
'@pnpm/core-loggers': link:../core-loggers
|
'@pnpm/core-loggers': link:../core-loggers
|
||||||
|
'@pnpm/crypto.base32-hash': link:../crypto.base32-hash
|
||||||
'@pnpm/error': link:../error
|
'@pnpm/error': link:../error
|
||||||
'@pnpm/lockfile-types': link:../lockfile-types
|
'@pnpm/lockfile-types': link:../lockfile-types
|
||||||
'@pnpm/lockfile-utils': link:../lockfile-utils
|
'@pnpm/lockfile-utils': link:../lockfile-utils
|
||||||
|
|||||||
Reference in New Issue
Block a user