|
1 | 1 | import {AbortError, BugError} from './error.js' |
2 | 2 | import {AbortController, AbortSignal} from './abort.js' |
3 | 3 | import {exec} from './system.js' |
4 | | -import {fileExists, readFile, writeFile, findPathUp, glob} from './fs.js' |
| 4 | +import {fileExists, readFile, writeFile, findPathUp, glob, fileExistsSync} from './fs.js' |
5 | 5 | import {dirname, joinPath} from './path.js' |
6 | 6 | import {runWithTimer} from './metadata.js' |
7 | 7 | import {inferPackageManagerForGlobalCLI} from './is-global.js' |
@@ -111,21 +111,29 @@ export function packageManagerFromUserAgent(env = process.env): PackageManager { |
111 | 111 |
|
112 | 112 | /** |
113 | 113 | * Returns the dependency manager used in a directory. |
| 114 | + * Walks upward from `fromDirectory` so workspace packages (e.g. `extensions/my-fn/package.json`) |
| 115 | + * still resolve to the repo root lockfile (`pnpm-lock.yaml`). |
| 116 | + * If no lockfile is found, it falls back to the package manager from the user agent. |
| 117 | + * If the package manager from the user agent is unknown, it returns 'npm'. |
114 | 118 | * @param fromDirectory - The starting directory |
115 | 119 | * @returns The dependency manager |
116 | 120 | */ |
117 | 121 | export async function getPackageManager(fromDirectory: string): Promise<PackageManager> { |
118 | | - const packageJsonPath = await findPathUp('package.json', {cwd: fromDirectory, type: 'file'}) |
119 | | - if (!packageJsonPath) { |
120 | | - return packageManagerFromUserAgent() |
| 122 | + let current = fromDirectory |
| 123 | + outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`) |
| 124 | + while (true) { |
| 125 | + if (fileExistsSync(joinPath(current, yarnLockfile))) return 'yarn' |
| 126 | + if (fileExistsSync(joinPath(current, pnpmLockfile))) return 'pnpm' |
| 127 | + if (fileExistsSync(joinPath(current, bunLockfile))) return 'bun' |
| 128 | + if (fileExistsSync(joinPath(current, npmLockfile))) return 'npm' |
| 129 | + const parent = dirname(current) |
| 130 | + if (parent === current) break |
| 131 | + current = parent |
121 | 132 | } |
122 | 133 |
|
123 | | - const directory = dirname(packageJsonPath) |
124 | | - outputDebug(outputContent`Obtaining the dependency manager in directory ${outputToken.path(directory)}...`) |
| 134 | + const pm: PackageManager = packageManagerFromUserAgent() |
| 135 | + if (pm !== 'unknown') return pm |
125 | 136 |
|
126 | | - if (await fileExists(joinPath(directory, yarnLockfile))) return 'yarn' |
127 | | - if (await fileExists(joinPath(directory, pnpmLockfile))) return 'pnpm' |
128 | | - if (await fileExists(joinPath(directory, bunLockfile))) return 'bun' |
129 | 137 | return 'npm' |
130 | 138 | } |
131 | 139 |
|
|
0 commit comments