Write the GUI text and CSV exports atomically - #127
Merged
Merged
Conversation
Both exports opened the chosen file directly, which truncates an existing report before the new one is complete. If the write then failed, the warning appeared but the previous report was already gone. The CLI reports, journals, plans and settings already used AtomicArtifactFile; these two paths did not. The exports now write through WriteExportFile, which stages the report in a temporary file and installs it only when it is complete. The save dialog, encodings, BOM policy and row scope are unchanged. The new tests fail a mid-write error against the old behaviour, leaving the previous report untouched and no staging file behind. BL-24 now records that its "all saved files" claim missed these two exports. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The atomic install would clear a read-only flag or swap a link for a regular file, where the previous direct write failed or wrote through. WriteExportFile now refuses both with a message, so exports keep that protection. The text export's encoding and line format move into internal members that the handler and the tests both use, so the tests no longer duplicate them and now compare exact bytes. New cases cover a missing folder, a read-only report and a link. BL-24's note is reworded: it says why it is folded into BL-24 and that the tests never ran against the original code, only against the direct write re-created behind the same method. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
new StreamWriter(path, false, encoding), which truncates an existing report before the new one is complete. A failed write showed the warning, but the previous report was already gone.MainForm.WriteExportFile, which usesAtomicArtifactFile.Write: the report is staged in a temporary file and installed only when complete. Save dialog, encodings, BOM policy, row scope and menu labels are unchanged.Behaviour decisions
WriteExportFilereturns "is read-only" and leaves the file and its flag alone.WriteExportFilereturns "is a link" and writes nothing. Conversion already refuses reparse points.Testability
MainForm.TextExportEncodingandMainForm.WriteTextExport, which the handler and the tests both use, so the tests no longer duplicate the handler and compare exact bytes.Ledger
BL-24 claimed all saved report types used the atomic writer. Its note now records this GUI gap, why it is folded into BL-24, and that
GuiExportWriteTestsnever ran against the original code (the method they call did not exist); with the direct write re-created behind the same method, the mid-write failure tests fail.Verification
GuiExportWriteTests(12): exact bytes for new and replaced reports (TXT and CSV), the line format, a write that fails part way leaves the previous bytes and no staging file, a failed new report leaves nothing, a held-open report, a missing folder, a read-only report, a linked destination.Limits
SaveFileDialogaround the write is not exercised.WriteExportFileis the step both handlers call.🤖 Generated with Claude Code