Skip to content

Commit 5f75aa3

Browse files
committed
allow 'info' to not error in quarto check
1 parent 8d9f858 commit 5f75aa3

File tree

4 files changed

+65
-23
lines changed

4 files changed

+65
-23
lines changed

src/command/check/check.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,20 @@ import { notebookContext } from "../../render/notebook/notebook-context.ts";
4747
import { typstBinaryPath } from "../../core/typst.ts";
4848
import { quartoCacheDir } from "../../core/appdirs.ts";
4949
import { isWindows } from "../../deno_ral/platform.ts";
50+
import { checkStringEnum } from "../../typing/dynamic.ts";
5051

51-
const kIndent = " ";
52+
export const kTargets = [
53+
"install",
54+
"info",
55+
"jupyter",
56+
"knitr",
57+
"versions",
58+
"all",
59+
] as const;
60+
export type Target = typeof kTargets[number];
61+
export const checkTargetType = checkStringEnum(...kTargets);
5262

53-
export type Target =
54-
| "install"
55-
| "jupyter"
56-
| "knitr"
57-
| "versions"
58-
| "info"
59-
| "all";
63+
const kIndent = " ";
6064

6165
export async function check(target: Target): Promise<void> {
6266
const services = renderServices(notebookContext());
@@ -82,7 +86,9 @@ export async function check(target: Target): Promise<void> {
8286
}
8387
}
8488

85-
// Currently this doesn't check anything, but
89+
// Currently this doesn't check anything
90+
// but it's a placeholder for future checks
91+
// and the message is useful for troubleshooting
8692
async function checkInfo(_services: RenderServices) {
8793
const cacheDir = quartoCacheDir();
8894
completeMessage("Checking environment information...");

src/command/check/cmd.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,8 @@
44
* Copyright (C) 2021-2022 Posit Software, PBC
55
*/
66

7-
import { error } from "../../deno_ral/log.ts";
8-
97
import { Command } from "cliffy/command/mod.ts";
10-
import { check, Target } from "./check.ts";
11-
12-
const kTargets = ["install", "jupyter", "knitr", "versions", "all"];
8+
import { check, checkTargetType } from "./check.ts";
139

1410
export const checkCommand = new Command()
1511
.name("check")
@@ -22,13 +18,7 @@ export const checkCommand = new Command()
2218
.example("Check Jupyter engine", "quarto check jupyter")
2319
.example("Check Knitr engine", "quarto check knitr")
2420
.example("Check installation and all engines", "quarto check all")
25-
.action(async (_options: unknown, target?: string) => {
26-
target = target || "all";
27-
if (!kTargets.includes(target)) {
28-
error(
29-
"Invalid target '" + target + "' (valid targets are " +
30-
kTargets.join(", ") + ").",
31-
);
32-
}
33-
await check(target as Target);
21+
.action(async (_options: unknown, targetStr?: string) => {
22+
targetStr = targetStr || "all";
23+
await check(checkTargetType(targetStr));
3424
});

src/typing/dynamic.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* dynamic.ts
3+
*
4+
* Tools for managing the interface between dynamic and static typing
5+
* in Quarto.
6+
*
7+
* Ideally, every usage of `any` or `as` would appear in this file.
8+
*
9+
* Copyright (C) 2024 Posit Software, PBC
10+
*/
11+
12+
import { DynamicTypeCheckError } from "../core/lib/error.ts";
13+
14+
export const checkStringEnum = <T extends string>(
15+
...values: T[]
16+
): (value: string) => T => {
17+
const valueSet: Set<string> = new Set(values);
18+
return (value: string): T => {
19+
if (!valueSet.has(value)) {
20+
throw new DynamicTypeCheckError(
21+
"Invalid value '" + value + "' (valid values are " +
22+
values.join(", ") + ").",
23+
);
24+
}
25+
return value as unknown as T;
26+
};
27+
};

tests/unit/typing/dynamic.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* dynamic.test.ts
3+
*
4+
* Copyright (C) 2024 Posit Software, PBC
5+
*
6+
*/
7+
8+
import { checkStringEnum } from "../../../src/typing/dynamic.ts";
9+
import { unitTest } from "../../test.ts";
10+
import { assert, assertThrows } from "testing/asserts";
11+
12+
// deno-lint-ignore require-await
13+
unitTest("checkStringEnum", async () => {
14+
const check = checkStringEnum("a", "b", "c");
15+
assert(check("a") === "a");
16+
assert(check("b") === "b");
17+
assert(check("c") === "c");
18+
assertThrows(() => check("d"), Error, "Invalid value 'd' (valid values are a, b, c).");
19+
});

0 commit comments

Comments
 (0)