Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ All changes included in 1.7:
- A new folder `quarto-session-temp` can be created in `.quarto` to store temporary files created by Quarto during a rendering. Reminder: `.quarto` is for internal use of Quarto and should not be versioned (thus added to `.gitignore`).
- ([fb38eb5](https://github.com/quarto-dev/quarto-cli/commit/fb38eb56c11e09f44cef58fd3b697ff24bb5a3f3)) Use the `latest` parser for Acorn when analyzing JS code imported from OJS blocks.
- ([#7260](https://github.com/quarto-dev/quarto-cli/issues/7260)): Add support for `active` class in tabsets so the `.active` tab shows up by default.
- ([#7757](https://github.com/quarto-dev/quarto-cli/issues/7757)): Session temporary files are now cleaned up when the session ends abnormally (e.g. `Ctrl+C`) also on Windows.
- ([#8613](https://github.com/quarto-dev/quarto-cli/issues/8613)): Fix `giscus` color on load to support dark mode (by @kv9898).
- ([#9867](https://github.com/quarto-dev/quarto-cli/issues/9867)): Blank lines are now trimmed in Raw HTML Table blocks.
- ([#10532](https://github.com/quarto-dev/quarto-cli/issues/10532)): Changed default of `--headless=old` to `--headless` as [Chrome 132 has removed old headless mode](https://developer.chrome.com/blog/removing-headless-old-from-chrome) and only support new mode. To use old mode, set `QUARTO_CHROMIUM` to a [new `chrome-headless-shell` binary](https://developer.chrome.com/blog/chrome-headless-shell) or to an older chrome version (between 128 and 132). Set `QUARTO_CHROMIUM_HEADLESS_MODE` to `old` to use old headless mode with that compatible version.
Expand Down
6 changes: 5 additions & 1 deletion src/core/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ export async function mainRunner(runner: Runner) {
await initializeLogger(logOptions(args));

// install termination signal handlers

// Even though windows doesn't technically have signals, Deno
// does the "expected" thing here and calls abend
// on interruption.
Deno.addSignalListener("SIGINT", abend);
if (!isWindows) {
Deno.addSignalListener("SIGINT", abend);
Deno.addSignalListener("SIGTERM", abend);
}

Expand Down
15 changes: 15 additions & 0 deletions src/core/once.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* once.ts
*
* Copyright (C) 2025 Posit Software, PBC
*/

export const once = (fn: () => void) => {
let called = false;
return () => {
if (!called) {
called = true;
fn();
}
};
};
19 changes: 12 additions & 7 deletions src/project/project-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ import { makeTimedFunctionAsync } from "../core/performance/function-times.ts";
import { createProjectCache } from "../core/cache/cache.ts";
import { createTempContext } from "../core/temp.ts";

import { onCleanup } from "../core/cleanup.ts";
import { once } from "../core/once.ts";

export async function projectContext(
path: string,
notebookContext: NotebookContext,
Expand Down Expand Up @@ -314,11 +317,11 @@ export async function projectContext(
isSingleFile: false,
diskCache: await createProjectCache(join(dir, ".quarto")),
temp,
cleanup: () => {
cleanup: once(() => {
cleanupFileInformationCache(result);
result.diskCache.close();
temp.cleanup();
},
}),
};

// see if the project [kProjectType] wants to filter the project config
Expand Down Expand Up @@ -357,7 +360,7 @@ export async function projectContext(
config: configFiles,
configResources: projectConfigResources(dir, projectConfig, type),
};

onCleanup(result.cleanup);
return result;
} else {
debug(`projectContext: Found Quarto project in ${dir}`);
Expand Down Expand Up @@ -408,11 +411,11 @@ export async function projectContext(
isSingleFile: false,
diskCache: await createProjectCache(join(dir, ".quarto")),
temp,
cleanup: () => {
cleanup: once(() => {
cleanupFileInformationCache(result);
result.diskCache.close();
temp.cleanup();
},
}),
};
const { files, engines } = await projectInputFiles(
result,
Expand All @@ -425,6 +428,7 @@ export async function projectContext(
config: configFiles,
configResources: projectConfigResources(dir, projectConfig),
};
onCleanup(result.cleanup);
return result;
}
} else {
Expand Down Expand Up @@ -486,11 +490,11 @@ export async function projectContext(
isSingleFile: false,
diskCache: await createProjectCache(join(temp.baseDir, ".quarto")),
temp,
cleanup: () => {
cleanup: once(() => {
cleanupFileInformationCache(context);
context.diskCache.close();
temp.cleanup();
},
}),
};
if (Deno.statSync(path).isDirectory) {
const { files, engines } = await projectInputFiles(context);
Expand All @@ -503,6 +507,7 @@ export async function projectContext(
context.files.input = [input];
}
debug(`projectContext: Found Quarto project in ${originalDir}`);
onCleanup(context.cleanup);
return context;
} else {
return undefined;
Expand Down
11 changes: 9 additions & 2 deletions src/project/types/single-file/single-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import { RenderFlags } from "../../../command/render/types.ts";
import { MappedString } from "../../../core/mapped-text.ts";
import { fileExecutionEngineAndTarget } from "../../../execute/engine.ts";
import {
cleanupFileInformationCache,
projectFileMetadata,
projectResolveBrand,
projectResolveFullMarkdownForFile,
} from "../../project-shared.ts";
import { ExecutionEngine } from "../../../execute/types.ts";
import { createProjectCache } from "../../../core/cache/cache.ts";
import { globalTempContext } from "../../../core/temp.ts";
import { once } from "../../../core/once.ts";

export async function singleFileProjectContext(
source: string,
Expand Down Expand Up @@ -77,10 +79,15 @@ export async function singleFileProjectContext(
isSingleFile: true,
diskCache: await createProjectCache(projectCacheBaseDir),
temp,
cleanup: () => {
cleanup: once(() => {
cleanupFileInformationCache(result);
result.diskCache.close();
},
}),
};
// because the single-file project is cleaned up with
// the global text context, we don't need to register it
// in the same way that we need to register the multi-file
// projects.
temp.onCleanup(result.cleanup);
return result;
}