Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use template literals for log output #123

Merged
merged 2 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
30 changes: 4 additions & 26 deletions src/bin/nodecg.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@
#!/usr/bin/env node

import { execSync } from "node:child_process";
import { execFileSync } from "node:child_process";

import chalk from "chalk";

const REQUIRED_VERSION = "v0.11.22";

if (typeof execSync !== "function") {
console.error(
"nodecg-cli relies on %s, which was added to Node.js in %s (your version: %s).",
chalk.cyan("execSync"),
chalk.magenta(REQUIRED_VERSION),
chalk.magenta(process.version),
);
console.error("Please upgrade your Node.js installation.");
process.exit(1);
}

try {
execSync("git --version", { stdio: ["pipe", "pipe", "pipe"] });
} catch (_) {
console.error(
"nodecg-cli requires that %s be available in your PATH.",
chalk.cyan("git"),
);
console.error(
"If you do not have %s installed, you can get it from http://git-scm.com/",
chalk.cyan("git"),
);
execFileSync("git", ["--version"]);
} catch {
console.error(
"By default, the installer will add %s to your PATH.",
chalk.cyan("git"),
`nodecg-cli requires that ${chalk.cyan("git")} be available in your PATH.`,
);
process.exit(1);
}
Expand Down
19 changes: 7 additions & 12 deletions src/commands/defaultconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function action(bundleName?: string) {
bundleName = bundleName ?? path.basename(cwd);
} else {
console.error(
chalk.red("Error:") + " No bundle found in the current directory!",
`${chalk.red("Error:")} No bundle found in the current directory!`,
);
return;
}
Expand All @@ -41,17 +41,13 @@ function action(bundleName?: string) {
const cfgPath = path.join(nodecgPath, "cfg/");

if (!fs.existsSync(bundlePath)) {
console.error(
chalk.red("Error:") + " Bundle %s does not exist",
bundleName,
);
console.error(`${chalk.red("Error:")} Bundle ${bundleName} does not exist`);
return;
}

if (!fs.existsSync(schemaPath)) {
console.error(
chalk.red("Error:") + " Bundle %s does not have a configschema.json",
bundleName,
`${chalk.red("Error:")} Bundle ${bundleName} does not have a configschema.json`,
);
return;
}
Expand All @@ -63,11 +59,10 @@ function action(bundleName?: string) {
const schema: JSONSchemaType<unknown> = JSON.parse(
fs.readFileSync(schemaPath, "utf8"),
);
const configPath = path.join(nodecgPath, "cfg/", bundleName + ".json");
const configPath = path.join(nodecgPath, "cfg/", `${bundleName}.json`);
if (fs.existsSync(configPath)) {
console.error(
chalk.red("Error:") + " Bundle %s already has a config file",
bundleName,
`${chalk.red("Error:")} Bundle ${bundleName} already has a config file`,
);
} else {
try {
Expand All @@ -79,8 +74,8 @@ function action(bundleName?: string) {
console.log(
`${chalk.green("Success:")} Created ${chalk.bold(bundleName)}'s default config from schema\n`,
);
} catch (e) {
console.error(chalk.red("Error: ") + String(e));
} catch (error) {
console.error(chalk.red("Error:"), error);
}
}
}
5 changes: 1 addition & 4 deletions src/commands/schema-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,7 @@ function action(inDir: string, cmd: { outDir: string; configSchema: boolean }) {
const processCwd = process.cwd();
const schemasDir = path.resolve(processCwd, inDir || "schemas");
if (!fs.existsSync(schemasDir)) {
console.error(
chalk.red("Error:") + ' Input directory ("%s") does not exist',
inDir,
);
console.error(`${chalk.red("Error:")} Input directory does not exist`);
return;
}

Expand Down
11 changes: 3 additions & 8 deletions src/commands/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ async function decideActionVersion(

if (isUpdate) {
const verb = downgrade ? "downgraded" : "upgraded";
console.log("NodeCG %s to", verb, chalk.magenta(target));
console.log(`NodeCG ${verb} to ${chalk.magenta(target)}`);
} else {
console.log(`NodeCG (${target}) installed to ${process.cwd()}`);
}
Expand Down Expand Up @@ -282,13 +282,8 @@ function logDownOrUpgradeMessage(
target: string,
downgrade: boolean,
): void {
const Verb = downgrade ? "Downgrading" : "Upgrading";
const verb = downgrade ? "Downgrading" : "Upgrading";
process.stdout.write(
Verb +
" from " +
chalk.magenta(current) +
" to " +
chalk.magenta(target) +
"... ",
`${verb} from ${chalk.magenta(current)} to ${chalk.magenta(target)}... `,
);
}
5 changes: 2 additions & 3 deletions src/commands/uninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ function action(bundleName: string, options: { force: boolean }) {

if (!fs.existsSync(bundlePath)) {
console.error(
"Cannot uninstall %s: bundle is not installed.",
chalk.magenta(bundleName),
`Cannot uninstall ${chalk.magenta(bundleName)}: bundle is not installed.`,
);
return;
}
Expand All @@ -48,7 +47,7 @@ function deleteBundle(name: string, path: string) {
return;
}

process.stdout.write("Uninstalling " + chalk.magenta(name) + "... ");
process.stdout.write(`Uninstalling ${chalk.magenta(name)}... `);
try {
fs.rmSync(path, { recursive: true, force: true });
} catch (e: any) {
Expand Down
9 changes: 2 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@ getLatestCLIRelease()
.then((release) => {
if (semver.gt(release.version, packageVersion)) {
console.log(
chalk.yellow("?") +
" A new update is available for nodecg-cli: " +
chalk.green.bold(release.version) +
chalk.dim(" (current: " + packageVersion + ")"),
`${chalk.yellow("?")} A new update is available for nodecg-cli: ${chalk.green.bold(release.version)} ${chalk.dim(`(current: ${packageVersion})`)}`,
);
console.log(
" Run " +
chalk.cyan.bold("npm install -g nodecg-cli") +
" to install the latest version",
` Run ${chalk.cyan.bold("npm install -g nodecg-cli")} to install the latest version`,
);
}
})
Expand Down
24 changes: 9 additions & 15 deletions src/lib/install-bundle-deps.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { execSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import { format } from "node:util";
import path from "node:path";

import chalk from "chalk";

Expand All @@ -15,32 +15,26 @@ import { isBundleFolder } from "./util.js";
export function installBundleDeps(bundlePath: string, installDev = false) {
if (!isBundleFolder(bundlePath)) {
console.error(
chalk.red("Error:") +
" There doesn't seem to be a valid NodeCG bundle in this folder:" +
"\n\t" +
chalk.magenta(bundlePath),
`${chalk.red("Error:")} There doesn't seem to be a valid NodeCG bundle in this folder:\n\t${chalk.magenta(bundlePath)}`,
);
process.exit(1);
}

let cmdline;

const cachedCwd = process.cwd();
if (fs.existsSync(bundlePath + "/package.json")) {
if (fs.existsSync(path.join(bundlePath, "package.json"))) {
process.chdir(bundlePath);
let cmdline: string;
if (fs.existsSync(bundlePath + "/yarn.lock")) {
if (fs.existsSync(path.join(bundlePath, "yarn.lock"))) {
cmdline = installDev ? "yarn" : "yarn --production";
process.stdout.write(
format(
"Installing npm dependencies with yarn (dev: %s)... ",
installDev,
),
`Installling npm dependencies with yarn (dev: ${installDev})... `,
);
} else {
cmdline = installDev ? "npm install" : "npm install --production";
process.stdout.write(
format("Installing npm dependencies (dev: %s)... ", installDev),
`Installing npm dependencies (dev: ${installDev})... `,
);
}

Expand All @@ -62,10 +56,10 @@ export function installBundleDeps(bundlePath: string, installDev = false) {
process.chdir(cachedCwd);
}

if (fs.existsSync(bundlePath + "/bower.json")) {
cmdline = format("bower install %s", installDev ? "" : "--production");
if (fs.existsSync(path.join(bundlePath, "bower.json"))) {
cmdline = installDev ? "bower install" : "bower install --production";
process.stdout.write(
format("Installing bower dependencies (dev: %s)... ", installDev),
`Installing bower dependencies (dev: ${installDev})... `,
);
try {
execSync(cmdline, {
Expand Down
32 changes: 24 additions & 8 deletions test/commands/defaultconfig.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,25 @@ describe("when run with a bundle argument", () => {
{ recursive: true },
);
await program.runWith("defaultconfig missing-schema-bundle");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"Error: Bundle %s does not have a configschema.json"`,
expect(spy.mock.calls[0]).toMatchInlineSnapshot(
`
[
"Error: Bundle missing-schema-bundle does not have a configschema.json",
]
`,
);
spy.mockRestore();
});

it("should print an error when the target bundle does not exist", async () => {
const spy = vi.spyOn(console, "error");
await program.runWith("defaultconfig not-installed");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"Error: Bundle %s does not exist"`,
expect(spy.mock.calls[0]).toMatchInlineSnapshot(
`
[
"Error: Bundle not-installed does not exist",
]
`,
);
spy.mockRestore();
});
Expand All @@ -68,8 +76,12 @@ describe("when run with a bundle argument", () => {
JSON.stringify({ fake: "data" }),
);
await program.runWith("defaultconfig config-schema");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"Error: Bundle %s already has a config file"`,
expect(spy.mock.calls[0]).toMatchInlineSnapshot(
`
[
"Error: Bundle config-schema already has a config file",
]
`,
);
spy.mockRestore();
});
Expand All @@ -90,8 +102,12 @@ describe("when run with no arguments", () => {

const spy = vi.spyOn(console, "error");
await program.runWith("defaultconfig");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"Error: No bundle found in the current directory!"`,
expect(spy.mock.calls[0]).toMatchInlineSnapshot(
`
[
"Error: No bundle found in the current directory!",
]
`,
);
spy.mockRestore();
});
Expand Down
8 changes: 6 additions & 2 deletions test/commands/schema-types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ it("should print an error when the target bundle does not have a schemas dir", a
process.chdir("bundles/uninstall-test");
const spy = vi.spyOn(console, "error");
await program.runWith("schema-types");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"Error: Input directory ("%s") does not exist"`,
expect(spy.mock.calls[0]).toMatchInlineSnapshot(
`
[
"Error: Input directory does not exist",
]
`,
);
spy.mockRestore();
});
Expand Down
8 changes: 5 additions & 3 deletions test/commands/setup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ test("should correctly handle and refuse when you try to downgrade from v2 to v1
test("should print an error when the target version doesn't exist", async () => {
const spy = vi.spyOn(console, "error");
await program.runWith("setup 0.0.99 -u --skip-dependencies");
expect(spy.mock.calls[0]![0]).toMatchInlineSnapshot(
`"No releases match the supplied semver range (0.0.99)"`,
);
expect(spy.mock.calls[0]).toMatchInlineSnapshot(`
[
"No releases match the supplied semver range (0.0.99)",
]
`);
spy.mockRestore();
});

Expand Down
8 changes: 5 additions & 3 deletions test/commands/uninstall.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ it("should delete the bundle's folder after prompting for confirmation", async (
it("should print an error when the target bundle is not installed", async () => {
const spy = vi.spyOn(console, "error");
await program.runWith("uninstall not-installed");
expect(spy.mock.calls[0]![0]).toBe(
"Cannot uninstall %s: bundle is not installed.",
);
expect(spy.mock.calls[0]).toMatchInlineSnapshot(`
[
"Cannot uninstall not-installed: bundle is not installed.",
]
`);
spy.mockRestore();
});
7 changes: 3 additions & 4 deletions test/mocks/program.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { mock } from "node:test";

import { Command } from "commander";
import { vi } from "vitest";

export class MockCommand extends Command {
log() {
// To be mocked later
}

request(opts: any) {
throw new Error("Unexpected request: " + JSON.stringify(opts, null, 2));
throw new Error(`Unexpected request: ${JSON.stringify(opts, null, 2)}`);
}

runWith(argString: string) {
Expand All @@ -19,7 +18,7 @@ export class MockCommand extends Command {
export const createMockProgram = () => {
const program = new MockCommand();

mock.method(program, "log").mock.mockImplementation(() => void 0);
vi.spyOn(program, "log").mockImplementation(() => void 0);

return program;
};
Loading