mirror of
https://github.com/pnpm/action-setup.git
synced 2026-04-05 20:20:48 +08:00
fix: fall back to pnpm shim in same directory for self-update bin/
ensureAliasLinks had a hardcoded relative path to @pnpm/exe/pnpm which only works from node_modules/.bin/. In self-update's bin/ directory ($PNPM_HOME/bin/), that path doesn't resolve. Now falls back to using the pnpm shim in the same directory when the package path doesn't exist.
This commit is contained in:
208
dist/index.js
vendored
208
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -125,6 +125,31 @@ describe('ensureAliasLinks', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('self-update bin directory (pnpm shim in same dir)', () => {
|
||||||
|
it('creates aliases using pnpm shim in the same directory on unix', async () => {
|
||||||
|
// self-update creates a pnpm shim in $PNPM_HOME/bin/ — no package dir
|
||||||
|
await writeFile(path.join(binDir, 'pnpm'), '#!/bin/sh\nexec /path/to/real/pnpm "$@"\n', { mode: 0o755 })
|
||||||
|
|
||||||
|
await ensureAliasLinks(binDir, true, 'linux')
|
||||||
|
|
||||||
|
const pnTarget = await readlink(path.join(binDir, 'pn'))
|
||||||
|
expect(pnTarget).toBe('pnpm')
|
||||||
|
|
||||||
|
const pnxContent = await readFile(path.join(binDir, 'pnx'), 'utf8')
|
||||||
|
expect(pnxContent).toContain('pnpm')
|
||||||
|
expect(pnxContent).toContain('dlx')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('creates .cmd shims using pnpm in same dir on windows', async () => {
|
||||||
|
await writeFile(path.join(binDir, 'pnpm'), 'pnpm binary')
|
||||||
|
|
||||||
|
await ensureAliasLinks(binDir, true, 'win32')
|
||||||
|
|
||||||
|
const cmdContent = await readFile(path.join(binDir, 'pn.cmd'), 'utf8')
|
||||||
|
expect(cmdContent).toContain('pnpm')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('overwrites existing broken shims', () => {
|
describe('overwrites existing broken shims', () => {
|
||||||
it('replaces npm broken shim with symlink on unix', async () => {
|
it('replaces npm broken shim with symlink on unix', async () => {
|
||||||
await setupStandaloneFixture(binDir)
|
await setupStandaloneFixture(binDir)
|
||||||
|
|||||||
@@ -24,6 +24,28 @@ async function forceWriteFile (filePath: string, content: string, mode?: number)
|
|||||||
await writeFile(filePath, content, { mode })
|
await writeFile(filePath, content, { mode })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the pnpm binary/shim relative to binDir.
|
||||||
|
* Checks the package directory first (node_modules/.bin/../@pnpm/exe/pnpm),
|
||||||
|
* then falls back to a pnpm shim in binDir itself (e.g. self-update's bin/).
|
||||||
|
*/
|
||||||
|
function findPnpmTarget (binDir: string, standalone: boolean): string | undefined {
|
||||||
|
const packageTarget = standalone
|
||||||
|
? path.join('..', '@pnpm', 'exe', 'pnpm')
|
||||||
|
: path.join('..', 'pnpm', 'bin', 'pnpm.cjs')
|
||||||
|
|
||||||
|
if (existsSync(path.resolve(binDir, packageTarget))) {
|
||||||
|
return packageTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
// self-update creates a pnpm shim in $PNPM_HOME/bin/ — use it directly
|
||||||
|
if (existsSync(path.join(binDir, 'pnpm'))) {
|
||||||
|
return 'pnpm'
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create pn/pnpx/pnx alias links in the bin directory.
|
* Create pn/pnpx/pnx alias links in the bin directory.
|
||||||
*
|
*
|
||||||
@@ -34,20 +56,12 @@ async function forceWriteFile (filePath: string, content: string, mode?: number)
|
|||||||
* pnpm self-update only replaces the pnpm binary — it doesn't update other
|
* pnpm self-update only replaces the pnpm binary — it doesn't update other
|
||||||
* files in the package. The aliases are created by pointing pn directly to
|
* files in the package. The aliases are created by pointing pn directly to
|
||||||
* the pnpm binary, and pnpx/pnx as scripts that exec "pnpm dlx".
|
* the pnpm binary, and pnpx/pnx as scripts that exec "pnpm dlx".
|
||||||
*
|
|
||||||
* Only creates links when the pnpm binary exists in the expected location
|
|
||||||
* (i.e. the package has been installed). This is always true after bootstrap.
|
|
||||||
*/
|
*/
|
||||||
export async function ensureAliasLinks (binDir: string, standalone: boolean, platform: NodeJS.Platform = process.platform): Promise<void> {
|
export async function ensureAliasLinks (binDir: string, standalone: boolean, platform: NodeJS.Platform = process.platform): Promise<void> {
|
||||||
const isWindows = platform === 'win32'
|
const isWindows = platform === 'win32'
|
||||||
|
|
||||||
// Determine the pnpm binary path relative to binDir
|
const pnpmTarget = findPnpmTarget(binDir, standalone)
|
||||||
const pnpmTarget = standalone
|
if (!pnpmTarget) return
|
||||||
? path.join('..', '@pnpm', 'exe', 'pnpm')
|
|
||||||
: path.join('..', 'pnpm', 'bin', 'pnpm.cjs')
|
|
||||||
|
|
||||||
const resolvedPnpm = path.resolve(binDir, pnpmTarget)
|
|
||||||
if (!existsSync(resolvedPnpm)) return
|
|
||||||
|
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
// pn → calls pnpm directly
|
// pn → calls pnpm directly
|
||||||
|
|||||||
Reference in New Issue
Block a user