Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add logger and spinner and some cleanup
  • Loading branch information
c4spar committed May 16, 2024
commit a81265b5d0cb2e182ad6d624621064cc275953e9
37 changes: 37 additions & 0 deletions command/upgrade/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Spinner } from "@std/cli/spinner";

export interface Logger {
log(...data: Array<unknown>): void;

info(...data: Array<unknown>): void;

error(...data: Array<unknown>): void;
}

export interface LoggerOptions {
spinner: Spinner;
verbose?: boolean;
}

export function createLogger({ spinner, verbose }: LoggerOptions): Logger {
function write(
type: "log" | "info" | "error",
...args: Array<unknown>
): void {
spinner && spinner.stop();
console[type](...args);
spinner && spinner.start();
}

return {
log: (...args: Array<unknown>): void => {
verbose && write("log", ...args);
},
info: (...args: Array<unknown>): void => {
write("info", ...args);
},
error: (...args: Array<unknown>): void => {
write("error", ...args);
},
};
}
3 changes: 3 additions & 0 deletions command/upgrade/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Logger } from "./logger.ts";
import type { Provider } from "./provider.ts";

/** Runtime specific upgrade options. */
Expand All @@ -11,6 +12,8 @@ export interface UpgradePackageOptions extends RuntimeUpgradeOptions {
name: string;
version: string;
provider: Provider;
verbose?: boolean;
logger?: Logger;
}

/** Runtime handler. */
Expand Down
32 changes: 18 additions & 14 deletions command/upgrade/runtime/bun_runtime.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import { dim } from "@std/fmt/colors";
import type { Logger } from "../logger.ts";
import { NodeRuntime } from "./node_runtime.ts";

// deno-lint-ignore no-explicit-any
const Bun = (globalThis as any).Bun;
// deno-lint-ignore no-explicit-any
const process = (globalThis as any).process;

