fix(project): prevent output-dir: ./ from deleting project directory #13895
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
_quarto.ymlcontainsoutput-dir: ./, runningquarto renderwould delete the entire project directory, leaving only an empty.quarto/directory.Root Cause
Two compounding issues in the output directory handling:
project-context.ts:306-308only checked for exact string".":This missed
"./"and other equivalent variations.project.ts:287-291used string comparison:After path normalization,
.and./produce different strings (e.g.,C:\projectvsC:\project\), causing the safety check to incorrectly pass.Why
resolve()instead ofnormalize()We verified empirically that
normalize()doesn't work for this case:normalize("./")→.\on Windows (keeps trailing separator)normalize(".")→.But
resolve()correctly handles all variations:resolve(dir, ".")andresolve(dir, "./")both → same absolute pathFix Approach
Use
resolve()for path comparison - handles all current-directory variations (.,./,.\,././, etc.)Replace
removeIfExistswithsafeRemoveDirSyncas defense in depth - this function uses properisSubdirboundary checking and throwsUnsafeRemovalErrorif someone attempts to delete the project directoryTest Plan
resolve()behavior for path equivalence (platform-aware:.\only tested on Windows)output-dir: ./,output-dir: ., andoutput-dir: _outputFixes #13892