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
4 changes: 4 additions & 0 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ 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.

### `jupyter`

- ([#12114](https://github.com/quarto-dev/quarto-cli/issues/12114)): `JUPYTERCACHE` environment variable from [Jupyter cache CLI](https://jupyter-cache.readthedocs.io/en/latest/using/cli.html) is now respected by Quarto when `cache: true` is used. This environment variable allows to change the path of the cache directory.

## Other Fixes and Improvements

- ([#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.
Expand Down
4 changes: 3 additions & 1 deletion src/resources/jupyter/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ def retrieve_nb_from_cache(nb, status, input, **kwargs):
if not get_cache:
raise ImportError('The jupyter-cache package is required for cached execution')
trace('getting cache')
nb_cache = get_cache(".jupyter_cache")
# Respect env var used to modify default cache dir
# https://jupyter-cache.readthedocs.io/en/latest/using/cli.html
nb_cache = get_cache(os.getenv('JUPYTERCACHE', '.jupyter_cache'))
if not cache == "refresh":
cached_nb = nb_from_cache(nb, nb_cache)
if cached_nb:
Expand Down
1 change: 1 addition & 0 deletions tests/docs/jupyter/cache-non-default/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.quarto/
1 change: 1 addition & 0 deletions tests/docs/jupyter/cache-non-default/_environment
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JUPYTERCACHE=".cache/jupyter-cache"
2 changes: 2 additions & 0 deletions tests/docs/jupyter/cache-non-default/_quarto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
project:
type: default
8 changes: 8 additions & 0 deletions tests/docs/jupyter/cache-non-default/test.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: test1
cache: true
---

```{python}
1+1
```
76 changes: 70 additions & 6 deletions tests/smoke/jupyter/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,86 @@
*
* Copyright (C) 2023 Posit Software, PBC
*/
import { dirname, join } from "path";
import { quarto } from "../../../src/quarto.ts";
import { test } from "../../test.ts";
import { assertEquals } from "testing/asserts";
import { docs } from "../../utils.ts";
import { folderExists, printsMessage } from "../../verify.ts";
import { fileLoader } from "../../utils.ts";
import { safeExistsSync, safeRemoveSync } from "../../../src/core/path.ts";

const testInput = fileLoader("jupyter", "cache")("test.qmd", "html")
const cacheFolder = join(dirname(testInput.input), ".jupyter_cache")

test({
name: "jupyter:cache:test-1",
context: {},
name: "Jupyter cache is working",
execute: async () => {
// return await new Promise((_resolve, reject) => {
// setTimeout(reject, 10000, "timed out after 10 seconds");
// })
// https://github.com/quarto-dev/quarto-cli/issues/9618
// repeated executions to trigger jupyter cache
await quarto(["render", "docs/jupyter/cache/test.qmd", "--no-execute-daemon"]);
await quarto(["render", "docs/jupyter/cache/test.qmd", "--no-execute-daemon"]);
await quarto(["render", testInput.input, "--to", "html", "--no-execute-daemon"]);
await quarto(["render", testInput.input, "--to", "html", "--no-execute-daemon"]);
},
context: {
teardown: async () => {
if (safeExistsSync(cacheFolder)) {
safeRemoveSync(cacheFolder, { recursive: true });
}
if (safeExistsSync(testInput.output.outputPath)) {
safeRemoveSync(testInput.output.outputPath);
}
if (safeExistsSync(testInput.output.supportPath)) {
safeRemoveSync(testInput.output.supportPath, { recursive: true });
}
}
},
verify: [],
verify: [
folderExists(cacheFolder),
// this will check only for the second render that should be read from cache
printsMessage("INFO", /Notebook read from cache/)
],
type: "smoke",
});

// -- Testing changing cache folder

const testInput2 = fileLoader("jupyter", "cache-non-default")("test.qmd", "html")
// From value of cache set in _environment in test quarto project
const cacheFolder2 = join(dirname(testInput2.input), ".cache/jupyter-cache")

test({
name: "Jupyter cache folder can be change",
execute: async () => {
// return await new Promise((_resolve, reject) => {
// setTimeout(reject, 10000, "timed out after 10 seconds");
// })
// https://github.com/quarto-dev/quarto-cli/issues/9618
// repeated executions to trigger jupyter cache
await quarto(["render", testInput2.input, "--to", "html", "--no-execute-daemon"]);
await quarto(["render", testInput2.input, "--to", "html", "--no-execute-daemon"]);
},
context: {
teardown: async () => {
if (safeExistsSync(cacheFolder2)) {
safeRemoveSync(cacheFolder2, { recursive: true });
}
if (safeExistsSync(testInput2.output.outputPath)) {
safeRemoveSync(testInput2.output.outputPath);
}
if (safeExistsSync(testInput2.output.supportPath)) {
safeRemoveSync(testInput2.output.supportPath, { recursive: true });
}
if (safeExistsSync(join(dirname(testInput2.input), ".quarto"))) {
safeRemoveSync(join(dirname(testInput2.input), ".quarto"), { recursive: true });
}
}
},
verify: [
folderExists(cacheFolder2),
// this will check only for the second render that should be read from cache
printsMessage("INFO", /Notebook read from cache/)
],
type: "smoke",
});