export class BunRuntime extends NodeRuntime {
protected async execute(
cmdArgs: string[],
isJsr: boolean,
logger?: Logger,
): Promise<string | null> {
const proc = isJsr
? Bun.spawn([`${process.execPath}x`, "jsr", ...cmdArgs], {
stdout: "piped",
stderr: "piped",
})
: Bun.spawn([process.execPath, ...cmdArgs], {
stdout: "piped",
stderr: "piped",
});
// deno-lint-ignore no-explicit-any
const Bun = (globalThis as any).Bun;
// deno-lint-ignore no-explicit-any
const process = (globalThis as any).process;

cmdArgs = isJsr
? [`${process.execPath}x`, "jsr", ...cmdArgs]
: [process.execPath, ...cmdArgs];

logger?.log(
dim("$ %s %s"),
Deno.execPath(),
cmdArgs.join(" "),
);

const proc = Bun.spawn(cmdArgs, { stdout: "piped", stderr: "piped" });
await proc.exited;

if (proc.exitCode) {
Expand Down
42 changes: 25 additions & 17 deletions command/upgrade/runtime/deno_runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { dim } from "@std/fmt/colors";
import { Runtime, type UpgradePackageOptions } from "../runtime.ts";
import type { Logger } from "../logger.ts";

/** Deno specific upgrade options. */
export interface DenoUpgradeOptions {
Expand All @@ -13,35 +15,41 @@ export type DenoUpgradePackageOptions =
/** Deno runtime upgrade handler. */
export class DenoRuntime extends Runtime {
upgrade(
{ provider, name, main, version, importMap, args = [] }:
{ provider, name, main, version, importMap, verbose, logger, args = [] }:
DenoUpgradePackageOptions,
): Promise<string | null> {
const specifier: string = provider.getSpecifier(name, version, main);

const cmdArgs = ["install", "--global"];
const cmdArgs = ["install", `--name=${name}`, "--global", "--force"];

if (importMap) {
const importJson: string = new URL(importMap, specifier).href;
cmdArgs.push("--import-map", importJson);
if (!verbose) {
cmdArgs.push("--quiet");
}

if (args.length) {
cmdArgs.push(...args, "--force", "--name", name, specifier);
} else {
cmdArgs.push(
"--no-check",
"--quiet",
"--force",
"--name",
name,
specifier,
);
cmdArgs.push(...args);
}

return this.execute(cmdArgs);
if (importMap) {
const importJson: string = new URL(importMap, specifier).href;
cmdArgs.push(`--import-map=${importJson}`);
}

cmdArgs.push(specifier);

return this.execute(cmdArgs, logger);
}

protected async execute(cmdArgs: string[]): Promise<string | null> {
protected async execute(
cmdArgs: string[],
logger?: Logger,
): Promise<string | null> {
logger?.log(
dim("$ %s %s"),
Deno.execPath(),
cmdArgs.join(" "),
);

const cmd = new Deno.Command(Deno.execPath(), {
args: cmdArgs,
stdout: "piped",
Expand Down
42 changes: 32 additions & 10 deletions command/upgrade/runtime/node_runtime.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
import { Runtime, UpgradePackageOptions } from "../runtime.ts";
import { dim } from "@std/fmt/colors";
import type { Logger } from "../logger.ts";
import type { Runtime, UpgradePackageOptions } from "../runtime.ts";

export class NodeRuntime implements Runtime {
upgrade(
{ provider, name, main, version, args = [] }: UpgradePackageOptions,
{
provider,
name,
main,
version,
verbose,
logger,
args = [],
}: UpgradePackageOptions,
): Promise<string | null> {
const specifier = provider.getSpecifier(name, version, main)
.replace(/^(npm|jsr):/, "");
const isJsr = provider.name === "jsr";

const cmdArgs = ["install", "--global"];
const cmdArgs = ["install", "--global", "--force"];

if (!verbose) {
cmdArgs.push("--silent");
}

if (args.length) {
cmdArgs.push(...args, "--force", specifier);
} else {
cmdArgs.push("--silent", "--force", specifier);
cmdArgs.push(...args);
}

return this.execute(cmdArgs, isJsr);
cmdArgs.push(specifier);

return this.execute(cmdArgs, isJsr, logger);
}

protected async execute(
cmdArgs: string[],
isJsr: boolean,
logger?: Logger,
): Promise<string | null> {
const { spawn } = await import("node:child_process");

const [bin, args] = isJsr ? ["npx", ["jsr", ...cmdArgs]] : ["npm", cmdArgs];

logger?.log(
dim("$ %s %s %s"),
Deno.execPath(),
bin,
args.join(" "),
);

const proc = spawn(bin, args, { stdio: [null, "pipe", "pipe"] });
const stderr: Array<string> = [];
const proc = isJsr
? spawn("npx", ["jsr", ...cmdArgs], { stdio: [null, "pipe", "pipe"] })
: spawn("npm", cmdArgs, { stdio: [null, "pipe", "pipe"] });

proc.stderr?.on("data", (data: string) => stderr.push(data.toString()));

Expand Down
32 changes: 24 additions & 8 deletions command/upgrade/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { bold, dim, green, red } from "@std/fmt/colors";
import { getRuntime } from "./get_runtime.ts";
import type {
RuntimeUpgradeOptions,
UpgradePackageOptions,
} from "./runtime.ts";
import { DenoUpgradeOptions } from "./runtime/deno_runtime.ts";
import type { DenoUpgradeOptions } from "./runtime/deno_runtime.ts";

type DenoRuntimeUpgradeOptions = RuntimeUpgradeOptions & DenoUpgradeOptions;
type NodeRuntimeUpgradeOptions = RuntimeUpgradeOptions;
Expand Down Expand Up @@ -37,6 +38,8 @@ export async function upgrade(
version,
currentVersion,
force,
logger,
verbose,
}: UpgradeOptions,
): Promise<void> {
if (
Expand All @@ -45,10 +48,14 @@ export async function upgrade(
await provider.isOutdated(name, currentVersion, version)
) {
if (version === "latest") {
logger?.log(dim("Upgrading %s to the %s version"), name, version);
const { latest } = await provider.getVersions(name);
version = latest;
} else {
logger?.log(dim("Upgrading %s to version %s"), name, version);
}
const { runtimeName, runtime } = await getRuntime();
logger?.log(dim("Detected runtime: %s"), runtimeName);

const errorMessage: string | null = await runtime.upgrade({
args,
Expand All @@ -57,20 +64,29 @@ export async function upgrade(
version,
main,
provider,
logger,
verbose,
});

if (errorMessage) {
console.error(errorMessage);
console.error(
`Failed to upgrade ${name} from ${currentVersion} to version ${version}!`,
logger?.error(
red(
`Failed to upgrade ${bold(name)} ${
currentVersion ? `from version ${bold(currentVersion)} ` : ""
}to ${bold(version)}:`,
),
);
logger?.error(errorMessage);
Deno.exit(1);
}

console.info(
`Successfully upgraded ${name} from ${currentVersion} to version ${version}! (${
provider.getRegistryUrl(name, version)
})`,
logger?.info(
green(
`Successfully upgraded ${bold(name)} from version ${
bold(currentVersion ?? "")
} to ${bold(version)}!`,
),
dim(`(${provider.getRegistryUrl(name, version)})`),
);
}
}
40 changes: 31 additions & 9 deletions command/upgrade/upgrade_command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Spinner } from "@std/cli/spinner";
import { bold, brightBlue } from "@std/fmt/colors";
import { ValidationError } from "../_errors.ts";
import { Command } from "../command.ts";
import { EnumType } from "../types/enum.ts";
import { createLogger } from "./logger.ts";
import type { Provider, Versions } from "./provider.ts";
import type { RuntimeUpgradeOptions } from "./runtime.ts";
import { type RuntimeOptionsMap, upgrade } from "./upgrade.ts";
Expand All @@ -9,7 +12,6 @@ export interface UpgradeCommandOptions<
TProvider extends Provider = Provider,
> extends RuntimeUpgradeOptions {
provider: TProvider | Array<TProvider>;
main?: string;
runtime?: RuntimeOptionsMap;
}

Expand Down Expand Up @@ -65,19 +67,39 @@ export class UpgradeCommand extends Command {
"-f, --force",
"Replace current installation even if not out-of-date.",
)
.option(
"-v, --verbose",
"Log verbose output.",
)
.complete("version", () => this.getAllVersions())
.action(async ({ registry: provider, version, force }) => {
.action(async ({ registry: provider, version, force, verbose }) => {
const name: string = this.getMainCommand().getName();
const currentVersion: string | undefined = this.getVersion();

await upgrade({
name,
version,
currentVersion,
force,
provider,
...options,
const spinner = new Spinner({
message: brightBlue(
`Upgrading ${bold(name)} from version ${
bold(currentVersion ?? "")
} to ${bold(version)}...`,
),
});
const logger = createLogger({ spinner, verbose });
spinner.start();

try {
await upgrade({
name,
version,
currentVersion,
force,
provider,
verbose,
logger,
...options,
});
} finally {
spinner.stop();
}
});
}

Expand Down