mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
feat: new option for disabling local directory dependencies relinking (#7083)
Removed `disableRelinkFromStore` and `relinkLocalDirDeps`. Replaced them with `disableRelinkLocalDirDeps`.
This commit is contained in:
9
.changeset/eighty-peas-think.md
Normal file
9
.changeset/eighty-peas-think.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
"@pnpm/store-connection-manager": major
|
||||
"@pnpm/store-controller-types": major
|
||||
"@pnpm/headless": minor
|
||||
"@pnpm/core": minor
|
||||
"@pnpm/worker": minor
|
||||
---
|
||||
|
||||
Remove `disableRelinkFromStore` and `relinkLocalDirDeps`. Replace them with `disableRelinkLocalDirDeps`.
|
||||
13
.changeset/few-gifts-call.md
Normal file
13
.changeset/few-gifts-call.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
"@pnpm/package-requester": major
|
||||
"@pnpm/store-controller-types": major
|
||||
"@pnpm/fs.indexed-pkg-importer": major
|
||||
"@pnpm/create-cafs-store": major
|
||||
"@pnpm/cafs-types": major
|
||||
"@pnpm/server": major
|
||||
"@pnpm/tarball-fetcher": major
|
||||
"@pnpm/node.fetcher": major
|
||||
"@pnpm/lifecycle": major
|
||||
---
|
||||
|
||||
`fromStore` replaced with `resolvedFrom`.
|
||||
5
.changeset/slimy-trains-flash.md
Normal file
5
.changeset/slimy-trains-flash.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/graceful-fs": minor
|
||||
---
|
||||
|
||||
Export readdirSync.
|
||||
2
env/node.fetcher/src/index.ts
vendored
2
env/node.fetcher/src/index.ts
vendored
@@ -49,7 +49,7 @@ export async function fetchNode (fetch: FetchFromRegistry, version: string, targ
|
||||
cafs.importPackage(targetDir, {
|
||||
filesResponse: {
|
||||
filesIndex: filesIndex as Record<string, string>,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
},
|
||||
force: true,
|
||||
})
|
||||
|
||||
@@ -84,7 +84,7 @@ export async function runLifecycleHooksConcurrently (
|
||||
}
|
||||
return opts.storeController.importPackage(targetDir, {
|
||||
filesResponse: {
|
||||
fromStore: false,
|
||||
resolvedFrom: 'local-dir',
|
||||
...filesResponse,
|
||||
filesIndex: {
|
||||
...filesResponse.filesIndex,
|
||||
|
||||
@@ -45,7 +45,7 @@ async function prepareGitHostedPkg (
|
||||
cafs.importPackage(tempLocation, {
|
||||
filesResponse: {
|
||||
filesIndex,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
},
|
||||
force: true,
|
||||
})
|
||||
|
||||
@@ -3,15 +3,16 @@ import gfs from 'graceful-fs'
|
||||
|
||||
export default { // eslint-disable-line
|
||||
copyFile: promisify(gfs.copyFile),
|
||||
copyFileSync: gfs.copyFileSync,
|
||||
createReadStream: gfs.createReadStream,
|
||||
link: promisify(gfs.link),
|
||||
linkSync: gfs.linkSync,
|
||||
readFile: promisify(gfs.readFile),
|
||||
readFileSync: gfs.readFileSync,
|
||||
readdirSync: gfs.readdirSync,
|
||||
stat: promisify(gfs.stat),
|
||||
statSync: gfs.statSync,
|
||||
unlinkSync: gfs.unlinkSync,
|
||||
writeFile: promisify(gfs.writeFile),
|
||||
writeFileSync: gfs.writeFileSync,
|
||||
readFileSync: gfs.readFileSync,
|
||||
unlinkSync: gfs.unlinkSync,
|
||||
linkSync: gfs.linkSync,
|
||||
statSync: gfs.statSync,
|
||||
copyFileSync: gfs.copyFileSync,
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ function clonePkg (
|
||||
) {
|
||||
const pkgJsonPath = path.join(to, 'package.json')
|
||||
|
||||
if (!opts.fromStore || opts.force || !existsSync(pkgJsonPath)) {
|
||||
if (opts.resolvedFrom !== 'store' || opts.force || !existsSync(pkgJsonPath)) {
|
||||
importIndexedDir(cloneFile, to, opts.filesMap, opts)
|
||||
return 'clone'
|
||||
}
|
||||
@@ -122,20 +122,26 @@ function hardlinkPkg (
|
||||
to: string,
|
||||
opts: ImportOptions
|
||||
) {
|
||||
if (
|
||||
!opts.fromStore ||
|
||||
opts.force ||
|
||||
!(opts.disableRelinkFromStore ? pkgExists : pkgLinkedToStore)(opts.filesMap, to)
|
||||
) {
|
||||
if (opts.force || shouldRelinkPkg(to, opts)) {
|
||||
importIndexedDir(importFile, to, opts.filesMap, opts)
|
||||
return 'hardlink'
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
function pkgExists (filesMap: Record<string, string>, to: string): boolean {
|
||||
const [anyFile] = Object.keys(filesMap)
|
||||
return existsSync(path.join(to, anyFile))
|
||||
function shouldRelinkPkg (
|
||||
to: string,
|
||||
opts: ImportOptions
|
||||
) {
|
||||
if (opts.disableRelinkLocalDirDeps && opts.resolvedFrom === 'local-dir') {
|
||||
try {
|
||||
const files = fs.readdirSync(to)
|
||||
return files.length === 0 || files.length === 1 && files[0] === 'node_modules'
|
||||
} catch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return opts.resolvedFrom !== 'store' || !pkgLinkedToStore(opts.filesMap, to)
|
||||
}
|
||||
|
||||
function linkOrCopy (existingPath: string, newPath: string) {
|
||||
@@ -189,7 +195,7 @@ export function copyPkg (
|
||||
) {
|
||||
const pkgJsonPath = path.join(to, 'package.json')
|
||||
|
||||
if (!opts.fromStore || opts.force || !existsSync(pkgJsonPath)) {
|
||||
if (opts.resolvedFrom !== 'store' || opts.force || !existsSync(pkgJsonPath)) {
|
||||
importIndexedDir(fs.copyFileSync, to, opts.filesMap, opts)
|
||||
return 'copy'
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ test('packageImportMethod=auto: clone files by default', () => {
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('clone')
|
||||
expect(gfs.copyFileSync).toBeCalledWith(
|
||||
path.join('hash1'),
|
||||
@@ -69,7 +69,7 @@ test('packageImportMethod=auto: link files if cloning fails', () => {
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.linkSync).toBeCalledWith(path.join('hash1'), path.join('project', 'package_tmp', 'package.json'))
|
||||
expect(gfs.linkSync).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
@@ -83,7 +83,7 @@ test('packageImportMethod=auto: link files if cloning fails', () => {
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.copyFileSync).not.toBeCalled()
|
||||
expect(gfs.linkSync).toBeCalledWith(path.join('hash1'), path.join('project2', 'package_tmp', 'package.json'))
|
||||
@@ -107,7 +107,7 @@ test('packageImportMethod=auto: link files if cloning fails and even hard linkin
|
||||
'index.js': 'hash2',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.linkSync).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
expect(gfs.linkSync).toBeCalledTimes(2)
|
||||
@@ -129,7 +129,7 @@ test('packageImportMethod=auto: chooses copying if cloning and hard linking is n
|
||||
'index.js': 'hash2',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('copy')
|
||||
expect(gfs.copyFileSync).toBeCalledWith(path.join('hash2'), path.join('project', 'package_tmp', 'index.js'))
|
||||
expect(gfs.copyFileSync).toBeCalledTimes(2)
|
||||
@@ -150,7 +150,7 @@ test('packageImportMethod=hardlink: fall back to copying if hardlinking fails',
|
||||
license: 'hash3',
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})).toBe('hardlink')
|
||||
expect(gfs.linkSync).toBeCalledTimes(3)
|
||||
expect(gfs.copyFileSync).toBeCalledTimes(2) // One time the target already exists, so it won't be copied
|
||||
@@ -167,7 +167,7 @@ test('packageImportMethod=hardlink does not relink package from store if package
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
})).toBe(undefined)
|
||||
})
|
||||
|
||||
@@ -181,7 +181,7 @@ test('packageImportMethod=hardlink relinks package from store if package.json is
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
})).toBe('hardlink')
|
||||
expect(globalInfo).toBeCalledWith('Relinking project/package from the store')
|
||||
})
|
||||
@@ -197,7 +197,7 @@ test('packageImportMethod=hardlink does not relink package from store if package
|
||||
'index.js': 'hash2',
|
||||
},
|
||||
force: false,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
})).toBe(undefined)
|
||||
})
|
||||
|
||||
@@ -215,7 +215,7 @@ test('packageImportMethod=hardlink links packages when they are not found', () =
|
||||
'package.json': 'hash1',
|
||||
},
|
||||
force: false,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
})).toBe('hardlink')
|
||||
expect(globalInfo).not.toBeCalledWith('Relinking project/package from the store')
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ test('importing a package with invalid files', () => {
|
||||
'1*2.txt': __filename,
|
||||
},
|
||||
force: false,
|
||||
fromStore: false,
|
||||
resolvedFrom: 'remote',
|
||||
})
|
||||
expect((fs.readdirSync(target)).length).toBe(2)
|
||||
})
|
||||
|
||||
@@ -125,8 +125,7 @@ export interface StrictInstallOptions {
|
||||
excludeLinksFromLockfile: boolean
|
||||
confirmModulesPurge: boolean
|
||||
/**
|
||||
* Don't relink packages if they are not hard linked from the store.
|
||||
* This also applies to injected dependencies, which are linked from the local package's location.
|
||||
* Don't relink local directory dependencies if they are not hard linked from the local directory.
|
||||
*
|
||||
* This option was added to fix an issue with Bit CLI.
|
||||
* Bit compile adds dist directories to the injected dependencies, so if pnpm were to relink them,
|
||||
@@ -134,7 +133,7 @@ export interface StrictInstallOptions {
|
||||
*
|
||||
* The option might be used in the future to improve performance.
|
||||
*/
|
||||
disableRelinkFromStore: boolean
|
||||
disableRelinkLocalDirDeps: boolean
|
||||
}
|
||||
|
||||
export type InstallOptions =
|
||||
|
||||
@@ -1094,7 +1094,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
|
||||
dedupeDirectDeps: opts.dedupeDirectDeps,
|
||||
dependenciesByProjectId,
|
||||
depsStateCache,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
extraNodePaths: ctx.extraNodePaths,
|
||||
force: opts.force,
|
||||
hoistedDependencies: ctx.hoistedDependencies,
|
||||
|
||||
@@ -49,7 +49,7 @@ export async function linkPackages (
|
||||
currentLockfile: Lockfile
|
||||
dedupeDirectDeps: boolean
|
||||
dependenciesByProjectId: Record<string, Record<string, string>>
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
depsStateCache: DepsStateCache
|
||||
extraNodePaths: string[]
|
||||
@@ -144,7 +144,7 @@ export async function linkPackages (
|
||||
newCurrentLockfile,
|
||||
depGraph,
|
||||
{
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
force: opts.force,
|
||||
depsStateCache: opts.depsStateCache,
|
||||
ignoreScripts: opts.ignoreScripts,
|
||||
@@ -303,7 +303,7 @@ async function linkNewPackages (
|
||||
depGraph: DependenciesGraph,
|
||||
opts: {
|
||||
depsStateCache: DepsStateCache
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
optional: boolean
|
||||
ignoreScripts: boolean
|
||||
@@ -369,7 +369,7 @@ async function linkNewPackages (
|
||||
linkAllPkgs(opts.storeController, newPkgs, {
|
||||
depGraph,
|
||||
depsStateCache: opts.depsStateCache,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
force: opts.force,
|
||||
ignoreScripts: opts.ignoreScripts,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
@@ -422,7 +422,7 @@ async function linkAllPkgs (
|
||||
opts: {
|
||||
depGraph: DependenciesGraph
|
||||
depsStateCache: DepsStateCache
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
ignoreScripts: boolean
|
||||
lockfileDir: string
|
||||
@@ -444,7 +444,7 @@ async function linkAllPkgs (
|
||||
})
|
||||
}
|
||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
filesResponse: files,
|
||||
force: opts.force,
|
||||
sideEffectsCacheKey,
|
||||
|
||||
@@ -1692,7 +1692,7 @@ test('relink injected dependency on install by default', async () => {
|
||||
expect(storeInode).toEqual(getInode())
|
||||
})
|
||||
|
||||
test('do not relink injected dependency on install when disableRelinkFromStore is set to true', async () => {
|
||||
test('do not relink injected dependency on install when disableRelinkLocalDirDeps is set to true', async () => {
|
||||
const depManifest = {
|
||||
name: 'dep',
|
||||
version: '1.0.0',
|
||||
@@ -1775,9 +1775,7 @@ test('do not relink injected dependency on install when disableRelinkFromStore i
|
||||
workspacePackages,
|
||||
packageImportMethod: 'hardlink',
|
||||
fastUnpack: false,
|
||||
disableRelinkFromStore: true,
|
||||
}, {}, {}, {
|
||||
relinkLocalDirDeps: false,
|
||||
disableRelinkLocalDirDeps: true,
|
||||
}))
|
||||
|
||||
expect(newInode).toEqual(getInode())
|
||||
|
||||
@@ -481,7 +481,7 @@ test('re-install should update local file dependency', async () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('local directory is not relinked if relinkLocalDirDeps is set to false', async () => {
|
||||
test('local directory is not relinked if disableRelinkLocalDirDeps is set to true', async () => {
|
||||
prepareEmpty()
|
||||
fss.mkdirSync('pkg')
|
||||
fss.writeFileSync('pkg/index.js', 'hello', 'utf8')
|
||||
@@ -491,15 +491,11 @@ test('local directory is not relinked if relinkLocalDirDeps is set to false', as
|
||||
|
||||
fss.writeFileSync('pkg/new.js', 'hello', 'utf8')
|
||||
|
||||
await addDependenciesToPackage(manifest, ['is-odd@1.0.0'], await testDefaults({}, {}, {}, {
|
||||
relinkLocalDirDeps: false,
|
||||
}))
|
||||
await addDependenciesToPackage(manifest, ['is-odd@1.0.0'], await testDefaults({ disableRelinkLocalDirDeps: true }))
|
||||
|
||||
expect(fss.readdirSync('node_modules/pkg').sort()).toStrictEqual(['index.js', 'package.json'])
|
||||
|
||||
await install(manifest, await testDefaults({ frozenLockfile: true }, {}, {}, {
|
||||
relinkLocalDirDeps: false,
|
||||
}))
|
||||
await install(manifest, await testDefaults({ frozenLockfile: true, disableRelinkLocalDirDeps: true }))
|
||||
|
||||
expect(fss.readdirSync('node_modules/pkg').sort()).toStrictEqual(['index.js', 'package.json'])
|
||||
})
|
||||
|
||||
@@ -132,7 +132,7 @@ export interface HeadlessOptions {
|
||||
sideEffectsCacheRead: boolean
|
||||
sideEffectsCacheWrite: boolean
|
||||
symlink?: boolean
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
storeDir: string
|
||||
rawConfig: object
|
||||
@@ -354,7 +354,7 @@ export async function headlessInstall (opts: HeadlessOptions): Promise<Installat
|
||||
if (opts.nodeLinker === 'hoisted' && hierarchy && prevGraph) {
|
||||
await linkHoistedModules(opts.storeController, graph, prevGraph, hierarchy, {
|
||||
depsStateCache,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
force: opts.force,
|
||||
ignoreScripts: opts.ignoreScripts,
|
||||
lockfileDir: opts.lockfileDir,
|
||||
@@ -385,7 +385,7 @@ export async function headlessInstall (opts: HeadlessOptions): Promise<Installat
|
||||
}),
|
||||
linkAllPkgs(opts.storeController, depNodes, {
|
||||
force: opts.force,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
depGraph: graph,
|
||||
depsStateCache,
|
||||
ignoreScripts: opts.ignoreScripts,
|
||||
@@ -773,7 +773,7 @@ async function linkAllPkgs (
|
||||
opts: {
|
||||
depGraph: DependenciesGraph
|
||||
depsStateCache: DepsStateCache
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
ignoreScripts: boolean
|
||||
lockfileDir: string
|
||||
@@ -800,7 +800,7 @@ async function linkAllPkgs (
|
||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||
filesResponse,
|
||||
force: opts.force,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
requiresBuild: depNode.requiresBuild || depNode.patchFile != null,
|
||||
sideEffectsCacheKey,
|
||||
})
|
||||
|
||||
@@ -29,7 +29,7 @@ export async function linkHoistedModules (
|
||||
hierarchy: DepHierarchy,
|
||||
opts: {
|
||||
depsStateCache: DepsStateCache
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
ignoreScripts: boolean
|
||||
lockfileDir: string
|
||||
@@ -87,7 +87,7 @@ async function linkAllPkgsInOrder (
|
||||
parentDir: string,
|
||||
opts: {
|
||||
depsStateCache: DepsStateCache
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
force: boolean
|
||||
ignoreScripts: boolean
|
||||
lockfileDir: string
|
||||
@@ -123,7 +123,7 @@ async function linkAllPkgsInOrder (
|
||||
const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, {
|
||||
filesResponse,
|
||||
force: opts.force || depNode.depPath !== prevGraph[dir]?.depPath,
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
keepModulesDir: true,
|
||||
requiresBuild: depNode.requiresBuild || depNode.patchFile != null,
|
||||
sideEffectsCacheKey,
|
||||
|
||||
@@ -89,7 +89,6 @@ export function createPackageRequester (
|
||||
networkConcurrency?: number
|
||||
storeDir: string
|
||||
verifyStoreIntegrity: boolean
|
||||
relinkLocalDirDeps?: boolean
|
||||
}
|
||||
): RequestPackageFunction & {
|
||||
fetchPackageToStore: FetchPackageToStoreFunction
|
||||
@@ -116,7 +115,6 @@ export function createPackageRequester (
|
||||
counter: 0,
|
||||
concurrency: networkConcurrency,
|
||||
}),
|
||||
relinkLocalDirDeps: opts.relinkLocalDirDeps ?? true,
|
||||
storeDir: opts.storeDir,
|
||||
})
|
||||
const requestPackage = resolveAndFetch.bind(null, {
|
||||
@@ -329,7 +327,6 @@ function fetchToStore (
|
||||
counter: number
|
||||
concurrency: number
|
||||
}
|
||||
relinkLocalDirDeps: boolean
|
||||
storeDir: string
|
||||
},
|
||||
opts: FetchPackageToStoreOptions
|
||||
@@ -363,13 +360,13 @@ function fetchToStore (
|
||||
progressLogger.debug({
|
||||
packageId: opts.pkg.id,
|
||||
requester: opts.lockfileDir,
|
||||
status: cache.files.fromStore
|
||||
? 'found_in_store'
|
||||
: 'fetched',
|
||||
status: cache.files.resolvedFrom === 'remote'
|
||||
? 'fetched'
|
||||
: 'found_in_store',
|
||||
})
|
||||
|
||||
// If it's already in the store, we don't need to update the cache
|
||||
if (cache.files.fromStore) {
|
||||
if (cache.files.resolvedFrom !== 'remote') {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -385,7 +382,7 @@ function fetchToStore (
|
||||
...cache,
|
||||
files: {
|
||||
...cache.files,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
},
|
||||
}),
|
||||
})
|
||||
@@ -479,7 +476,7 @@ Actual package in the store by the given integrity: ${pkgFilesIndex.name}@${pkgF
|
||||
files: {
|
||||
unprocessed: true,
|
||||
filesIndex: pkgFilesIndex.files,
|
||||
fromStore: true,
|
||||
resolvedFrom: 'store',
|
||||
sideEffects: pkgFilesIndex.sideEffects,
|
||||
},
|
||||
bundledManifest: manifest == null ? manifest : normalizeBundledManifest(manifest),
|
||||
@@ -539,8 +536,7 @@ Actual package in the store by the given integrity: ${pkgFilesIndex.name}@${pkgF
|
||||
|
||||
fetching.resolve({
|
||||
files: {
|
||||
local: fetchedPackage.local,
|
||||
fromStore: !fetchedPackage.local ? false : !ctx.relinkLocalDirDeps,
|
||||
resolvedFrom: fetchedPackage.local ? 'local-dir' : 'remote',
|
||||
filesIndex: fetchedPackage.filesIndex,
|
||||
packageImportMethod: (fetchedPackage as DirectoryFetcherResult).packageImportMethod,
|
||||
},
|
||||
|
||||
@@ -68,7 +68,7 @@ test('request package', async () => {
|
||||
|
||||
const { files } = await pkgResponse.fetching!()
|
||||
expect(Object.keys(files.filesIndex).sort()).toStrictEqual(['package.json', 'index.js', 'license', 'readme.md'].sort())
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
})
|
||||
|
||||
test('request package but skip fetching', async () => {
|
||||
@@ -209,7 +209,7 @@ test('refetch local tarball if its integrity has changed', async () => {
|
||||
const { files, bundledManifest } = await response.fetching()
|
||||
|
||||
expect(response.body.updated).toBeFalsy()
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ test('refetch local tarball if its integrity has changed', async () => {
|
||||
const { files, bundledManifest } = await response.fetching!()
|
||||
|
||||
expect(response.body.updated).toBeTruthy()
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ test('refetch local tarball if its integrity has changed', async () => {
|
||||
const { files, bundledManifest } = await response.fetching()
|
||||
|
||||
expect(response.body.updated).toBeFalsy()
|
||||
expect(files.fromStore).toBeTruthy()
|
||||
expect(files.resolvedFrom).toBe('store')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
})
|
||||
@@ -303,7 +303,7 @@ test('refetch local tarball if its integrity has changed. The requester does not
|
||||
const { files, bundledManifest } = await response.fetching()
|
||||
|
||||
expect(response.body.updated).toBeTruthy()
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ test('refetch local tarball if its integrity has changed. The requester does not
|
||||
const { files, bundledManifest } = await response.fetching()
|
||||
|
||||
expect(response.body.updated).toBeTruthy()
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ test('refetch local tarball if its integrity has changed. The requester does not
|
||||
}
|
||||
const { files, bundledManifest } = await response.fetching()
|
||||
|
||||
expect(files.fromStore).toBeTruthy()
|
||||
expect(files.resolvedFrom).toBe('store')
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
}
|
||||
})
|
||||
@@ -379,7 +379,7 @@ test('fetchPackageToStore()', async () => {
|
||||
const { files, bundledManifest } = await fetchResult.fetching()
|
||||
expect(bundledManifest).toBeFalsy()
|
||||
expect(Object.keys(files.filesIndex).sort()).toStrictEqual(['package.json', 'index.js', 'license', 'readme.md'].sort())
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
|
||||
const indexFile = await loadJsonFile<PackageFilesIndex>(fetchResult.filesIndexFile)
|
||||
expect(indexFile).toBeTruthy()
|
||||
@@ -471,7 +471,7 @@ test('fetchPackageToStore() concurrency check', async () => {
|
||||
ino1 = statSync(files.filesIndex['package.json'] as string).ino
|
||||
|
||||
expect(Object.keys(files.filesIndex).sort()).toStrictEqual(['package.json', 'index.js', 'license', 'readme.md'].sort())
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
}
|
||||
|
||||
{
|
||||
@@ -481,7 +481,7 @@ test('fetchPackageToStore() concurrency check', async () => {
|
||||
ino2 = statSync(files.filesIndex['package.json'] as string).ino
|
||||
|
||||
expect(Object.keys(files.filesIndex).sort()).toStrictEqual(['package.json', 'index.js', 'license', 'readme.md'].sort())
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
}
|
||||
|
||||
expect(ino1).toBe(ino2)
|
||||
@@ -548,7 +548,7 @@ test('fetchPackageToStore() does not cache errors', async () => {
|
||||
})
|
||||
const { files } = await fetchResult.fetching()
|
||||
expect(Object.keys(files.filesIndex).sort()).toStrictEqual(['package.json', 'index.js', 'license', 'readme.md'].sort())
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
|
||||
expect(nock.isDone()).toBeTruthy()
|
||||
})
|
||||
|
||||
@@ -109,5 +109,5 @@ export async function handler (
|
||||
async function copyProject (src: string, dest: string, opts: { includeOnlyPackageFiles: boolean }) {
|
||||
const { filesIndex } = await fetchFromDir(src, opts)
|
||||
const importPkg = createIndexedPkgImporter('clone-or-copy')
|
||||
importPkg(dest, { filesMap: filesIndex, force: true, fromStore: true })
|
||||
importPkg(dest, { filesMap: filesIndex, force: true, resolvedFrom: 'local-dir' })
|
||||
}
|
||||
|
||||
@@ -8,11 +8,12 @@ export interface PackageFileInfo {
|
||||
size: number
|
||||
}
|
||||
|
||||
export type ResolvedFrom = 'store' | 'local-dir' | 'remote'
|
||||
|
||||
export type PackageFilesResponse = {
|
||||
fromStore: boolean
|
||||
resolvedFrom: ResolvedFrom
|
||||
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy'
|
||||
sideEffects?: Record<string, Record<string, PackageFileInfo>>
|
||||
local?: boolean
|
||||
} & ({
|
||||
unprocessed?: false
|
||||
filesIndex: Record<string, string>
|
||||
@@ -22,7 +23,7 @@ export type PackageFilesResponse = {
|
||||
})
|
||||
|
||||
export interface ImportPackageOpts {
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
requiresBuild?: boolean
|
||||
sideEffectsCacheKey?: string
|
||||
filesResponse: PackageFilesResponse
|
||||
|
||||
@@ -39,9 +39,9 @@ export function createPackageImporterAsync (
|
||||
: (opts.filesResponse.packageImportMethod ?? packageImportMethod)
|
||||
const impPkg = cachedImporterCreator(pkgImportMethod)
|
||||
const importMethod = await impPkg(to, {
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
filesMap,
|
||||
fromStore: opts.filesResponse.fromStore,
|
||||
resolvedFrom: opts.filesResponse.resolvedFrom,
|
||||
force: opts.force,
|
||||
keepModulesDir: Boolean(opts.keepModulesDir),
|
||||
})
|
||||
@@ -68,9 +68,9 @@ function createPackageImporter (
|
||||
: (opts.filesResponse.packageImportMethod ?? packageImportMethod)
|
||||
const impPkg = cachedImporterCreator(pkgImportMethod)
|
||||
const importMethod = impPkg(to, {
|
||||
disableRelinkFromStore: opts.disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps: opts.disableRelinkLocalDirDeps,
|
||||
filesMap,
|
||||
fromStore: opts.filesResponse.fromStore,
|
||||
resolvedFrom: opts.filesResponse.resolvedFrom,
|
||||
force: opts.force,
|
||||
keepModulesDir: Boolean(opts.keepModulesDir),
|
||||
})
|
||||
|
||||
@@ -26,7 +26,6 @@ export async function createPackageStore (
|
||||
storeDir: string
|
||||
networkConcurrency?: number
|
||||
packageImportMethod?: 'auto' | 'hardlink' | 'copy' | 'clone' | 'clone-or-copy'
|
||||
relinkLocalDirDeps?: boolean
|
||||
verifyStoreIntegrity: boolean
|
||||
}
|
||||
): Promise<StoreController> {
|
||||
@@ -47,7 +46,6 @@ export async function createPackageStore (
|
||||
networkConcurrency: initOpts.networkConcurrency,
|
||||
storeDir: initOpts.storeDir,
|
||||
verifyStoreIntegrity: initOpts.verifyStoreIntegrity,
|
||||
relinkLocalDirDeps: initOpts.relinkLocalDirDeps,
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -63,7 +63,7 @@ test('server', async () => {
|
||||
expect(response.body.manifest!.name).toBe('is-positive')
|
||||
expect(response.body.manifest!.version).toBe('1.0.0')
|
||||
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(files.filesIndex).toHaveProperty(['package.json'])
|
||||
|
||||
await server.close()
|
||||
@@ -103,7 +103,7 @@ test('fetchPackage', async () => {
|
||||
const { bundledManifest, files } = await response.fetching!()
|
||||
expect(bundledManifest).toBeTruthy()
|
||||
|
||||
expect(files.fromStore).toBeFalsy()
|
||||
expect(files.resolvedFrom).toBe('remote')
|
||||
expect(files.filesIndex).toHaveProperty(['package.json'])
|
||||
|
||||
await server.close()
|
||||
|
||||
@@ -44,15 +44,6 @@ export type CreateNewStoreControllerOptions = CreateResolverOptions & Pick<Confi
|
||||
> & {
|
||||
cafsLocker?: CafsLocker
|
||||
ignoreFile?: (filename: string) => boolean
|
||||
/**
|
||||
* By default, injected (also known as local) dependencies are relinked on every install
|
||||
* to ensure that the links are always up-to-date.
|
||||
* If another tool persists modifications to the injected dependencies,
|
||||
* this option can be set to `false`.
|
||||
* For example, 'bit compile' writes the compiled code directly to the node_modules directory,
|
||||
* eliminating the need to relink the package.
|
||||
*/
|
||||
relinkLocalDirDeps?: boolean
|
||||
} & Partial<Pick<Config, 'userConfig' | 'deployAllFiles'>> & Pick<ClientOptions, 'resolveSymlinksInInjectedDirs'>
|
||||
|
||||
export async function createNewStoreController (
|
||||
@@ -110,7 +101,6 @@ export async function createNewStoreController (
|
||||
packageImportMethod: opts.packageImportMethod,
|
||||
cacheDir: opts.cacheDir,
|
||||
storeDir: opts.storeDir,
|
||||
relinkLocalDirDeps: opts.relinkLocalDirDeps,
|
||||
verifyStoreIntegrity: typeof opts.verifyStoreIntegrity === 'boolean'
|
||||
? opts.verifyStoreIntegrity
|
||||
: true,
|
||||
|
||||
@@ -5,11 +5,12 @@ import {
|
||||
type WantedDependency,
|
||||
type WorkspacePackages,
|
||||
} from '@pnpm/resolver-base'
|
||||
import type {
|
||||
ImportPackageFunction,
|
||||
ImportPackageFunctionAsync,
|
||||
PackageFileInfo,
|
||||
PackageFilesResponse,
|
||||
import {
|
||||
type ImportPackageFunction,
|
||||
type ImportPackageFunctionAsync,
|
||||
type PackageFileInfo,
|
||||
type PackageFilesResponse,
|
||||
type ResolvedFrom,
|
||||
} from '@pnpm/cafs-types'
|
||||
import {
|
||||
type DependencyManifest,
|
||||
@@ -161,10 +162,10 @@ export interface PackageResponse {
|
||||
export type FilesMap = Record<string, string>
|
||||
|
||||
export interface ImportOptions {
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
filesMap: FilesMap
|
||||
force: boolean
|
||||
fromStore: boolean
|
||||
resolvedFrom: ResolvedFrom
|
||||
keepModulesDir?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ export interface LinkPkgMessage {
|
||||
requiresBuild?: boolean
|
||||
force: boolean
|
||||
keepModulesDir?: boolean
|
||||
disableRelinkFromStore?: boolean
|
||||
disableRelinkLocalDirDeps?: boolean
|
||||
}
|
||||
|
||||
export interface SymlinkAllModulesMessage {
|
||||
|
||||
@@ -176,7 +176,7 @@ function importPackage ({
|
||||
requiresBuild,
|
||||
force,
|
||||
keepModulesDir,
|
||||
disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps,
|
||||
}: LinkPkgMessage) {
|
||||
const cacheKey = JSON.stringify({ storeDir, packageImportMethod })
|
||||
if (!cafsStoreCache.has(cacheKey)) {
|
||||
@@ -186,7 +186,7 @@ function importPackage ({
|
||||
const { importMethod, isBuilt } = cafsStore.importPackage(targetDir, {
|
||||
filesResponse,
|
||||
force,
|
||||
disableRelinkFromStore,
|
||||
disableRelinkLocalDirDeps,
|
||||
requiresBuild,
|
||||
sideEffectsCacheKey,
|
||||
keepModulesDir,
|
||||
|
||||
Reference in New Issue
Block a user