Skip to content

Commit

Permalink
Merge pull request #12151 from quarto-dev/fix/windows/yaml-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
cderv authored Feb 28, 2025
2 parents e8eefd9 + 2b4c504 commit cdb794f
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 13 deletions.
3 changes: 3 additions & 0 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ All changes included in 1.7:
## YAML validation

- ([#11654](https://github.com/quarto-dev/quarto-cli/issues/11654)): Allow `page-inset` as value in `column` key for code cells.
- ([#12151](https://github.com/quarto-dev/quarto-cli/issues/12151)): Fix YAML validation in computations cell on Windows.
- ([#12151](https://github.com/quarto-dev/quarto-cli/pull/12151)): Basic YAML validation is now active in cell for document using Julia engine.

## Website projects

Expand Down Expand Up @@ -72,6 +74,7 @@ All changes included in 1.7:

- ([#11659](https://github.com/quarto-dev/quarto-cli/pull/11659)): Fix escaping bug where paths containing spaces or backslashes break server startup on Windows.
- ([#12121](https://github.com/quarto-dev/quarto-cli/pull/12121)): Update QuartoNotebookRunner to 0.13.1. Support for evaluating Python cells via [PythonCall.jl](https://github.com/JuliaPy/PythonCall.jl) added.
- ([#12151](https://github.com/quarto-dev/quarto-cli/pull/12151)): Basic YAML validation is now active for document using Julia engine.

## Other Fixes and Improvements

Expand Down
11 changes: 11 additions & 0 deletions src/core/lib/yaml-schema/chunk-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,16 @@ const jupyterEngineSchema = defineCached(
},
"engine-jupyter",
);
const juliaEnginesSchema = defineCached(
// deno-lint-ignore require-await
async () => {
return {
schema: makeEngineSchema("julia"),
errorHandlers: [],
};
},
"engine-julia",
);

export async function getEngineOptionsSchema(): Promise<
Record<string, ConcreteSchema>
Expand All @@ -140,6 +150,7 @@ export async function getEngineOptionsSchema(): Promise<
markdown: await markdownEngineSchema(),
knitr: await knitrEngineSchema(),
jupyter: await jupyterEngineSchema(),
julia: await juliaEnginesSchema(),
};

return obj;
Expand Down
24 changes: 11 additions & 13 deletions src/core/schema/validate-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ export async function validateDocumentFromSource(
} else {
firstContentCellIndex = 0;
}

for (const cell of nb.cells.slice(firstContentCellIndex)) {
if (
cell.cell_type === "markdown" ||
cell.cell_type === "raw"
cell.cell_type === "raw" ||
cell.cell_type?.language === "_directive"
) {
// not a language chunk
continue;
Expand All @@ -110,21 +110,19 @@ export async function validateDocumentFromSource(
const lang = cell.cell_type.language;

try {
const fullCell = mappedString(cell.sourceVerbatim, [{
start: lang.length + 6,
end: cell.sourceVerbatim.value.length - 3,
}]);
await partitionCellOptionsMapped(
lang,
fullCell,
true,
engine,
);
if (cell.sourceWithYaml) {
await partitionCellOptionsMapped(
lang,
cell.sourceWithYaml,
true,
engine,
);
}
} catch (e) {
if (e instanceof ValidationError) {
error("Validation of YAML cell metadata failed.");
for (const err of e.validationErrors) {
console.log(tidyverseFormatError(err.niceError));
error(tidyverseFormatError(err.niceError), { colorize: false });
}
result.push(...e.validationErrors);
} else {
Expand Down
11 changes: 11 additions & 0 deletions tests/docs/yaml/fail-validation-julia-backticks.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: "YAML intelligence should fail with knitr engine"
engine: julia
---

This code cell has more than default 3 backticks

````{julia}
#| echo: 123
1 + 1
````
9 changes: 9 additions & 0 deletions tests/docs/yaml/fail-validation-julia.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: "YAML intelligence should fail with knitr engine"
engine: julia
---

```{julia}
#| echo: 123
1 + 1
```
10 changes: 10 additions & 0 deletions tests/docs/yaml/fail-validation-jupyter-backticks.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "YAML intelligence should fail with knitr engine"
---

This code cell has more than default 3 backticks

````{python}
#| echo: 123
1 + 1
````
8 changes: 8 additions & 0 deletions tests/docs/yaml/fail-validation-jupyter.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: "YAML intelligence should fail with knitr engine"
---

```{python}
#| echo: 123
1 + 1
```
10 changes: 10 additions & 0 deletions tests/docs/yaml/fail-validation-knitr-backticks.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "YAML intelligence should fail with knitr engine"
---

This code cell has more than default 3 backticks

````{r}
#| echo: 123
1 + 1
````
8 changes: 8 additions & 0 deletions tests/docs/yaml/fail-validation-knitr.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: "YAML intelligence should fail with knitr engine"
---

```{r}
#| echo: 123
1 + 1
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { testQuartoCmd } from "../../test.ts";
import { fileLoader } from "../../utils.ts";
import { printsMessage } from "../../verify.ts";

const yamlDocs = fileLoader("yaml");

const testYamlValidationFails = (file: string) => {
testQuartoCmd(
"render",
[yamlDocs(file, "html").input, "--to", "html", "--quiet"],
[printsMessage("ERROR", /Validation of YAML cell metadata failed/)],
);
};

const files = [
"fail-validation-knitr.qmd",
"fail-validation-knitr-backticks.qmd",
"fail-validation-jupyter.qmd",
"fail-validation-jupyter-backticks.qmd",
"fail-validation-julia.qmd",
"fail-validation-julia-backticks.qmd",
];

files.forEach(testYamlValidationFails);

0 comments on commit cdb794f

Please sign in to comment.