Fix transient .quarto_ipynb files accumulating during preview#14287
Merged
Fix transient .quarto_ipynb files accumulating during preview#14287
Conversation
Preview re-renders delete the fileInformationCache entry to pick up file changes, but this loses track of the transient .quarto_ipynb path. The collision-avoidance loop in jupyter.ts target() then sees the old file on disk and creates numbered variants (_1, _2, etc.) that are never cleaned up until preview exits. Add invalidateForFile() to FileInformationCacheMap that cleans up any transient notebook file from disk before removing the cache entry. Replace the bare delete() call in renderForPreview() with this method. Fixes #14281
Document asMappedString() and createMockProjectContext() utilities for constructing Quarto types in unit tests.
cmd.ts already creates a ProjectContext for format detection (shiny routing, serveable project check). Previously this context was discarded and preview() created a second one independently — a structural redundancy that caused duplicate .quarto_ipynb files on startup when both contexts called renderFormats()/target(). Add pProject parameter to preview() (matching render()'s pContext pattern) and pass the cmd.ts context through. Derive nbContext from the project instead of creating a new one.
Documents the preview command branching (5 paths), context lifecycle, file mutation state machine, transient notebook lifecycle, and invalidateForFile role. Based on investigation for #14281.
Manual test document for verifying that .quarto_ipynb files do not accumulate during preview re-renders. Requires interactive preview session, so placed in tests/docs/manual/ (not discovered by test runners).
Generic /quarto-preview-test command for testing quarto preview with browser automation (/agent-browser preferred, Chrome DevTools MCP for deep debugging). Cross-platform, no personal setup required. Manual test matrix in tests/docs/manual/preview/README.md covers 16 scenarios across 3 priority tiers for the quarto_ipynb accumulation fix.
- Fix inconsistent verification rules in README (conditional by test type) - Add excluded-file test case (T10b) for files not in project inputs - Add PowerShell equivalents for background preview examples in skill
Use _excluded.qmd consistently in both setup and steps.
Test fixtures for T1-T10: single-file Python, project website, keep-ipynb, plain qmd, and knitr. Project scaffolded via quarto create. Skill updated with: venv activation requirement, Windows SIGINT limitation for cleanup testing, simplified background process examples.
cleanupFileInformationCache() now delegates to invalidateForFile() instead of duplicating the same transient-check logic. Add tests for invalidateForFile() with no-target entries and missing keys.
Collaborator
Author
|
Note: #11597 reports the same symptom (stray |
Add YAML frontmatter (main_commit, analyzed_date, key_files) per llm-docs maintenance rules. Update cleanupFileInformationCache description to reflect delegation to invalidateForFile.
Regression fix: transient .quarto_ipynb accumulation during preview. Command improvement: eliminate duplicate context creation on startup.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When previewing a
.qmdfile with Jupyter execution (Python/Julia), transient.quarto_ipynbfiles accumulate in the source directory:test.quarto_ipynb,test.quarto_ipynb_1,test.quarto_ipynb_2, etc. Each re-render creates a new numbered variant that persists on disk even withkeep-ipynb: false. Regression from v1.8.27 to v1.9.Root Cause
Two interacting changes from #13804:
A collision-avoidance loop in
jupyter.tstarget()creates numbered suffixes (_1,_2) when the target.quarto_ipynbalready exists on disk.renderForPreview()callsfileInformationCache.delete(file)before each re-render to pick up file changes. This removes the cache entry (losing track of which.quarto_ipynbwas previously created) but does not delete the old file from disk. On the next render,target()sees the old file viaexistsSyncand increments the counter.Additionally,
cmd.tscreates aProjectContextfor format detection (shiny routing, serveable project check), then discards it when callingpreview().preview()creates a second independent context. The first context's.quarto_ipynbis orphaned on disk, causing a duplicate at startup. This double-context pattern pre-dates #13804 but was invisible becausetarget()always reused the same filename.Fix
Add
invalidateForFile()method toFileInformationCacheMapthat deletes any transient notebook file from disk before removing the cache entry.renderForPreview()now calls this instead of baredelete(). This fix is backported tov1.9in a separate PR since the regression was introduced there.Pass the
ProjectContextfromcmd.tstopreview()via a newpProjectparameter (matchingrender()'s existingpContextpattern). This eliminates the redundant second context creation. This is a structural improvement not backported tov1.9.Test Plan
invalidateForFile()(transient file deleted, non-transient preserved).quarto_ipynbcreated.quarto_ipynbcreatedFixes #14281