|
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,22 +111,26 @@ 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`), not `npm` when only the root has the lock. |
114 | 116 | * @param fromDirectory - The starting directory |
115 | 117 | * @returns The dependency manager |
116 | 118 | */ |
117 | 119 | 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() |
| 120 | + let current = fromDirectory |
| 121 | + outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`) |
| 122 | + while (true) { |
| 123 | + outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`) |
| 124 | + if (fileExistsSync(joinPath(current, yarnLockfile))) return 'yarn' |
| 125 | + if (fileExistsSync(joinPath(current, pnpmLockfile))) return 'pnpm' |
| 126 | + if (fileExistsSync(joinPath(current, bunLockfile))) return 'bun' |
| 127 | + if (fileExistsSync(joinPath(current, npmLockfile))) return 'npm' |
| 128 | + const parent = dirname(current) |
| 129 | + if (parent === current) break |
| 130 | + current = parent |
121 | 131 | } |
122 | 132 |
|
123 | | - const directory = dirname(packageJsonPath) |
124 | | - outputDebug(outputContent`Obtaining the dependency manager in directory ${outputToken.path(directory)}...`) |
125 | | - |
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 | | - return 'npm' |
| 133 | + return packageManagerFromUserAgent() |
130 | 134 | } |
131 | 135 |
|
132 | 136 | interface InstallNPMDependenciesRecursivelyOptions { |
|
0 commit comments