mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-24 07:38:12 -05:00
fix: recursive install from subdir when injected deps are present (#3971)
close #3970
This commit is contained in:
6
.changeset/cuddly-coins-lick.md
Normal file
6
.changeset/cuddly-coins-lick.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/directory-fetcher": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Installing a workspace project with an injected dependency from a non-root directory should not fail [#3970](https://github.com/pnpm/pnpm/issues/3970).
|
||||
7
.changeset/strong-clocks-knock.md
Normal file
7
.changeset/strong-clocks-knock.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@pnpm/local-resolver": patch
|
||||
"@pnpm/npm-resolver": patch
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
---
|
||||
|
||||
Injected directory resolutions should contain the relative path to the directory.
|
||||
@@ -6,6 +6,7 @@ import loadJsonFile from 'load-json-file'
|
||||
import packlist from 'npm-packlist'
|
||||
|
||||
export interface DirectoryFetcherOptions {
|
||||
lockfileDir: string
|
||||
manifest?: DeferredManifestPromise
|
||||
}
|
||||
|
||||
@@ -15,13 +16,16 @@ export default () => {
|
||||
cafs: Cafs,
|
||||
resolution: DirectoryResolution,
|
||||
opts: DirectoryFetcherOptions
|
||||
) => fetchFromDir(resolution.directory, opts),
|
||||
) => {
|
||||
const dir = path.join(opts.lockfileDir, resolution.directory)
|
||||
return fetchFromDir(dir, opts)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchFromDir (
|
||||
dir: string,
|
||||
opts: DirectoryFetcherOptions
|
||||
opts: Omit<DirectoryFetcherOptions, 'lockfileDir'>
|
||||
) {
|
||||
const files = await packlist({ path: dir })
|
||||
const filesIndex: Record<string, string> = fromPairs(files.map((file) => [file, path.join(dir, file)]))
|
||||
|
||||
@@ -6,7 +6,12 @@ test('fetch', async () => {
|
||||
const fetcher = createFetcher()
|
||||
|
||||
// eslint-disable-next-line
|
||||
const fetchResult = await fetcher.directory({} as any, { directory: path.join(__dirname, '..'), type: 'directory' }, {})
|
||||
const fetchResult = await fetcher.directory({} as any, {
|
||||
directory: '..',
|
||||
type: 'directory',
|
||||
}, {
|
||||
lockfileDir: __dirname,
|
||||
})
|
||||
|
||||
expect(fetchResult.local).toBe(true)
|
||||
expect(fetchResult.packageImportMethod).toBe('hardlink')
|
||||
|
||||
@@ -78,7 +78,9 @@ function fromLocal (
|
||||
}
|
||||
}
|
||||
|
||||
const dependencyPath = normalize(path.resolve(fetchSpec))
|
||||
const dependencyPath = injected
|
||||
? normalize(path.relative(lockfileDir, fetchSpec))
|
||||
: normalize(path.resolve(fetchSpec))
|
||||
const id = !injected && (type === 'directory' || projectDir === lockfileDir)
|
||||
? `${protocol}${normalize(path.relative(projectDir, fetchSpec))}`
|
||||
: `${protocol}${normalize(path.relative(lockfileDir, fetchSpec))}`
|
||||
|
||||
@@ -17,7 +17,7 @@ test('resolve injected directory', async () => {
|
||||
expect(resolveResult!.id).toEqual('file:..')
|
||||
expect(resolveResult!.normalizedPref).toEqual('file:..')
|
||||
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
|
||||
expect(resolveResult!.resolution['directory']).toEqual(normalize(path.join(__dirname, '..')))
|
||||
expect(resolveResult!.resolution['directory']).toEqual('..')
|
||||
expect(resolveResult!.resolution['type']).toEqual('directory')
|
||||
})
|
||||
|
||||
|
||||
@@ -301,14 +301,21 @@ function resolveFromLocalPackage (
|
||||
lockfileDir?: string
|
||||
}
|
||||
) {
|
||||
let id!: string
|
||||
let directory!: string
|
||||
if (opts.hardLinkLocalPackages) {
|
||||
directory = normalize(path.relative(opts.lockfileDir!, localPackage.dir))
|
||||
id = `file:${directory}`
|
||||
} else {
|
||||
directory = localPackage.dir
|
||||
id = `link:${normalize(path.relative(opts.projectDir, localPackage.dir))}`
|
||||
}
|
||||
return {
|
||||
id: opts.hardLinkLocalPackages
|
||||
? `file:${normalize(path.relative(opts.lockfileDir!, localPackage.dir))}`
|
||||
: `link:${normalize(path.relative(opts.projectDir, localPackage.dir))}`,
|
||||
id,
|
||||
manifest: localPackage.manifest,
|
||||
normalizedPref,
|
||||
resolution: {
|
||||
directory: localPackage.dir,
|
||||
directory,
|
||||
type: 'directory',
|
||||
},
|
||||
resolvedVia: 'local-filesystem',
|
||||
|
||||
@@ -974,7 +974,7 @@ test('resolve injected dependency from local directory when it matches the lates
|
||||
expect(resolveResult!.id).toBe('file:is-positive')
|
||||
expect(resolveResult!.latest!.split('.').length).toBe(3)
|
||||
expect(resolveResult!.resolution).toStrictEqual({
|
||||
directory: '/home/istvan/src/is-positive',
|
||||
directory: 'is-positive',
|
||||
type: 'directory',
|
||||
})
|
||||
expect(resolveResult!.manifest).toBeTruthy()
|
||||
|
||||
@@ -220,12 +220,6 @@ function toLockfileResolution (
|
||||
): LockfileResolution {
|
||||
/* eslint-disable @typescript-eslint/dot-notation */
|
||||
if (dp.isAbsolute(depPath) || resolution.type !== undefined || !resolution['integrity']) {
|
||||
if (resolution.type === 'directory') {
|
||||
return {
|
||||
type: 'directory',
|
||||
directory: pkg.id.replace(/^file:/, ''),
|
||||
}
|
||||
}
|
||||
return resolution as LockfileResolution
|
||||
}
|
||||
const base = registry !== resolution['registry'] ? { registry: resolution['registry'] } : {}
|
||||
|
||||
Reference in New Issue
Block a user