From dc95350ec0ec26fb4a4dab3abe6bedfc41e09508 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 14:28:07 +0100 Subject: [PATCH 1/7] test, yaml - add test for render that should fail as YAML validation error --- .../yaml/fail-validation-julia-backticks.qmd | 11 ++++++++ tests/docs/yaml/fail-validation-julia.qmd | 9 +++++++ .../fail-validation-jupyter-backticks.qmd | 10 ++++++++ tests/docs/yaml/fail-validation-jupyter.qmd | 8 ++++++ .../yaml/fail-validation-knitr-backticks.qmd | 10 ++++++++ tests/docs/yaml/fail-validation-knitr.qmd | 8 ++++++ ...aml-intelligence-code-cell-options.test.ts | 25 +++++++++++++++++++ 7 files changed, 81 insertions(+) create mode 100644 tests/docs/yaml/fail-validation-julia-backticks.qmd create mode 100644 tests/docs/yaml/fail-validation-julia.qmd create mode 100644 tests/docs/yaml/fail-validation-jupyter-backticks.qmd create mode 100644 tests/docs/yaml/fail-validation-jupyter.qmd create mode 100644 tests/docs/yaml/fail-validation-knitr-backticks.qmd create mode 100644 tests/docs/yaml/fail-validation-knitr.qmd create mode 100644 tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts diff --git a/tests/docs/yaml/fail-validation-julia-backticks.qmd b/tests/docs/yaml/fail-validation-julia-backticks.qmd new file mode 100644 index 00000000000..039e149b27e --- /dev/null +++ b/tests/docs/yaml/fail-validation-julia-backticks.qmd @@ -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 +```` diff --git a/tests/docs/yaml/fail-validation-julia.qmd b/tests/docs/yaml/fail-validation-julia.qmd new file mode 100644 index 00000000000..b379b2ffa90 --- /dev/null +++ b/tests/docs/yaml/fail-validation-julia.qmd @@ -0,0 +1,9 @@ +--- +title: "YAML intelligence should fail with knitr engine" +engine: julia +--- + +```{julia} +#| echo: 123 +1 + 1 +``` diff --git a/tests/docs/yaml/fail-validation-jupyter-backticks.qmd b/tests/docs/yaml/fail-validation-jupyter-backticks.qmd new file mode 100644 index 00000000000..9ca84d5cb75 --- /dev/null +++ b/tests/docs/yaml/fail-validation-jupyter-backticks.qmd @@ -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 +```` \ No newline at end of file diff --git a/tests/docs/yaml/fail-validation-jupyter.qmd b/tests/docs/yaml/fail-validation-jupyter.qmd new file mode 100644 index 00000000000..917ba63fccf --- /dev/null +++ b/tests/docs/yaml/fail-validation-jupyter.qmd @@ -0,0 +1,8 @@ +--- +title: "YAML intelligence should fail with knitr engine" +--- + +```{python} +#| echo: 123 +1 + 1 +``` diff --git a/tests/docs/yaml/fail-validation-knitr-backticks.qmd b/tests/docs/yaml/fail-validation-knitr-backticks.qmd new file mode 100644 index 00000000000..81186fbfcec --- /dev/null +++ b/tests/docs/yaml/fail-validation-knitr-backticks.qmd @@ -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 +```` \ No newline at end of file diff --git a/tests/docs/yaml/fail-validation-knitr.qmd b/tests/docs/yaml/fail-validation-knitr.qmd new file mode 100644 index 00000000000..50473685a4d --- /dev/null +++ b/tests/docs/yaml/fail-validation-knitr.qmd @@ -0,0 +1,8 @@ +--- +title: "YAML intelligence should fail with knitr engine" +--- + +```{r} +#| echo: 123 +1 + 1 +``` diff --git a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts new file mode 100644 index 00000000000..d617f78db64 --- /dev/null +++ b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts @@ -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", "--log-level", "error", "--quiet"], + [printsMessage("ERROR", /Validation of YAML cell metadata failed/)], + ); +}; + +const files = [ + "fail-validation-knitr.qmd", + "fail-validation-jupyter.qmd", + "fail-validation-julia.qmd", + "fail-validation-knitr-backticks.qmd", + "fail-validation-jupyter-backticks.qmd", + "fail-validation-julia-backticks.qmd", +]; + +files.forEach(testYamlValidationFails); + From cefcdb154a7bcb6c82f71dc233c9aeea4e3fc06a Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 14:31:47 +0100 Subject: [PATCH 2/7] niceError should be printed at info level so that it can be responsive to ------log-level --- src/core/schema/validate-document.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/schema/validate-document.ts b/src/core/schema/validate-document.ts index 84953156f15..7a5d76555fe 100644 --- a/src/core/schema/validate-document.ts +++ b/src/core/schema/validate-document.ts @@ -9,7 +9,7 @@ import { breakQuartoMd } from "../lib/break-quarto-md.ts"; import { mappedString } from "../mapped-text.ts"; import { rangedLines } from "../ranged-text.ts"; import { readAnnotatedYamlFromMappedString } from "./annotated-yaml.ts"; -import { error } from "../../deno_ral/log.ts"; +import { error, info } from "../../deno_ral/log.ts"; import { partitionCellOptionsMapped } from "../lib/partition-cell-options.ts"; import { withValidator } from "../lib/yaml-validation/validator-queue.ts"; import { ValidationError } from "./validated-yaml.ts"; @@ -124,7 +124,7 @@ export async function validateDocumentFromSource( if (e instanceof ValidationError) { error("Validation of YAML cell metadata failed."); for (const err of e.validationErrors) { - console.log(tidyverseFormatError(err.niceError)); + info(tidyverseFormatError(err.niceError)); } result.push(...e.validationErrors); } else { From 32e52952c280dd390a523c032c96dfd794ec4787 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 15:56:36 +0100 Subject: [PATCH 3/7] Use error without color --- src/core/schema/validate-document.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/schema/validate-document.ts b/src/core/schema/validate-document.ts index 7a5d76555fe..24bae33a1e1 100644 --- a/src/core/schema/validate-document.ts +++ b/src/core/schema/validate-document.ts @@ -124,7 +124,7 @@ export async function validateDocumentFromSource( if (e instanceof ValidationError) { error("Validation of YAML cell metadata failed."); for (const err of e.validationErrors) { - info(tidyverseFormatError(err.niceError)); + error(tidyverseFormatError(err.niceError), { colorize: false }); } result.push(...e.validationErrors); } else { From 0b8bc98a5af3198c8e376687e39c841d88cde12b Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 16:05:23 +0100 Subject: [PATCH 4/7] Use the parsed cellSourceWithYAML from breakQuartoMd No need to count character as the current parser does it already. --- src/core/schema/validate-document.ts | 22 +++++++++---------- ...aml-intelligence-code-cell-options.test.ts | 9 ++++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/core/schema/validate-document.ts b/src/core/schema/validate-document.ts index 24bae33a1e1..4f762646684 100644 --- a/src/core/schema/validate-document.ts +++ b/src/core/schema/validate-document.ts @@ -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; @@ -110,16 +110,14 @@ 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."); diff --git a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts index d617f78db64..78924d4c755 100644 --- a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts +++ b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts @@ -7,18 +7,19 @@ const yamlDocs = fileLoader("yaml"); const testYamlValidationFails = (file: string) => { testQuartoCmd( "render", - [yamlDocs(file, "html").input, "--to", "html", "--log-level", "error", "--quiet"], + [yamlDocs(file, "html").input, "--to", "html", "--quiet"], [printsMessage("ERROR", /Validation of YAML cell metadata failed/)], ); }; const files = [ "fail-validation-knitr.qmd", - "fail-validation-jupyter.qmd", - "fail-validation-julia.qmd", "fail-validation-knitr-backticks.qmd", + "fail-validation-jupyter.qmd", "fail-validation-jupyter-backticks.qmd", - "fail-validation-julia-backticks.qmd", + // FIXME: Activate this when Quarto schema for Julia engine + //"fail-validation-julia.qmd", + //"fail-validation-julia-backticks.qmd", ]; files.forEach(testYamlValidationFails); From 22b6c5d84a9ec2585b060a1d374f6e2e8a85b7d8 Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 16:28:00 +0100 Subject: [PATCH 5/7] Add basic YAML validation for `engine: julia` --- src/core/lib/yaml-schema/chunk-metadata.ts | 11 +++++++++++ .../yaml-intelligence-code-cell-options.test.ts | 5 ++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/core/lib/yaml-schema/chunk-metadata.ts b/src/core/lib/yaml-schema/chunk-metadata.ts index c89b3058549..689e3bc65d3 100644 --- a/src/core/lib/yaml-schema/chunk-metadata.ts +++ b/src/core/lib/yaml-schema/chunk-metadata.ts @@ -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 @@ -140,6 +150,7 @@ export async function getEngineOptionsSchema(): Promise< markdown: await markdownEngineSchema(), knitr: await knitrEngineSchema(), jupyter: await jupyterEngineSchema(), + julia: await juliaEnginesSchema(), }; return obj; diff --git a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts index 78924d4c755..c2dcea97dc3 100644 --- a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts +++ b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts @@ -17,9 +17,8 @@ const files = [ "fail-validation-knitr-backticks.qmd", "fail-validation-jupyter.qmd", "fail-validation-jupyter-backticks.qmd", - // FIXME: Activate this when Quarto schema for Julia engine - //"fail-validation-julia.qmd", - //"fail-validation-julia-backticks.qmd", + "fail-validation-julia.qmd", + "fail-validation-julia-backticks.qmd", ]; files.forEach(testYamlValidationFails); From 01ec3e7edc08c74824cd020d33aef34655e1d65b Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 17:20:25 +0100 Subject: [PATCH 6/7] Add to changelog [skip ci] --- news/changelog-1.7.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index 26edbb839bb..a5a09ef4432 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -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 @@ -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 From 2b4c504c626c32cd311f8296d619031fc6941f9f Mon Sep 17 00:00:00 2001 From: Christophe Dervieux Date: Tue, 25 Feb 2025 18:04:44 +0100 Subject: [PATCH 7/7] Removed unused import --- src/core/schema/validate-document.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/schema/validate-document.ts b/src/core/schema/validate-document.ts index 4f762646684..42e2276ff9f 100644 --- a/src/core/schema/validate-document.ts +++ b/src/core/schema/validate-document.ts @@ -9,7 +9,7 @@ import { breakQuartoMd } from "../lib/break-quarto-md.ts"; import { mappedString } from "../mapped-text.ts"; import { rangedLines } from "../ranged-text.ts"; import { readAnnotatedYamlFromMappedString } from "./annotated-yaml.ts"; -import { error, info } from "../../deno_ral/log.ts"; +import { error } from "../../deno_ral/log.ts"; import { partitionCellOptionsMapped } from "../lib/partition-cell-options.ts"; import { withValidator } from "../lib/yaml-validation/validator-queue.ts"; import { ValidationError } from "./validated-yaml.ts";