feat(coding-agent): support renamed self-update package
This commit is contained in:
@@ -28,12 +28,36 @@ export const isBunRuntime = !!process.versions.bun;
|
||||
|
||||
export type InstallMethod = "bun-binary" | "npm" | "pnpm" | "yarn" | "bun" | "unknown";
|
||||
|
||||
export interface SelfUpdateCommand {
|
||||
interface SelfUpdateCommandStep {
|
||||
command: string;
|
||||
args: string[];
|
||||
display: string;
|
||||
}
|
||||
|
||||
export interface SelfUpdateCommand extends SelfUpdateCommandStep {
|
||||
steps?: SelfUpdateCommandStep[];
|
||||
}
|
||||
|
||||
function makeSelfUpdateCommand(
|
||||
installStep: SelfUpdateCommandStep,
|
||||
uninstallStep?: SelfUpdateCommandStep,
|
||||
): SelfUpdateCommand {
|
||||
if (!uninstallStep) return installStep;
|
||||
return {
|
||||
...installStep,
|
||||
display: `${uninstallStep.display} && ${installStep.display}`,
|
||||
steps: [uninstallStep, installStep],
|
||||
};
|
||||
}
|
||||
|
||||
function makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {
|
||||
return {
|
||||
command,
|
||||
args,
|
||||
display: [command, ...args].map((arg) => (/\s/.test(arg) ? `"${arg}"` : arg)).join(" "),
|
||||
};
|
||||
}
|
||||
|
||||
export function detectInstallMethod(): InstallMethod {
|
||||
if (isBunBinary) {
|
||||
return "bun-binary";
|
||||
@@ -83,24 +107,44 @@ function getInferredNpmInstall(packageName: string): { root: string; prefix: str
|
||||
|
||||
function getSelfUpdateCommandForMethod(
|
||||
method: InstallMethod,
|
||||
packageName: string,
|
||||
installedPackageName: string,
|
||||
updatePackageName = installedPackageName,
|
||||
npmCommand?: string[],
|
||||
): SelfUpdateCommand | undefined {
|
||||
switch (method) {
|
||||
case "bun-binary":
|
||||
return undefined;
|
||||
case "pnpm":
|
||||
return { command: "pnpm", args: ["install", "-g", packageName], display: `pnpm install -g ${packageName}` };
|
||||
return makeSelfUpdateCommand(
|
||||
makeSelfUpdateCommandStep("pnpm", ["install", "-g", updatePackageName]),
|
||||
updatePackageName === installedPackageName
|
||||
? undefined
|
||||
: makeSelfUpdateCommandStep("pnpm", ["remove", "-g", installedPackageName]),
|
||||
);
|
||||
case "yarn":
|
||||
return { command: "yarn", args: ["global", "add", packageName], display: `yarn global add ${packageName}` };
|
||||
return makeSelfUpdateCommand(
|
||||
makeSelfUpdateCommandStep("yarn", ["global", "add", updatePackageName]),
|
||||
updatePackageName === installedPackageName
|
||||
? undefined
|
||||
: makeSelfUpdateCommandStep("yarn", ["global", "remove", installedPackageName]),
|
||||
);
|
||||
case "bun":
|
||||
return { command: "bun", args: ["install", "-g", packageName], display: `bun install -g ${packageName}` };
|
||||
return makeSelfUpdateCommand(
|
||||
makeSelfUpdateCommandStep("bun", ["install", "-g", updatePackageName]),
|
||||
updatePackageName === installedPackageName
|
||||
? undefined
|
||||
: makeSelfUpdateCommandStep("bun", ["uninstall", "-g", installedPackageName]),
|
||||
);
|
||||
case "npm": {
|
||||
const [command = "npm", ...npmArgs] = npmCommand ?? [];
|
||||
const inferred = npmCommand?.length ? undefined : getInferredNpmInstall(packageName);
|
||||
const args = [...npmArgs, ...(inferred ? ["--prefix", inferred.prefix] : []), "install", "-g", packageName];
|
||||
const display = [command, ...args].map((arg) => (/\s/.test(arg) ? `"${arg}"` : arg)).join(" ");
|
||||
return { command, args, display };
|
||||
const inferred = npmCommand?.length ? undefined : getInferredNpmInstall(installedPackageName);
|
||||
const prefixArgs = [...npmArgs, ...(inferred ? ["--prefix", inferred.prefix] : [])];
|
||||
const installStep = makeSelfUpdateCommandStep(command, [...prefixArgs, "install", "-g", updatePackageName]);
|
||||
const uninstallStep =
|
||||
updatePackageName === installedPackageName
|
||||
? undefined
|
||||
: makeSelfUpdateCommandStep(command, [...prefixArgs, "uninstall", "-g", installedPackageName]);
|
||||
return makeSelfUpdateCommand(installStep, uninstallStep);
|
||||
}
|
||||
case "unknown":
|
||||
return undefined;
|
||||
@@ -210,28 +254,36 @@ function isManagedByGlobalPackageManager(method: InstallMethod, packageName: str
|
||||
);
|
||||
}
|
||||
|
||||
export function getSelfUpdateCommand(packageName: string, npmCommand?: string[]): SelfUpdateCommand | undefined {
|
||||
export function getSelfUpdateCommand(
|
||||
packageName: string,
|
||||
npmCommand?: string[],
|
||||
updatePackageName = packageName,
|
||||
): SelfUpdateCommand | undefined {
|
||||
const method = detectInstallMethod();
|
||||
const command = getSelfUpdateCommandForMethod(method, packageName, npmCommand);
|
||||
const command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);
|
||||
if (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {
|
||||
return undefined;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
export function getSelfUpdateUnavailableInstruction(packageName: string, npmCommand?: string[]): string {
|
||||
export function getSelfUpdateUnavailableInstruction(
|
||||
packageName: string,
|
||||
npmCommand?: string[],
|
||||
updatePackageName = packageName,
|
||||
): string {
|
||||
const method = detectInstallMethod();
|
||||
if (method === "bun-binary") {
|
||||
return `Download from: https://github.com/badlogic/pi-mono/releases/latest`;
|
||||
}
|
||||
const command = getSelfUpdateCommandForMethod(method, packageName, npmCommand);
|
||||
const command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);
|
||||
if (command) {
|
||||
if (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {
|
||||
return `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;
|
||||
}
|
||||
return `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;
|
||||
}
|
||||
return `Update ${packageName} using the package manager, wrapper, or source checkout that provides this installation.`;
|
||||
return `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;
|
||||
}
|
||||
|
||||
export function getUpdateInstruction(packageName: string): string {
|
||||
|
||||
Reference in New Issue
Block a user