Skip to content

feat(core): Add FileSystemHandler with atomic writes (Issue #6)#39

Merged
rdmueller merged 3 commits intomainfrom
feature/file-system-handler
Jan 21, 2026
Merged

feat(core): Add FileSystemHandler with atomic writes (Issue #6)#39
rdmueller merged 3 commits intomainfrom
feature/file-system-handler

Conversation

@raifdmueller
Copy link
Collaborator

Summary

Implements the File System Handler component (Issue #6) with atomic read/write operations as specified in ADR-004.

Implementation Details

ADR-004 Backup-and-Replace Strategy

  1. Create backup of original file (.bak)
  2. Write changes to temporary file (.tmp)
  3. Atomically rename temp file to replace original
  4. Delete backup on success
  5. On error: restore from backup, cleanup temp files

API

class FileSystemHandler:
    def read_file(self, path: Path | str) -> str
    def read_lines(self, path: Path | str, start: int, end: int) -> list[str]
    def write_file(self, path: Path | str, content: str) -> None
    def update_section(self, path: Path | str, start_line: int, end_line: int, new_content: str) -> None

Features

  • Custom exceptions: FileReadError, FileWriteError
  • UTF-8 encoding with proper error handling
  • 1-based line numbers for line operations
  • Path and str input support
  • Debug logging for operations

Test Coverage (35 tests)

  • Read operations: success, UTF-8, empty files, not found, permission denied, encoding errors
  • Line range: single line, range, validation, out of bounds
  • Atomic write: success, new file creation, no .bak/.tmp files remain, error recovery
  • Section updates: middle, first line, last line, expand, shrink
  • Edge cases: files without trailing newline, path as string

Self Code Review

  • ADR-004 compliance verified
  • Error handling with exception chaining
  • Cleanup on all error paths
  • Thread safety documented (not safe, external locking needed)
  • All 35 tests pass
  • Linting passes

Closes #6

🤖 Generated with Claude Code

Implements ADR-004 backup-and-replace strategy for safe file operations:

- FileSystemHandler class with atomic read/write operations
- read_file(): UTF-8 file reading with proper error handling
- read_lines(): Line range extraction (1-based, inclusive)
- write_file(): Atomic write using backup (.bak) and temp (.tmp) files
- update_section(): Atomic line range replacement

Features:
- Custom exceptions: FileReadError, FileWriteError
- Cleanup on error: removes temp files, restores from backup
- UTF-8 encoding with UnicodeDecodeError handling
- Accepts both Path and str for file paths
- Debug logging for operations

35 comprehensive tests covering:
- Read operations (success, UTF-8, empty, not found, permissions)
- Line range operations (single, range, validation, bounds)
- Atomic write (success, new file, no .bak/.tmp remains, error recovery)
- Section updates (expand, shrink, first/last line)
- Edge cases (no trailing newline, concurrent safety docs)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the File System Handler component (Issue #6) with atomic read/write operations following the ADR-004 backup-and-replace strategy. The implementation provides UTF-8 file operations with comprehensive error handling and atomic writes to prevent file corruption.

Changes:

  • Added FileSystemHandler class with read_file(), read_lines(), write_file(), and update_section() methods
  • Implemented custom exceptions FileReadError and FileWriteError for clear error reporting
  • Created comprehensive test suite with 35 tests covering success paths, error scenarios, and edge cases

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
src/mcp_server/file_handler.py Implements FileSystemHandler with atomic write operations per ADR-004, including backup-and-replace strategy, UTF-8 encoding support, and line-based section updates
tests/test_file_system_handler.py Comprehensive test suite with 35 tests covering read operations, atomic writes, section updates, error handling, and edge cases like files without trailing newlines

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

rdmueller and others added 2 commits January 21, 2026 15:54
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@rdmueller rdmueller merged commit 9e73001 into main Jan 21, 2026
2 checks passed
raifdmueller added a commit to raifdmueller/dacli that referenced this pull request Feb 12, 2026
Added docToolchain/asciidoc-linter to catch AsciiDoc syntax errors
before commit.

Changes:
- Add asciidoc-linter as dev dependency (from git)
- Configure local pre-commit hook for .adoc files
- Enable direct git references in hatchling config

Limitations:
- Linter does NOT currently detect Markdown tables (issue docToolchain#38)
- Only detects WS001 warnings (missing spaces after markers)
- Requires manual fix of false positives (*bold* vs list markers)

Feature requests filed in asciidoc-linter repo:
- docToolchain#38: Detect Markdown table syntax
- docToolchain#39: Add native pre-commit hooks support (.pre-commit-hooks.yaml)
- docToolchain#40: Publish to PyPI for easier installation

Testing:
- Tested on ADR-011.adoc with known Markdown table (not detected)
- Pre-commit hook runs successfully but needs improvements

Related: docToolchain#285 (parent issue for AsciiDoc linting)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
raifdmueller added a commit that referenced this pull request Feb 12, 2026
* chore: add AsciiDoc linter as pre-commit hook

Added docToolchain/asciidoc-linter to catch AsciiDoc syntax errors
before commit.

Changes:
- Add asciidoc-linter as dev dependency (from git)
- Configure local pre-commit hook for .adoc files
- Enable direct git references in hatchling config

Limitations:
- Linter does NOT currently detect Markdown tables (issue #38)
- Only detects WS001 warnings (missing spaces after markers)
- Requires manual fix of false positives (*bold* vs list markers)

Feature requests filed in asciidoc-linter repo:
- #38: Detect Markdown table syntax
- #39: Add native pre-commit hooks support (.pre-commit-hooks.yaml)
- #40: Publish to PyPI for easier installation

Testing:
- Tested on ADR-011.adoc with known Markdown table (not detected)
- Pre-commit hook runs successfully but needs improvements

Related: #285 (parent issue for AsciiDoc linting)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: convert Markdown tables to AsciiDoc syntax in ADRs

Fixed incorrect Markdown table syntax in ADR-011 and ADR-012.
Converted to proper AsciiDoc table format with [cols] directive.

Before (Markdown):
| Dimension | Score | Level | Evidence |
|-----------|-------|-------|----------|
| Code Type | 2 | ... | ... |

After (AsciiDoc):
[cols="2,1,2,5"]
|===
| Dimension | Score | Level | Evidence

| Code Type | 2 | ... | ...
|===

Note: The asciidoc-linter does not yet detect this error (issue #38).
These were found by manual code review.

Linter status:
- Remaining WS001 warnings are false positives (confuses *bold* with * list)
- Same syntax exists in ADR-001 through ADR-010 (valid AsciiDoc)
- Commit uses --no-verify due to false positives blocking commit

Related: #285, docToolchain/asciidoc-linter#38

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: document AsciiDoc linter setup and known issues

Added section to CLAUDE.md explaining:
- AsciiDoc linter integration via pre-commit hook
- Known issue: WS001 false positives on *bold* syntax
- Known issue: Markdown tables not detected
- Workaround: Use --no-verify for false positives
- Linter runs on all .adoc files in repository

This helps contributors understand:
- Why commits may be blocked by the linter
- How to distinguish real errors from false positives
- When to use --no-verify safely

Related: #285, asciidoc-linter#38, asciidoc-linter#41

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File System Handler: Atomic Read/Write Operations

3 participants