From 2e498bd85c9a95c96c6afc5da297a8cf810a33bc Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Thu, 17 Oct 2024 12:02:57 -0700 Subject: [PATCH] pre,postrender - use QUARTO_USE_* environment when requested --- src/command/render/project.ts | 76 +++++++++++++++---- src/quarto.ts | 16 ++-- .../project/prepost/issue-10828/.gitignore | 1 + .../project/prepost/issue-10828/_quarto.yml | 21 +++++ .../project/prepost/issue-10828/about.qmd | 5 ++ .../prepost/issue-10828/check-input.ts | 1 + .../prepost/issue-10828/check-output.ts | 1 + .../project/prepost/issue-10828/index.qmd | 7 ++ .../project/prepost/issue-10828/styles.css | 1 + tests/smoke/project/project-prepost.test.ts | 24 +++++- 10 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 tests/docs/project/prepost/issue-10828/.gitignore create mode 100644 tests/docs/project/prepost/issue-10828/_quarto.yml create mode 100644 tests/docs/project/prepost/issue-10828/about.qmd create mode 100644 tests/docs/project/prepost/issue-10828/check-input.ts create mode 100644 tests/docs/project/prepost/issue-10828/check-output.ts create mode 100644 tests/docs/project/prepost/issue-10828/index.qmd create mode 100644 tests/docs/project/prepost/issue-10828/styles.css diff --git a/src/command/render/project.ts b/src/command/render/project.ts index dc4aa8698f..58a5a94e72 100644 --- a/src/command/render/project.ts +++ b/src/command/render/project.ts @@ -326,18 +326,34 @@ export async function renderProject( // run pre-render step if we are rendering all files if (preRenderScripts.length) { + // https://github.com/quarto-dev/quarto-cli/issues/10828 + // some environments limit the length of environment variables. + // It's hard to know in advance what the limit is, so we will + // instead ask users to configure their environment with + // the names of the files we will write the list of files to. + + const filesToRender = projectRenderConfig.filesToRender + .map((fileToRender) => fileToRender.path) + .map((file) => relative(projDir, file)); + const env: Record = { + ...prePostEnv, + }; + + if (Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES")) { + Deno.writeTextFileSync( + Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES")!, + filesToRender.join("\n"), + ); + } else { + env.QUARTO_PROJECT_INPUT_FILES = filesToRender.join("\n"); + } + await runPreRender( projDir, preRenderScripts, progress, !!projectRenderConfig.options.flags?.quiet, - { - ...prePostEnv, - QUARTO_PROJECT_INPUT_FILES: projectRenderConfig.filesToRender - .map((fileToRender) => fileToRender.path) - .map((file) => relative(projDir, file)) - .join("\n"), - }, + env, ); // re-initialize project context @@ -814,17 +830,34 @@ export async function renderProject( // run post-render if this isn't incremental if (postRenderScripts.length) { + // https://github.com/quarto-dev/quarto-cli/issues/10828 + // some environments limit the length of environment variables. + // It's hard to know in advance what the limit is, so we will + // instead ask users to configure their environment with + // the names of the files we will write the list of files to. + + const env: Record = { + ...prePostEnv, + }; + + if (Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES")) { + Deno.writeTextFileSync( + Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES")!, + outputFiles.map((outputFile) => relative(projDir, outputFile.file)) + .join("\n"), + ); + } else { + env.QUARTO_PROJECT_OUTPUT_FILES = outputFiles + .map((outputFile) => relative(projDir, outputFile.file)) + .join("\n"); + } + await runPostRender( projDir, postRenderScripts, progress, !!projectRenderConfig.options.flags?.quiet, - { - ...prePostEnv, - QUARTO_PROJECT_OUTPUT_FILES: outputFiles - .map((outputFile) => relative(projDir, outputFile.file)) - .join("\n"), - }, + env, ); } } @@ -908,6 +941,23 @@ async function runScripts( const handler = handlerForScript(script); if (handler) { + if (env) { + env = { + ...env, + }; + } else { + env = {}; + } + if (!env) throw new Error("should never get here"); + const input = Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES"); + const output = Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES"); + if (input) { + env["QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES"] = input; + } + if (output) { + env["QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES"] = output; + } + const result = await handler.run(script, args.splice(1), undefined, { cwd: projDir, stdout: quiet ? "piped" : "inherit", diff --git a/src/quarto.ts b/src/quarto.ts index 698383d44f..76411af26a 100644 --- a/src/quarto.ts +++ b/src/quarto.ts @@ -93,7 +93,7 @@ export async function quarto( // passthrough to run handlers if (args[0] === "run" && args[1] !== "help" && args[1] !== "--help") { - const result = await runScript(args.slice(1)); + const result = await runScript(args.slice(1), env); Deno.exit(result.code); } @@ -151,16 +151,16 @@ export async function quarto( const promise = quartoCommand.command("help", new HelpCommand().global()) .command("completions", new CompletionsCommand()).hidden().parse(args); - for (const [key, value] of Object.entries(oldEnv)) { - if (value === undefined) { - Deno.env.delete(key); - } else { - Deno.env.set(key, value); - } - } try { await promise; + for (const [key, value] of Object.entries(oldEnv)) { + if (value === undefined) { + Deno.env.delete(key); + } else { + Deno.env.set(key, value); + } + } } catch (e) { if (e instanceof CommandError) { logError(e, false); diff --git a/tests/docs/project/prepost/issue-10828/.gitignore b/tests/docs/project/prepost/issue-10828/.gitignore new file mode 100644 index 0000000000..075b2542af --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/tests/docs/project/prepost/issue-10828/_quarto.yml b/tests/docs/project/prepost/issue-10828/_quarto.yml new file mode 100644 index 0000000000..7b7fb80a13 --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/_quarto.yml @@ -0,0 +1,21 @@ +project: + type: website + pre-render: check-input.ts + post-render: check-output.ts + +website: + title: "issue-10828" + navbar: + left: + - href: index.qmd + text: Home + - about.qmd + +format: + html: + theme: cosmo + css: styles.css + toc: true + + + diff --git a/tests/docs/project/prepost/issue-10828/about.qmd b/tests/docs/project/prepost/issue-10828/about.qmd new file mode 100644 index 0000000000..07c5e7f9d1 --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/about.qmd @@ -0,0 +1,5 @@ +--- +title: "About" +--- + +About this site diff --git a/tests/docs/project/prepost/issue-10828/check-input.ts b/tests/docs/project/prepost/issue-10828/check-input.ts new file mode 100644 index 0000000000..702833860e --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/check-input.ts @@ -0,0 +1 @@ +Deno.readTextFileSync(Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES")); \ No newline at end of file diff --git a/tests/docs/project/prepost/issue-10828/check-output.ts b/tests/docs/project/prepost/issue-10828/check-output.ts new file mode 100644 index 0000000000..acebe30357 --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/check-output.ts @@ -0,0 +1 @@ +Deno.readTextFileSync(Deno.env.get("QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES")); \ No newline at end of file diff --git a/tests/docs/project/prepost/issue-10828/index.qmd b/tests/docs/project/prepost/issue-10828/index.qmd new file mode 100644 index 0000000000..9b441ad4a6 --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/index.qmd @@ -0,0 +1,7 @@ +--- +title: "issue-10828" +--- + +This is a Quarto website. + +To learn more about Quarto websites visit . diff --git a/tests/docs/project/prepost/issue-10828/styles.css b/tests/docs/project/prepost/issue-10828/styles.css new file mode 100644 index 0000000000..2ddf50c7b4 --- /dev/null +++ b/tests/docs/project/prepost/issue-10828/styles.css @@ -0,0 +1 @@ +/* css styles */ diff --git a/tests/smoke/project/project-prepost.test.ts b/tests/smoke/project/project-prepost.test.ts index f44ee3f7af..85845e046b 100644 --- a/tests/smoke/project/project-prepost.test.ts +++ b/tests/smoke/project/project-prepost.test.ts @@ -10,7 +10,7 @@ import { join } from "../../../src/deno_ral/path.ts"; import { existsSync } from "../../../src/deno_ral/fs.ts"; import { testQuartoCmd } from "../../test.ts"; import { fileExists, noErrors, printsMessage, verifyNoPath, verifyPath } from "../../verify.ts"; -import { safeRemoveIfExists } from "../../../src/core/path.ts"; +import { normalizePath, safeRemoveIfExists } from "../../../src/core/path.ts"; const renderDir = docs("project/prepost/mutate-render-list"); const dir = join(Deno.cwd(), renderDir); @@ -76,4 +76,24 @@ testQuartoCmd( verifyPath(path); safeRemoveIfExists(path); } - }); \ No newline at end of file + }); + + testQuartoCmd( + "render", + [docs("project/prepost/issue-10828")], + [], + { + env: { + "QUARTO_USE_FILE_FOR_PROJECT_INPUT_FILES": normalizePath(docs("project/prepost/issue-10828/input-files.txt")), + "QUARTO_USE_FILE_FOR_PROJECT_OUTPUT_FILES": normalizePath(docs("project/prepost/issue-10828/output-files.txt")) + }, + teardown: async () => { + const inputPath = normalizePath(docs("project/prepost/issue-10828/input-files.txt")); + const outputPath = normalizePath(docs("project/prepost/issue-10828/output-files.txt")); + verifyPath(inputPath); + safeRemoveIfExists(inputPath); + verifyPath(outputPath); + safeRemoveIfExists(outputPath); + } + } + ) \ No newline at end of file