summaryrefslogtreecommitdiff
path: root/packages/upgrade/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/upgrade/src')
-rw-r--r--packages/upgrade/src/actions/context.ts10
-rw-r--r--packages/upgrade/src/actions/install.ts37
-rw-r--r--packages/upgrade/src/messages.ts4
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;