Skip to content

Commit 69d1701

Browse files
authored
Merge pull request #12424 from quarto-dev/feature/10047
check - compare binary dependency versions strictly by default (#10047)
2 parents 6661062 + 7448a54 commit 69d1701

File tree

4 files changed

+62
-26
lines changed

4 files changed

+62
-26
lines changed

configuration

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
# but it also used when packaging (e.g. run configure.sh, then prepare-dist.sh, then package.sh)
88
# deno_dom should match release at https://github.com/b-fuze/deno-dom/releases
99

10+
# NB: When these are updated, you must also update the versions
11+
# in src/command/check/check.ts
12+
1013
# Binary dependencies
1114
export DENO=v1.46.3
1215
# TODO figure out where 0.1.41 apple silicon libs are available

news/changelog-1.7.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ All changes included in 1.7:
3535

3636
## `quarto check`
3737

38+
- ([#10047](https://github.com/quarto-dev/quarto-cli/issues/10047)): `quarto check` will now check binary dependency versions strictly by default. Use `quarto check --no-strict` to revert to old behavior.
3839
- ([#11608](https://github.com/quarto-dev/quarto-cli/pull/11608)): Do not issue error message when calling `quarto check info`.
3940

4041
## `quarto convert`

src/command/check/check.ts

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ export const enforceTargetType = makeStringEnumTypeEnforcer(...kTargets);
6363

6464
const kIndent = " ";
6565

66-
export async function check(target: Target): Promise<void> {
66+
export async function check(target: Target, strict?: boolean): Promise<void> {
6767
const services = renderServices(notebookContext());
6868
try {
6969
info(`Quarto ${quartoConfig.version()}`);
7070
if (target === "info" || target === "all") {
7171
await checkInfo(services);
7272
}
7373
if (target === "versions" || target === "all") {
74-
await checkVersions(services);
74+
await checkVersions(services, strict);
7575
}
7676
if (target === "install" || target === "all") {
7777
await checkInstall(services);
@@ -96,8 +96,8 @@ async function checkInfo(_services: RenderServices) {
9696
info(kIndent + "Quarto cache location: " + cacheDir);
9797
}
9898

99-
async function checkVersions(_services: RenderServices) {
100-
const checkVersion = async (
99+
async function checkVersions(_services: RenderServices, strict?: boolean) {
100+
const checkVersion = (
101101
version: string | undefined,
102102
constraint: string,
103103
name: string,
@@ -116,6 +116,20 @@ async function checkVersions(_services: RenderServices) {
116116
}
117117
};
118118

119+
const strictCheckVersion = (
120+
version: string,
121+
constraint: string,
122+
name: string,
123+
) => {
124+
if (version !== constraint) {
125+
info(
126+
` NOTE: ${name} version ${version} does not strictly match ${constraint} and strict checking is enabled. Please use ${constraint}.`,
127+
);
128+
} else {
129+
info(` ${name} version ${version}: OK`);
130+
}
131+
};
132+
119133
completeMessage("Checking versions of quarto binary dependencies...");
120134

121135
let pandocVersion = lines(
@@ -124,6 +138,15 @@ async function checkVersions(_services: RenderServices) {
124138
stdout: "piped",
125139
})).stdout!,
126140
)[0]?.split(" ")[1];
141+
const sassVersion = (await dartCommand(["--version"]))?.trim();
142+
const denoVersion = Deno.version.deno;
143+
const typstVersion = lines(
144+
(await execProcess({
145+
cmd: [typstBinaryPath(), "--version"],
146+
stdout: "piped",
147+
})).stdout!,
148+
)[0].split(" ")[1];
149+
127150
// We hack around pandocVersion to build a sem-verish string
128151
// that satisfies the semver package
129152
// if pandoc reports more than three version numbers, pick the first three
@@ -138,29 +161,33 @@ async function checkVersions(_services: RenderServices) {
138161
).join(".");
139162
}
140163
}
141-
checkVersion(pandocVersion, ">=2.19.2", "Pandoc");
142-
143-
const sassVersion = (await dartCommand(["--version"]))?.trim();
144-
checkVersion(sassVersion, ">=1.32.8", "Dart Sass");
145164

146-
// manually check Deno version without shelling out
147-
// because we're actually running in Deno right now
148-
if (!satisfies(Deno.version.deno, ">=1.33.1")) {
149-
info(
150-
` NOTE: Deno version ${Deno.version.deno} is too old. Please upgrade to 1.33.1 or later.`,
151-
);
152-
} else {
153-
info(` Deno version ${Deno.version.deno}: OK`);
165+
// FIXME: all of these strict checks should be done by
166+
// loading the configuration file directly, but that
167+
// file is in an awkward format and it is not packaged
168+
// with our installers
169+
const checkData: [string | undefined, string, string][] = strict
170+
? [
171+
[pandocVersion, "3.6.3", "Pandoc"],
172+
[sassVersion, "1.85.1", "Dart Sass"],
173+
[denoVersion, "1.46.3", "Deno"],
174+
[typstVersion, "0.13.0", "Typst"],
175+
]
176+
: [
177+
[pandocVersion, ">=2.19.2", "Pandoc"],
178+
[sassVersion, ">=1.32.8", "Dart Sass"],
179+
[denoVersion, ">=1.33.1", "Deno"],
180+
[typstVersion, ">=0.10.0", "Typst"],
181+
];
182+
const fun = strict ? strictCheckVersion : checkVersion;
183+
for (const [version, constraint, name] of checkData) {
184+
if (version === undefined) {
185+
info(` ${name} version: (not detected)`);
186+
} else {
187+
fun(version, constraint, name);
188+
}
154189
}
155190

156-
let typstVersion = lines(
157-
(await execProcess({
158-
cmd: [typstBinaryPath(), "--version"],
159-
stdout: "piped",
160-
})).stdout!,
161-
)[0].split(" ")[1];
162-
checkVersion(typstVersion, ">=0.10.0", "Typst");
163-
164191
completeMessage("Checking versions of quarto dependencies......OK");
165192
}
166193

src/command/check/cmd.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { check, enforceTargetType } from "./check.ts";
99

1010
export const checkCommand = new Command()
1111
.name("check")
12+
.option(
13+
"--no-strict",
14+
"When set, will not fail if dependency versions don't match precisely",
15+
)
1216
.arguments("[target:string]")
1317
.description(
1418
"Verify correct functioning of Quarto installation.\n\n" +
@@ -18,7 +22,8 @@ export const checkCommand = new Command()
1822
.example("Check Jupyter engine", "quarto check jupyter")
1923
.example("Check Knitr engine", "quarto check knitr")
2024
.example("Check installation and all engines", "quarto check all")
21-
.action(async (_options: unknown, targetStr?: string) => {
25+
// deno-lint-ignore no-explicit-any
26+
.action(async (options: any, targetStr?: string) => {
2227
targetStr = targetStr || "all";
23-
await check(enforceTargetType(targetStr));
28+
await check(enforceTargetType(targetStr), options.strict);
2429
});

0 commit comments

Comments
 (0)