hosts/memory-bank/systemPatterns.md
2025-07-29 13:50:55 +02:00

6.1 KiB

System Patterns: hosts

System Architecture

Layered Architecture

┌─────────────────────────────────────┐
│             TUI Layer               │  ← User Interface (Textual)
├─────────────────────────────────────┤
│           Manager Layer             │  ← Orchestration & Operations
├─────────────────────────────────────┤
│            Core Layer               │  ← Business Logic
├─────────────────────────────────────┤
│           System Layer              │  ← File I/O & DNS
└─────────────────────────────────────┘

Component Relationships

TUI Layer (src/hosts/tui/)

  • views.py: Main application views and widgets
  • Responsibilities: User interaction, display logic, event handling
  • Dependencies: Manager layer for operations

Manager Layer (src/hosts/core/manager.py)

  • Responsibilities: Coordinate operations, maintain application state
  • Dependencies: Core models, parser, DNS resolver
  • Patterns: Command pattern for operations, Observer for state changes

Core Layer (src/hosts/core/)

  • models.py: Data structures (Entry, Comment, HostsFile)
  • parser.py: Hosts file parsing and serialization
  • dns.py: DNS resolution and IP comparison
  • Responsibilities: Pure business logic, no I/O dependencies

System Layer

  • File I/O: Direct /etc/hosts file operations
  • DNS Resolution: Network calls for hostname resolution
  • Permission Management: Sudo privilege handling

Key Technical Decisions

Data Model Design

@dataclass
class HostEntry:
    ip_address: str
    hostnames: list[str]
    comment: str | None = None
    is_active: bool = True
    dns_name: str | None = None  # For CNAME-like functionality
    
@dataclass
class HostsFile:
    entries: list[HostEntry]
    header_comments: list[str]
    footer_comments: list[str]

State Management

  • Immutable operations: All modifications return new state
  • Validation pipeline: Every change goes through validation
  • Undo/Redo capability: Maintain operation history
  • Dirty state tracking: Know when changes need saving

Permission Model

class PermissionManager:
    def __init__(self):
        self.edit_mode = False
        self.sudo_acquired = False
    
    def enter_edit_mode(self) -> bool:
        # Request sudo permissions
        # Set edit_mode = True only if successful
    
    def exit_edit_mode(self):
        # Release sudo permissions
        # Set edit_mode = False

Design Patterns in Use

Command Pattern

class Command(ABC):
    @abstractmethod
    def execute(self) -> HostsFile:
        pass
    
    @abstractmethod
    def undo(self) -> HostsFile:
        pass

class ToggleEntryCommand(Command):
    def __init__(self, entry_index: int):
        self.entry_index = entry_index
    
    def execute(self, hosts_file: HostsFile) -> HostsFile:
        # Toggle entry active state
    
    def undo(self, hosts_file: HostsFile) -> HostsFile:
        # Reverse the toggle

Observer Pattern

class HostsManager:
    def __init__(self):
        self.observers: list[Observer] = []
        self.state: HostsFile = HostsFile()
    
    def notify_observers(self, event: StateChangeEvent):
        for observer in self.observers:
            observer.on_state_change(event)

Factory Pattern

class ParserFactory:
    @staticmethod
    def create_parser(file_path: str) -> HostsParser:
        # Return appropriate parser based on file format
        return StandardHostsParser(file_path)

Critical Implementation Paths

Application Startup

  1. Initialize TUI: Create Textual app instance
  2. Load hosts file: Parse /etc/hosts in read-only mode
  3. Build UI: Populate left pane with entries
  4. Enter main loop: Handle user input and events

Edit Mode Activation

  1. User triggers edit mode: Keyboard shortcut or menu
  2. Request sudo: Prompt for password if needed
  3. Validate permissions: Ensure write access to /etc/hosts
  4. Update UI state: Enable edit operations
  5. Maintain permissions: Keep sudo active until exit

Entry Modification

  1. User action: Toggle, reorder, or edit entry
  2. Create command: Instantiate appropriate command object
  3. Validate operation: Check if change is valid
  4. Execute command: Apply change to in-memory state
  5. Update UI: Refresh display to show changes
  6. Track dirty state: Mark file as needing save

File Persistence

  1. User saves: Explicit save command or auto-save
  2. Validate entire file: Ensure no syntax errors
  3. Create backup: Optional backup of original file
  4. Write atomically: Use temporary file + rename
  5. Verify write: Confirm file was written correctly

DNS Resolution Flow

  1. User requests resolution: For entry with DNS name
  2. Resolve hostname: Use socket.gethostbyname()
  3. Compare IPs: Current IP vs resolved IP
  4. Present choice: Show user both options
  5. Update entry: Apply user's choice
  6. Mark dirty: Flag file for saving

Error Handling Patterns

Graceful Degradation

  • Permission denied: Fall back to read-only mode
  • DNS resolution failure: Show error but continue
  • File corruption: Load what's possible, warn user
  • Network unavailable: Disable DNS features

User Feedback

  • Status bar: Show current mode and operation status
  • Modal dialogs: For errors requiring user attention
  • Inline validation: Real-time feedback on input
  • Progress indicators: For long-running operations

Recovery Mechanisms

  • Undo operations: Allow reverting recent changes
  • File restoration: Restore from backup if available
  • Safe mode: Minimal functionality if errors occur
  • Graceful exit: Always attempt to save valid changes