mirror of
https://github.com/pnpm/pnpm.git
synced 2025-12-31 19:18:19 -05:00
fix: resolve real path for case insensitive systems (#4935)
close #4904
This commit is contained in:
6
.changeset/quiet-icons-wait.md
Normal file
6
.changeset/quiet-icons-wait.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/find-workspace-dir": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Resolve native workspace path for case-insensitive file systems [#4904](https://github.com/pnpm/pnpm/issues/4904).
|
||||
@@ -1,3 +1,4 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import PnpmError from '@pnpm/error'
|
||||
import findUp from 'find-up'
|
||||
@@ -9,9 +10,21 @@ export default async function findWorkspaceDir (cwd: string) {
|
||||
const workspaceManifestDirEnvVar = process.env[WORKSPACE_DIR_ENV_VAR] ?? process.env[WORKSPACE_DIR_ENV_VAR.toLowerCase()]
|
||||
const workspaceManifestLocation = workspaceManifestDirEnvVar
|
||||
? path.join(workspaceManifestDirEnvVar, 'pnpm-workspace.yaml')
|
||||
: await findUp([WORKSPACE_MANIFEST_FILENAME, 'pnpm-workspace.yml'], { cwd })
|
||||
: await findUp([WORKSPACE_MANIFEST_FILENAME, 'pnpm-workspace.yml'], { cwd: await getRealPath(cwd) })
|
||||
if (workspaceManifestLocation?.endsWith('.yml')) {
|
||||
throw new PnpmError('BAD_WORKSPACE_MANIFEST_NAME', `The workspace manifest file should be named "pnpm-workspace.yaml". File found: ${workspaceManifestLocation}`)
|
||||
}
|
||||
return workspaceManifestLocation && path.dirname(workspaceManifestLocation)
|
||||
}
|
||||
|
||||
async function getRealPath (path: string) {
|
||||
return new Promise<string>((resolve) => {
|
||||
// We need to resolve the real native path for case-insensitive file systems.
|
||||
// For example, we can access file as C:\Code\Project as well as c:\code\projects
|
||||
// Without this we can face a problem when try to install packages with -w flag,
|
||||
// when root dir is using c:\code\projects but packages were found by C:\Code\Project
|
||||
fs.realpath.native(path, function (err, resolvedPath) {
|
||||
resolve(err !== null ? path : resolvedPath)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,16 +1,36 @@
|
||||
/// <reference path="../../../typings/index.d.ts"/>
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import findWorkspaceDir from '@pnpm/find-workspace-dir'
|
||||
|
||||
const NPM_CONFIG_WORKSPACE_DIR_ENV_VAR = 'NPM_CONFIG_WORKSPACE_DIR'
|
||||
const FAKE_PATH = 'FAKE_PATH'
|
||||
|
||||
function isFileSystemCaseSensitive () {
|
||||
try {
|
||||
fs.realpathSync.native(process.cwd().toUpperCase())
|
||||
return false
|
||||
} catch (_) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need to validate case-sensitive systems
|
||||
// because it is not possible to reach process.cwd() with wrong case there.
|
||||
const testOnCaseInSensitiveSystems = isFileSystemCaseSensitive() ? test.skip : test
|
||||
|
||||
test('finds actual workspace dir', async () => {
|
||||
const workspaceDir = await findWorkspaceDir(process.cwd())
|
||||
|
||||
expect(workspaceDir).toBe(path.resolve(__dirname, '..', '..', '..'))
|
||||
})
|
||||
|
||||
testOnCaseInSensitiveSystems('finds workspace dir with wrong case from cwd', async () => {
|
||||
const workspaceDir = await findWorkspaceDir(process.cwd().toUpperCase())
|
||||
|
||||
expect(workspaceDir).toBe(path.resolve(__dirname, '..', '..', '..'))
|
||||
})
|
||||
|
||||
test('finds overriden workspace dir', async () => {
|
||||
const oldValue = process.env[NPM_CONFIG_WORKSPACE_DIR_ENV_VAR]
|
||||
process.env[NPM_CONFIG_WORKSPACE_DIR_ENV_VAR] = FAKE_PATH
|
||||
|
||||
Reference in New Issue
Block a user