diff options
Diffstat (limited to 'packages/upgrade/src')
-rw-r--r-- | packages/upgrade/src/actions/context.ts | 10 | ||||
-rw-r--r-- | packages/upgrade/src/actions/install.ts | 37 | ||||
-rw-r--r-- | packages/upgrade/src/messages.ts | 4 |
3 files changed, 31 insertions, 20 deletions
diff --git a/packages/upgrade/src/actions/context.ts b/packages/upgrade/src/actions/context.ts index 2103a5327..1588eb509 100644 --- a/packages/upgrade/src/actions/context.ts +++ b/packages/upgrade/src/actions/context.ts @@ -1,7 +1,7 @@ import { pathToFileURL } from 'node:url'; import { prompt } from '@astrojs/cli-kit'; import arg from 'arg'; -import detectPackageManager from 'preferred-pm'; +import { type DetectResult, detect } from 'package-manager-detector'; export interface Context { help: boolean; @@ -11,7 +11,7 @@ export interface Context { cwd: URL; stdin?: typeof process.stdin; stdout?: typeof process.stdout; - packageManager: string; + packageManager: DetectResult; packages: PackageInfo[]; exit(code: number): never; } @@ -38,7 +38,11 @@ export async function getContext(argv: string[]): Promise<Context> { { argv, permissive: true }, ); - const packageManager = (await detectPackageManager(process.cwd()))?.name ?? 'npm'; + const packageManager = (await detect({ + // Include the `install-metadata` strategy to have the package manager that's + // used for installation take precedence + strategies: ['install-metadata', 'lockfile', 'packageManager-field'], + })) ?? { agent: 'npm', name: 'npm' }; const { _: [version = 'latest'] = [], '--help': help = false, diff --git a/packages/upgrade/src/actions/install.ts b/packages/upgrade/src/actions/install.ts index ac62b1598..83f25833a 100644 --- a/packages/upgrade/src/actions/install.ts +++ b/packages/upgrade/src/actions/install.ts @@ -5,6 +5,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { color, say } from '@astrojs/cli-kit'; import { random, sleep } from '@astrojs/cli-kit/utils'; +import { resolveCommand } from 'package-manager-detector'; import { banner, bye, @@ -121,21 +122,26 @@ async function runInstallCommand( devDependencies: PackageInfo[], ) { const cwd = fileURLToPath(ctx.cwd); - if (ctx.packageManager === 'yarn') await ensureYarnLock({ cwd }); + if (ctx.packageManager.name === 'yarn') await ensureYarnLock({ cwd }); - const installCmd = - ctx.packageManager === 'yarn' || ctx.packageManager === 'pnpm' ? 'add' : 'install'; + const installCommand = resolveCommand(ctx.packageManager.agent, 'add', []); + if (!installCommand) { + // NOTE: Usually it's impossible to reach here as `package-manager-detector` should + // already match a supported agent + error('error', `Unable to find install command for ${ctx.packageManager.name}.`); + return ctx.exit(1); + } await spinner({ - start: `Installing dependencies with ${ctx.packageManager}...`, + start: `Installing dependencies with ${ctx.packageManager.name}...`, end: `Installed dependencies!`, while: async () => { try { if (dependencies.length > 0) { await shell( - ctx.packageManager, + installCommand.command, [ - installCmd, + ...installCommand.args, ...dependencies.map( ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}`, ), @@ -145,10 +151,9 @@ async function runInstallCommand( } if (devDependencies.length > 0) { await shell( - ctx.packageManager, + installCommand.command, [ - installCmd, - '--save-dev', + ...installCommand.args, ...devDependencies.map( ({ name, targetVersion }) => `${name}@${targetVersion.replace(/^\^/, '')}`, ), @@ -157,15 +162,17 @@ async function runInstallCommand( ); } } catch { - const packages = [...dependencies, ...devDependencies] - .map(({ name, targetVersion }) => `${name}@${targetVersion}`) - .join(' '); + const manualInstallCommand = [ + installCommand.command, + ...installCommand.args, + ...[...dependencies, ...devDependencies].map( + ({ name, targetVersion }) => `${name}@${targetVersion}`, + ), + ].join(' '); newline(); error( 'error', - `Dependencies failed to install, please run the following command manually:\n${color.bold( - `${ctx.packageManager} ${installCmd} ${packages}`, - )}`, + `Dependencies failed to install, please run the following command manually:\n${color.bold(manualInstallCommand)}`, ); return ctx.exit(1); } diff --git a/packages/upgrade/src/messages.ts b/packages/upgrade/src/messages.ts index 032faa1ac..fb70215ee 100644 --- a/packages/upgrade/src/messages.ts +++ b/packages/upgrade/src/messages.ts @@ -1,7 +1,7 @@ /* eslint no-console: 'off' */ import { color, label, spinner as load } from '@astrojs/cli-kit'; import { align } from '@astrojs/cli-kit/utils'; -import detectPackageManager from 'preferred-pm'; +import { detect } from 'package-manager-detector'; import terminalLink from 'terminal-link'; import type { PackageInfo } from './actions/context.js'; import { shell } from './shell.js'; @@ -14,7 +14,7 @@ let _registry: string; export async function getRegistry(): Promise<string> { if (_registry) return _registry; const fallback = 'https://registry.npmjs.org'; - const packageManager = (await detectPackageManager(process.cwd()))?.name || 'npm'; + const packageManager = (await detect())?.name || 'npm'; try { const { stdout } = await shell(packageManager, ['config', 'get', 'registry']); _registry = stdout?.trim()?.replace(/\/$/, '') || fallback; |