mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-27 18:46:18 -04:00
fix: warn when directory contains PATH delimiter character (#10487)
* fix: warn when directory contains PATH delimiter character Add a warning when the current directory contains the PATH delimiter character (colon on macOS/Linux, semicolon on Windows). On macOS, folder names containing forward slashes (/) appear as colons (:) at the Unix layer. Since colons are PATH separators in POSIX systems, this breaks PATH injection for node_modules/.bin. close #10457 * test: add tests for PATH delimiter warning - Test warning is emitted when directory contains delimiter - Test no warning for normal directories
This commit is contained in:
8
.changeset/warn-path-delimiter.md
Normal file
8
.changeset/warn-path-delimiter.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/config": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Add a warning when the current directory contains the PATH delimiter character. On macOS, folder names containing forward slashes (/) appear as colons (:) at the Unix layer. Since colons are PATH separators in POSIX systems, this breaks PATH injection for `node_modules/.bin`, causing binaries to not be found when running commands like `pnpm exec`.
|
||||
|
||||
Closes [#10457](https://github.com/pnpm/pnpm/issues/10457).
|
||||
@@ -274,6 +274,12 @@ export async function getConfig (opts: {
|
||||
// This prevents potential inconsistencies in the future, especially when processing or mapping subdirectories.
|
||||
const cwd = fs.realpathSync(betterPathResolve(cliOptions.dir ?? npmConfig.localPrefix))
|
||||
|
||||
// Unfortunately, there is no way to escape the PATH delimiter,
|
||||
// so directories added to PATH should not contain it.
|
||||
if (cwd.includes(path.delimiter)) {
|
||||
warnings.push(`Directory "${cwd}" contains the path delimiter character (${path.delimiter}), so binaries from node_modules/.bin will not be accessible via PATH. Consider renaming the directory.`)
|
||||
}
|
||||
|
||||
pnpmConfig.maxSockets = npmConfig.maxsockets
|
||||
// @ts-expect-error
|
||||
delete pnpmConfig['maxsockets']
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference path="../../../__typings__/index.d.ts"/>
|
||||
import fs from 'fs'
|
||||
import os from 'os'
|
||||
import path from 'path'
|
||||
import PATH from 'path-name'
|
||||
import { sync as writeYamlFile } from 'write-yaml-file'
|
||||
@@ -1361,6 +1362,48 @@ test('CLI should override environment variable pnpm_config_*', async () => {
|
||||
})).toBe(10)
|
||||
})
|
||||
|
||||
test('warn when directory contains PATH delimiter character', async () => {
|
||||
const tempDir = path.join(os.tmpdir(), `pnpm-test${path.delimiter}project-${Date.now()}`)
|
||||
fs.mkdirSync(tempDir, { recursive: true })
|
||||
|
||||
try {
|
||||
const { warnings } = await getConfig({
|
||||
cliOptions: { dir: tempDir },
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
|
||||
expect(warnings).toContainEqual(
|
||||
expect.stringContaining('path delimiter character')
|
||||
)
|
||||
} finally {
|
||||
fs.rmSync(tempDir, { recursive: true })
|
||||
}
|
||||
})
|
||||
|
||||
test('no warning when directory does not contain PATH delimiter character', async () => {
|
||||
const tempDir = path.join(os.tmpdir(), `pnpm-test-normal-${Date.now()}`)
|
||||
fs.mkdirSync(tempDir, { recursive: true })
|
||||
|
||||
try {
|
||||
const { warnings } = await getConfig({
|
||||
cliOptions: { dir: tempDir },
|
||||
packageManager: {
|
||||
name: 'pnpm',
|
||||
version: '1.0.0',
|
||||
},
|
||||
})
|
||||
|
||||
expect(warnings).not.toContainEqual(
|
||||
expect.stringContaining('path delimiter character')
|
||||
)
|
||||
} finally {
|
||||
fs.rmSync(tempDir, { recursive: true })
|
||||
}
|
||||
})
|
||||
|
||||
describe('global config.yaml', () => {
|
||||
let XDG_CONFIG_HOME: string | undefined
|
||||
|
||||
|
||||
Reference in New Issue
Block a user