Skip to content

Commit

Permalink
refactor: replace inquirer with @inquirer/prompts (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoishin authored Dec 27, 2024
1 parent 7c6cfdc commit f6b7def
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 122 deletions.
47 changes: 1 addition & 46 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@
},
"prettier": {},
"dependencies": {
"@inquirer/prompts": "^7.2.1",
"ajv": "^8.17.1",
"chalk": "^5.4.1",
"commander": "^12.1.0",
"hosted-git-info": "^8.0.2",
"inquirer": "^12.3.0",
"json-schema-to-typescript": "^15.0.3",
"npm-package-arg": "^12.0.1",
"semver": "^7.6.3",
Expand Down
44 changes: 13 additions & 31 deletions src/commands/setup.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { execSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import stream from "node:stream/promises";

import { confirm } from "@inquirer/prompts";
import chalk from "chalk";
import { execSync } from "child_process";
import { Command } from "commander";
import inquirer from "inquirer";
import semver from "semver";
import * as tar from "tar";

Expand Down Expand Up @@ -44,9 +44,7 @@ async function decideActionVersion(
if (!options.update) {
console.error("NodeCG is already installed in this directory.");
console.error(
"Use " +
chalk.cyan("nodecg setup [version] -u") +
" if you want update your existing install.",
`Use ${chalk.cyan("nodecg setup [version] -u")} if you want update your existing install.`,
);
return;
}
Expand All @@ -56,9 +54,7 @@ async function decideActionVersion(

if (version) {
process.stdout.write(
"Finding latest release that satisfies semver range " +
chalk.magenta(version) +
"... ",
`Finding latest release that satisfies semver range ${chalk.magenta(version)}... `,
);
} else if (isUpdate) {
process.stdout.write("Checking against local install for updates... ");
Expand All @@ -69,12 +65,9 @@ async function decideActionVersion(
let tags;
try {
tags = fetchTags(NODECG_GIT_URL);
} catch (e: any) {
/* istanbul ignore next */
} catch (error) {
process.stdout.write(chalk.red("failed!") + os.EOL);
/* istanbul ignore next */
console.error(e.stack);
/* istanbul ignore next */
console.error(error instanceof Error ? error.message : error);
return;
}

Expand All @@ -87,9 +80,7 @@ async function decideActionVersion(
if (!maxSatisfying) {
process.stdout.write(chalk.red("failed!") + os.EOL);
console.error(
"No releases match the supplied semver range (" +
chalk.magenta(version) +
")",
`No releases match the supplied semver range (${chalk.magenta(version)})`,
);
return;
}
Expand All @@ -109,30 +100,21 @@ async function decideActionVersion(

if (semver.eq(target, current)) {
console.log(
"The target version (%s) is equal to the current version (%s). No action will be taken.",
chalk.magenta(target),
chalk.magenta(current),
`The target version (${chalk.magenta(target)}) is equal to the current version (${chalk.magenta(current)}). No action will be taken.`,
);
return;
}

if (semver.lt(target, current)) {
console.log(
chalk.red("WARNING: ") +
"The target version (%s) is older than the current version (%s)",
chalk.magenta(target),
chalk.magenta(current),
`${chalk.red("WARNING:")} The target version (${chalk.magenta(target)}) is older than the current version (${chalk.magenta(current)})`,
);

const answers = await inquirer.prompt<{ installOlder: boolean }>([
{
name: "installOlder",
message: "Are you sure you wish to continue?",
type: "confirm",
},
]);
const answer = await confirm({
message: "Are you sure you wish to continue?",
});

if (!answers.installOlder) {
if (!answer) {
console.log("Setup cancelled.");
return;
}
Expand Down
25 changes: 8 additions & 17 deletions src/commands/uninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";

import { confirm } from "@inquirer/prompts";
import chalk from "chalk";
import { Command } from "commander";
import inquirer from "inquirer";

import { getNodeCGPath } from "../lib/util.js";

Expand Down Expand Up @@ -32,22 +32,13 @@ function action(bundleName: string, options: { force: boolean }) {
if (options.force) {
deleteBundle(bundleName, bundlePath);
} else {
void inquirer
.prompt<{ confirmUninstall: boolean }>([
{
name: "confirmUninstall",
message:
"Are you sure you wish to uninstall " +
chalk.magenta(bundleName) +
"?",
type: "confirm",
},
])
.then((answers) => {
if (answers.confirmUninstall) {
deleteBundle(bundleName, bundlePath);
}
});
void confirm({
message: `Are you sure you wish to uninstall ${chalk.magenta(bundleName)}?`,
}).then((answer) => {
if (answer) {
deleteBundle(bundleName, bundlePath);
}
});
}
}

Expand Down
11 changes: 5 additions & 6 deletions src/lib/fetch-tags.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { execSync } from "child_process";
import { execFileSync } from "child_process";

export function fetchTags(repoUrl: string) {
const rawTags = execSync(`git ls-remote --refs --tags ${repoUrl}`)
.toString()
return execFileSync("git", ["ls-remote", "--refs", "--tags", repoUrl])
.toString("utf-8")
.trim()
.split("\n");
return rawTags
.map((rawTag) => rawTag.split("refs/tags/").pop())
.split("\n")
.map((rawTag) => rawTag.split("refs/tags/").at(-1))
.filter((t) => typeof t === "string");
}
8 changes: 4 additions & 4 deletions src/lib/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import type { NpmRelease } from "./sample/npm-release.js";
*/
export function pathContainsNodeCG(pathToCheck: string): boolean {
const pjsonPath = path.join(pathToCheck, "package.json");
if (fs.existsSync(pjsonPath)) {
const pjson = JSON.parse(fs.readFileSync(pjsonPath, "utf8"));
try {
const pjson = JSON.parse(fs.readFileSync(pjsonPath, "utf-8"));
return pjson.name.toLowerCase() === "nodecg";
} catch {
return false;
}

return false;
}

/**
Expand Down
15 changes: 3 additions & 12 deletions test/commands/setup.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import fs from "node:fs";

import { Command } from "commander";
import inquirer from "inquirer";
import type { PackageJson } from "type-fest";
import { beforeEach, expect, test, vi } from "vitest";

import { setupCommand } from "../../src/commands/setup.js";
import { createMockProgram, MockCommand } from "../mocks/program.js";
import { setupTmpDir } from "./tmp-dir.js";

vi.mock("@inquirer/prompts", () => ({ confirm: () => Promise.resolve(true) }));

let program: MockCommand;
let currentDir = setupTmpDir();
const chdir = (keepCurrentDir = false) => {
Expand Down Expand Up @@ -50,13 +51,8 @@ test("should install v1 NodeCG when specified", async () => {
});

test("should ask the user for confirmation when downgrading versions", async () => {
const spy = vi
.spyOn(inquirer, "prompt")
.mockReturnValue(Promise.resolve({ installOlder: true }) as any);
await program.runWith("setup 0.8.1 -u --skip-dependencies");
expect(spy).toBeCalled();
expect(readPackageJson().version).toBe("0.8.1");
spy.mockRestore();
});

test("should let the user change upgrade versions", async () => {
Expand All @@ -69,19 +65,14 @@ test("should print an error when the target version is the same as current", asy
await program.runWith("setup 0.8.2 -u --skip-dependencies");
expect(spy.mock.calls[0]).toMatchInlineSnapshot(`
[
"The target version (%s) is equal to the current version (%s). No action will be taken.",
"v0.8.2",
"0.8.2",
"The target version (v0.8.2) is equal to the current version (0.8.2). No action will be taken.",
]
`);
spy.mockRestore();
});

test("should correctly handle and refuse when you try to downgrade from v2 to v1", async () => {
chdir();
vi.spyOn(inquirer, "prompt").mockReturnValue(
Promise.resolve({ installOlder: true }) as any,
);
await program.runWith("setup 2.0.0 --skip-dependencies");
expect(readPackageJson().version).toBe("2.0.0");
await program.runWith("setup 1.9.0 -u --skip-dependencies");
Expand Down
7 changes: 2 additions & 5 deletions test/commands/uninstall.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import path from "node:path";
import { fileURLToPath } from "node:url";

import { Command } from "commander";
import inquirer from "inquirer";
import { beforeEach, expect, it, vi } from "vitest";

import { uninstallCommand } from "../../src/commands/uninstall.js";
import { createMockProgram, MockCommand } from "../mocks/program.js";
import { setupTmpDir } from "./tmp-dir.js";

vi.mock("@inquirer/prompts", () => ({ confirm: () => Promise.resolve(true) }));

const dirname = path.dirname(fileURLToPath(import.meta.url));

let program: MockCommand;
Expand All @@ -29,12 +30,8 @@ beforeEach(() => {
});

it("should delete the bundle's folder after prompting for confirmation", async () => {
const spy = vi.spyOn(inquirer, "prompt").mockImplementation(() => {
return Promise.resolve({ confirmUninstall: true }) as any;
});
await program.runWith("uninstall uninstall-test");
expect(fs.existsSync("./bundles/uninstall-test")).toBe(false);
spy.mockRestore();
});

it("should print an error when the target bundle is not installed", async () => {
Expand Down

0 comments on commit f6b7def

Please sign in to comment.