Compare commits
No commits in common. "b0abec730ccaaae517a3791032a9110c97b4256c" and "5a117fb6241cd7e8cecd69cf0511b7598b5532bf" have entirely different histories.
b0abec730c
...
5a117fb624
9 changed files with 315 additions and 958 deletions
6
main_old.py
Normal file
6
main_old.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
def main():
|
||||
print("Hello from hosts!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -2,59 +2,10 @@
|
|||
|
||||
## Current Work Focus
|
||||
|
||||
**Post-Phase 3 Code Quality Maintenance**: The hosts TUI application has successfully completed Phase 3 with full edit mode foundation, save confirmation functionality, and comprehensive testing (149 tests). However, 20 minor linting issues (unused imports and variables) require cleanup before proceeding to Phase 4 advanced features.
|
||||
|
||||
## Immediate Next Steps
|
||||
|
||||
### Priority 1: Code Quality Cleanup
|
||||
1. **Fix linting issues**: Run `uv run ruff check --fix` to address 20 unused import and variable warnings
|
||||
2. **Validate fixes**: Ensure all tests still pass (149 tests) after cleanup
|
||||
3. **Confirm application functionality**: Test that `uv run hosts` still works perfectly
|
||||
4. **Commit clean state**: Create commit with "Fix linting issues" once cleanup is complete
|
||||
|
||||
### Priority 2: Phase 4 Planning
|
||||
Once code quality is restored:
|
||||
1. **Advanced entry operations**: Add/delete entries with validation
|
||||
2. **Search functionality**: Find entries by hostname or IP address
|
||||
3. **Bulk operations**: Select and modify multiple entries
|
||||
4. **Help modal**: Proper modal dialog with keyboard shortcuts
|
||||
|
||||
## Memory Bank Update Summary
|
||||
|
||||
### Files Updated
|
||||
- ✅ **activeContext.md**: Updated current focus and next steps
|
||||
- ✅ **progress.md**: Corrected test count (149 vs 97), added code quality status
|
||||
- ✅ **techContext.md**: Updated development workflow and code quality status
|
||||
- ✅ **systemPatterns.md**: Added edit mode and permission management patterns
|
||||
- ✅ **projectbrief.md**: Updated test coverage details and current status
|
||||
|
||||
### Key Corrections Made
|
||||
- **Test count**: Updated from 97 to 149 tests across all files
|
||||
- **Code quality**: Noted 20 linting issues requiring cleanup
|
||||
- **Project stage**: Clarified completion of Phase 3 with save confirmation
|
||||
- **Current status**: Maintenance phase before Phase 4 development
|
||||
- **Recent commits**: Reflected completion of save confirmation modal
|
||||
|
||||
### Architecture Insights Confirmed
|
||||
- **Textual framework**: Excellent for complex TUI applications with modal dialogs
|
||||
- **Layered architecture**: Proven effective for maintainable, testable code
|
||||
- **Test-driven development**: 149 comprehensive tests enable confident refactoring
|
||||
- **Configuration system**: JSON-based persistence working reliably
|
||||
- **Permission management**: Sudo handling implemented safely and securely
|
||||
|
||||
The memory bank now accurately reflects the current state of the project, ready for the next phase of development after code quality maintenance.
|
||||
**Phase 3 Complete - Edit Mode Foundation**: The hosts TUI application now has a complete edit mode foundation with permission management, entry manipulation, and safe file operations. All keyboard shortcuts are implemented and tested. The application is ready for Phase 4 advanced edit features.
|
||||
|
||||
## Recent Changes
|
||||
|
||||
### Phase 3 Save Confirmation Enhancement ✅ COMPLETE
|
||||
- ✅ **Save confirmation modal**: Professional modal dialog asking to save, discard, or cancel when exiting edit entry mode
|
||||
- ✅ **Change detection system**: Intelligent tracking of original entry values vs. current form values
|
||||
- ✅ **No auto-save behavior**: Changes are only saved when explicitly confirmed by the user
|
||||
- ✅ **Graceful exit handling**: ESC key in edit entry mode now triggers save confirmation instead of auto-exiting
|
||||
- ✅ **Validation integration**: Full validation before saving with clear error messages for invalid data
|
||||
- ✅ **Comprehensive testing**: Save confirmation functionality fully tested (149 total tests)
|
||||
- ✅ **Modal keyboard shortcuts**: Save (S), Discard (D), Cancel (ESC) with intuitive button labels
|
||||
|
||||
### Phase 2 Implementation Complete
|
||||
- ✅ **Advanced configuration system**: Complete Config class with JSON persistence to ~/.config/hosts-manager/
|
||||
- ✅ **Professional configuration modal**: Modal dialog with keyboard bindings for settings management
|
||||
|
@ -63,7 +14,7 @@ The memory bank now accurately reflects the current state of the project, ready
|
|||
- ✅ **Rich visual interface**: Color-coded entries with professional DataTable styling
|
||||
- ✅ **Interactive column headers**: Click headers to sort data with visual feedback
|
||||
- ✅ **Enhanced status bar**: Detailed information including entry counts and file path
|
||||
- ✅ **Comprehensive testing**: 149 tests covering all functionality including new features
|
||||
- ✅ **Comprehensive testing**: 97 tests covering all functionality including new features
|
||||
|
||||
### Current Project State
|
||||
- **Production-ready application**: `uv run hosts` launches polished TUI with advanced features
|
||||
|
@ -71,24 +22,38 @@ The memory bank now accurately reflects the current state of the project, ready
|
|||
- **Professional visual design**: Color-coded entries, zebra striping, and rich text styling
|
||||
- **Interactive sorting**: Click column headers or use keyboard shortcuts to sort data
|
||||
- **Intelligent filtering**: Hide default system entries based on user preference
|
||||
- **Comprehensive test coverage**: 149 tests with 100% pass rate covering all components
|
||||
- **Code quality maintenance needed**: 20 linting issues (unused imports/variables) require cleanup
|
||||
- **Robust architecture**: Clean layered design ready for Phase 4 advanced features
|
||||
- **Comprehensive test coverage**: 97 tests with 100% pass rate covering all components
|
||||
- **Perfect code quality**: All linting and formatting standards maintained
|
||||
- **Robust architecture**: Clean layered design ready for edit mode extension
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Immediate Priority: Code Quality Cleanup
|
||||
1. **Fix linting issues**: Address 20 unused import and variable warnings
|
||||
- Remove unused imports in core/config.py, test files
|
||||
- Clean up unused variables in exception handling
|
||||
- Run `uv run ruff check --fix` to auto-fix issues
|
||||
### Phase 3: Edit Mode Foundation (Current Priority)
|
||||
1. **Permission management system**:
|
||||
- Implement sudo request and validation
|
||||
- Edit mode toggle with proper security handling
|
||||
- Permission validation and error handling
|
||||
- Graceful fallback for permission denied scenarios
|
||||
|
||||
2. **Code quality validation**:
|
||||
- Ensure all ruff checks pass with zero issues
|
||||
- Maintain perfect test coverage (149 tests passing)
|
||||
- Verify application functionality after cleanup
|
||||
2. **Basic editing operations**:
|
||||
- Toggle entries active/inactive with visual feedback
|
||||
- Entry editing interface for IP addresses, hostnames, and comments
|
||||
- Real-time validation of IP addresses and hostnames
|
||||
- Safe state management during editing
|
||||
|
||||
### Phase 4: Advanced Edit Features (Next Phase)
|
||||
3. **File safety and backup**:
|
||||
- Automatic backup before any modifications
|
||||
- Atomic file operations with rollback capability
|
||||
- Validation before writing changes to disk
|
||||
- Error recovery and restoration mechanisms
|
||||
|
||||
4. **Edit mode user interface**:
|
||||
- Clear visual indicators for edit mode vs read-only mode
|
||||
- Edit forms and dialogs for entry modification
|
||||
- Confirmation dialogs for destructive operations
|
||||
- Enhanced status feedback during edit operations
|
||||
|
||||
### Phase 4: Advanced Edit Features (Future)
|
||||
1. **Advanced editing operations**:
|
||||
- Add new entries with validation
|
||||
- Delete entries with confirmation
|
||||
|
@ -122,37 +87,8 @@ The memory bank now accurately reflects the current state of the project, ready
|
|||
- ✅ **Error handling**: Graceful degradation and user feedback throughout
|
||||
- ✅ **Modal pattern**: Professional modal dialogs with proper lifecycle management
|
||||
- ✅ **Configuration pattern**: Centralized settings with persistence and defaults
|
||||
- ✅ **Command pattern**: Implemented for edit operations with save confirmation
|
||||
- 🔄 **Observer pattern**: Will implement for state change notifications in advanced features
|
||||
|
||||
## Important Patterns and Preferences
|
||||
|
||||
### Code Quality Standards
|
||||
- **Zero tolerance for linting issues**: All ruff checks must pass before commits
|
||||
- **Comprehensive testing**: Maintain 100% test pass rate with meaningful coverage
|
||||
- **Type safety**: Full type hints throughout codebase
|
||||
- **Documentation**: Clear docstrings and inline comments for complex logic
|
||||
- **Error handling**: Graceful degradation with informative user feedback
|
||||
|
||||
### Development Workflow
|
||||
- **Test-driven development**: Write tests before implementing features
|
||||
- **Incremental implementation**: Small, focused changes with immediate testing
|
||||
- **Clean commits**: Each commit should represent a complete, working feature
|
||||
- **Memory bank maintenance**: Update documentation after significant changes
|
||||
|
||||
## Learnings and Project Insights
|
||||
|
||||
### Technical Insights
|
||||
- **Textual framework**: Excellent for rich TUI applications with reactive state management
|
||||
- **Modal system**: Professional dialog implementation requires careful focus and lifecycle management
|
||||
- **File operations**: Atomic operations and backup systems essential for system file modification
|
||||
- **Permission management**: Sudo handling requires careful security consideration and user experience design
|
||||
|
||||
### Process Insights
|
||||
- **Memory bank value**: Documentation consistency crucial for maintaining project context
|
||||
- **Testing strategy**: Comprehensive test coverage enables confident refactoring and feature addition
|
||||
- **Code quality**: Automated linting and formatting tools essential for maintaining standards
|
||||
- **Incremental development**: Small, focused phases enable better quality and easier debugging
|
||||
- 🔄 **Command pattern**: Planned for Phase 3 edit operations with undo/redo
|
||||
- 🔄 **Observer pattern**: Will implement for state change notifications in edit mode
|
||||
|
||||
### Technical Constraints Confirmed
|
||||
- ✅ **Python 3.13+**: Excellent choice with modern features working perfectly
|
||||
|
|
|
@ -39,6 +39,16 @@
|
|||
- ✅ **Modal system**: Proper modal dialogs with keyboard bindings
|
||||
- ✅ **Configuration persistence**: Settings saved to ~/.config/hosts-manager/
|
||||
|
||||
### Documentation
|
||||
- ✅ **Project brief**: Comprehensive project definition and requirements
|
||||
- ✅ **Product context**: User experience goals and problem definition
|
||||
- ✅ **Technical context**: Technology stack and development setup
|
||||
- ✅ **System patterns**: Architecture, design patterns, and implementation paths
|
||||
- ✅ **Active context**: Current work focus and next steps
|
||||
|
||||
## What's Left to Build
|
||||
|
||||
|
||||
### Phase 3: Edit Mode Foundation ✅ COMPLETE
|
||||
- ✅ **Permission management**: Sudo request and management with PermissionManager class
|
||||
- ✅ **Edit mode toggle**: Switch between read-only and edit modes with 'e' key
|
||||
|
@ -54,23 +64,7 @@
|
|||
- ✅ **Live testing**: Manual testing confirms all functionality works correctly
|
||||
- ✅ **Human-readable formatting**: Tab-based column alignment with proper spacing
|
||||
- ✅ **Management header**: Automatic addition of management header to hosts files
|
||||
- ✅ **Save confirmation modal**: Professional modal dialog for save/discard/cancel when exiting edit entry mode
|
||||
- ✅ **Change detection**: Intelligent tracking of original vs. current entry values
|
||||
- ✅ **No auto-save**: Changes saved only when explicitly confirmed by user
|
||||
|
||||
### Documentation
|
||||
- ✅ **Project brief**: Comprehensive project definition and requirements
|
||||
- ✅ **Product context**: User experience goals and problem definition
|
||||
- ✅ **Technical context**: Technology stack and development setup
|
||||
- ✅ **System patterns**: Architecture, design patterns, and implementation paths
|
||||
- ✅ **Active context**: Current work focus and next steps
|
||||
|
||||
## What's Left to Build
|
||||
|
||||
### Immediate Priority: Code Quality Cleanup
|
||||
- ❌ **Fix linting issues**: Address 20 unused import and variable warnings
|
||||
- ❌ **Code quality validation**: Ensure all ruff checks pass with zero issues
|
||||
- ❌ **Maintain test coverage**: Keep 149 tests passing during cleanup
|
||||
- ✅ **Auto-save functionality**: Immediate saving of changes when entries are edited
|
||||
|
||||
### Phase 4: Advanced Edit Features
|
||||
- ❌ **Add new entries**: Create new host entries
|
||||
|
@ -95,9 +89,19 @@
|
|||
## Current Status
|
||||
|
||||
### Development Stage
|
||||
**Stage**: Phase 3 Complete with Code Quality Maintenance Required
|
||||
**Progress**: 82% (Complete edit mode foundation with save confirmation, code cleanup needed)
|
||||
**Next Milestone**: Code quality cleanup, then Phase 4 advanced edit features
|
||||
**Stage**: Phase 3 Complete - Moving to Phase 4
|
||||
**Progress**: 75% (Complete edit mode foundation with permission management)
|
||||
**Next Milestone**: Advanced edit features (add/delete entries, bulk operations)
|
||||
|
||||
### Phase 2 Final Achievements
|
||||
1. ✅ **Advanced configuration system**: Complete settings management with persistence
|
||||
2. ✅ **Professional modal dialogs**: Configuration modal with proper keyboard bindings
|
||||
3. ✅ **Intelligent filtering**: Hide/show default system entries based on user preference
|
||||
4. ✅ **Complete sorting system**: Sort by IP address and hostname with direction toggle
|
||||
5. ✅ **Rich visual interface**: Color-coded entries with professional DataTable styling
|
||||
6. ✅ **Interactive headers**: Click column headers to sort data
|
||||
7. ✅ **Enhanced user experience**: Visual sort indicators and comprehensive status information
|
||||
8. ✅ **Robust configuration**: JSON-based settings with graceful error handling
|
||||
|
||||
### Phase 3 Final Achievements ✅ COMPLETE
|
||||
1. ✅ **Permission management**: Complete PermissionManager class with sudo request and validation
|
||||
|
@ -108,17 +112,18 @@
|
|||
6. ✅ **Manager module**: Complete HostsManager class for all edit operations
|
||||
7. ✅ **Safe file operations**: Atomic file writing with rollback capability
|
||||
8. ✅ **Enhanced error messages**: Professional read-only mode error messages with clear instructions
|
||||
9. ✅ **Comprehensive testing**: Full test coverage for manager module (149 total tests)
|
||||
10. ✅ **Save confirmation modal**: Professional save/discard/cancel dialog when exiting edit entry mode
|
||||
11. ✅ **Change detection system**: Intelligent tracking of original vs. current entry values
|
||||
12. ✅ **No auto-save behavior**: User-controlled saving with explicit confirmation
|
||||
9. ✅ **Comprehensive testing**: 38 new tests for manager module (135 total tests)
|
||||
|
||||
### Current Project State
|
||||
- **Application functionality**: Fully functional with advanced edit capabilities
|
||||
- **Test coverage**: 149 tests with 100% pass rate covering all functionality
|
||||
- **Code quality issue**: 20 linting issues (unused imports/variables) need cleanup
|
||||
- **Architecture**: Robust layered design ready for Phase 4 advanced features
|
||||
- **User experience**: Professional TUI with modal dialogs and comprehensive keyboard shortcuts
|
||||
### Recent Major Accomplishments
|
||||
- ✅ **Complete Phase 3 implementation**: Full edit mode foundation with permission management
|
||||
- ✅ **Manager module**: PermissionManager and HostsManager classes with comprehensive functionality
|
||||
- ✅ **Edit mode integration**: Seamless integration with main TUI application
|
||||
- ✅ **Permission system**: Robust sudo request, validation, and release functionality
|
||||
- ✅ **File backup system**: Automatic backup creation with timestamp naming
|
||||
- ✅ **Entry manipulation**: Toggle active/inactive and reorder entries safely
|
||||
- ✅ **Comprehensive testing**: 135 total tests with 100% pass rate including edit operations
|
||||
- ✅ **Error handling**: Graceful handling of permission errors and file operations
|
||||
- ✅ **Keyboard shortcuts**: Complete set of edit mode bindings (e, space, Ctrl+Up/Down, Ctrl+S)
|
||||
|
||||
## Technical Implementation Details
|
||||
|
||||
|
@ -131,13 +136,11 @@
|
|||
### Test Coverage Excellence
|
||||
- **Models**: 27 comprehensive tests covering all data model edge cases
|
||||
- **Parser**: 15 tests covering file operations, permissions, and error conditions
|
||||
- **Manager**: Comprehensive tests for permission management and edit operations
|
||||
- **UI Components**: Full coverage of modal dialogs and TUI interactions
|
||||
- **Total**: 149 tests with 100% pass rate and comprehensive edge case coverage
|
||||
- **Coverage**: 100% of core functionality with edge case validation
|
||||
- **Quality**: All tests passing consistently with fast execution
|
||||
|
||||
### Code Quality Standards
|
||||
- **Linting**: 20 minor issues (unused imports/variables) requiring cleanup
|
||||
- **Linting**: Perfect ruff compliance with zero issues
|
||||
- **Type hints**: Complete type coverage throughout entire codebase
|
||||
- **Documentation**: Comprehensive docstrings and inline comments
|
||||
- **Error handling**: Graceful exception handling with user feedback
|
||||
|
@ -145,14 +148,7 @@
|
|||
|
||||
## Known Issues
|
||||
|
||||
### Immediate Code Quality Issues
|
||||
- **Linting warnings**: 20 unused import and variable warnings in core and test files
|
||||
- **Code standard compliance**: Must address before proceeding to Phase 4
|
||||
- **Auto-fixable**: All issues can be resolved with `uv run ruff check --fix`
|
||||
|
||||
### Phase 4 Enhancement Opportunities
|
||||
- **Add new entries**: Create new host entries with validation (planned for Phase 4)
|
||||
- **Delete entries**: Remove host entries with confirmation (planned for Phase 4)
|
||||
### Phase 3 Enhancement Opportunities
|
||||
- **Search functionality**: Find entries by hostname or IP address (planned for Phase 4)
|
||||
- **Help modal**: Proper help dialog instead of status message (planned for Phase 4)
|
||||
- **Large file performance**: Not yet tested with very large hosts files
|
||||
|
|
|
@ -81,7 +81,7 @@ hosts/
|
|||
- Mock `/etc/hosts` file I/O and DNS lookups to avoid system dependencies.
|
||||
- Include integration tests for the Textual TUI (using `textual.testing` or snapshot testing).
|
||||
|
||||
### Implemented Tests (149 tests total)
|
||||
### Implemented Tests (97 tests total)
|
||||
|
||||
1. **Parsing Tests** (15 tests):
|
||||
- Parse simple `/etc/hosts` with comments and disabled entries
|
||||
|
@ -101,39 +101,20 @@ hosts/
|
|||
- Configuration loading and saving
|
||||
- Default entry detection and filtering
|
||||
|
||||
4. **TUI Application Tests** (28 tests):
|
||||
- Main application initialization and startup
|
||||
4. **Modal Dialog Tests** (15 tests):
|
||||
- Configuration modal lifecycle
|
||||
- User interaction handling
|
||||
- Keyboard binding validation
|
||||
- State management during configuration changes
|
||||
|
||||
5. **Main Application Tests** (18 tests):
|
||||
- Application initialization and startup
|
||||
- File loading and error handling
|
||||
- User interface state management
|
||||
- Sorting and navigation functionality
|
||||
- Modal dialog lifecycle and interactions
|
||||
- Keyboard binding validation
|
||||
|
||||
5. **Manager Module Tests** (38 tests):
|
||||
- Permission management and sudo handling
|
||||
- Edit mode operations and state transitions
|
||||
- File backup and atomic operations
|
||||
- Entry manipulation and validation
|
||||
|
||||
6. **Save Confirmation Tests** (13 tests):
|
||||
- Modal dialog lifecycle and user interactions
|
||||
- Change detection and validation
|
||||
- Save/discard/cancel functionality
|
||||
- Integration with edit workflow
|
||||
|
||||
7. **Configuration Modal Tests** (6 tests):
|
||||
- Modal configuration interface
|
||||
- Settings persistence and validation
|
||||
- User interaction handling
|
||||
|
||||
### Current Test Coverage Status
|
||||
- **Total Tests**: 149 comprehensive tests
|
||||
- **Pass Rate**: 100% (all tests passing)
|
||||
- **Coverage Areas**: Core models, file parsing, configuration, TUI components, edit operations, modal dialogs
|
||||
- **Code Quality**: 20 minor linting issues (unused imports/variables) requiring cleanup
|
||||
|
||||
### Future Test Areas (Planned)
|
||||
- **Advanced Edit Tests**: Add/delete entries, bulk operations
|
||||
- **Edit Mode Tests**: Permission management and file modification
|
||||
- **DNS Resolution Tests**: Hostname resolution and IP comparison
|
||||
- **Performance Tests**: Large file handling and optimization
|
||||
- **Search Functionality Tests**: Entry searching and filtering
|
||||
- **Integration Tests**: End-to-end workflow testing
|
||||
|
|
|
@ -34,9 +34,8 @@
|
|||
#### System Layer (Implemented)
|
||||
- ✅ **File I/O**: Atomic file operations with backup support
|
||||
- ✅ **Permission checking**: Validation of file access permissions
|
||||
- ✅ **Permission management**: Sudo request and handling for edit mode
|
||||
- ✅ **Backup system**: Automatic backup creation before modifications
|
||||
- 🔄 **DNS Resolution**: Planned for Phase 5 advanced features
|
||||
- 🔄 **Permission Management**: Sudo handling planned for Phase 3 edit mode
|
||||
|
||||
## Key Technical Decisions
|
||||
|
||||
|
@ -94,13 +93,10 @@ class Config:
|
|||
- ✅ **Reactive state**: Using Textual's reactive attributes for complex UI updates
|
||||
- ✅ **Configuration state**: Persistent settings with JSON storage and graceful error handling
|
||||
- ✅ **Sorting state**: Reactive sort column and direction with visual indicators
|
||||
- ✅ **Edit mode state**: Safe transitions between read-only and edit modes
|
||||
- ✅ **Permission state**: Sudo request, validation, and release management
|
||||
- ✅ **Validation pipeline**: All data validated in models, parser, and configuration
|
||||
- ✅ **File integrity**: Atomic operations preserve file structure
|
||||
- ✅ **Error handling**: Graceful degradation for all error conditions
|
||||
- ✅ **Modal state**: Professional modal dialog lifecycle management
|
||||
- ✅ **Change detection**: Intelligent tracking for save confirmation
|
||||
- 🔄 **Undo/Redo capability**: Planned for Phase 4 with command pattern
|
||||
- 🔄 **Dirty state tracking**: Will be implemented in Phase 3 edit mode
|
||||
|
||||
|
|
|
@ -32,13 +32,13 @@ hosts/
|
|||
### Current State
|
||||
- ✅ **Complete uv project**: Python 3.13 with full dependency management
|
||||
- ✅ **Production application**: Fully functional TUI with advanced features and professional interface
|
||||
- ✅ **Code quality maintenance required**: 20 linting issues (unused imports/variables) need cleanup
|
||||
- ✅ **Perfect code quality**: All ruff checks passing with zero issues
|
||||
- ✅ **Proper project structure**: Well-organized src/hosts/ package with core and tui modules
|
||||
- ✅ **Comprehensive testing**: 149 tests covering all functionality including new features
|
||||
- ✅ **Comprehensive testing**: 97 tests covering all functionality including new features
|
||||
- ✅ **Entry point configured**: `hosts` command launches application perfectly
|
||||
- ✅ **Configuration system**: Complete settings management with JSON persistence
|
||||
- ✅ **Modal interface**: Professional configuration dialogs with keyboard bindings
|
||||
- ✅ **Advanced features**: Sorting, filtering, edit mode, and save confirmation
|
||||
- ✅ **Advanced features**: Sorting, filtering, and rich visual interface
|
||||
|
||||
### Runtime Management
|
||||
- ✅ **uv run hosts**: Command executes application instantly
|
||||
|
@ -94,17 +94,11 @@ hosts = "hosts.main:main"
|
|||
|
||||
### Development Workflow
|
||||
1. ✅ **uv run hosts**: Execute the application - launches instantly
|
||||
2. 🔧 **uv run ruff check**: Lint code - 20 issues need fixing
|
||||
2. ✅ **uv run ruff check**: Lint code - all checks passing perfectly
|
||||
3. ✅ **uv run ruff format**: Auto-format code - consistent style maintained
|
||||
4. ✅ **uv run pytest**: Run test suite - 149 tests passing with 100% success rate
|
||||
4. ✅ **uv run pytest**: Run test suite - 42 tests passing with 100% success rate
|
||||
5. ✅ **uv add**: Add dependencies - seamless dependency management
|
||||
|
||||
### Code Quality Status
|
||||
- **Current issues**: 20 linting warnings (unused imports and variables)
|
||||
- **Auto-fixable**: All issues can be resolved with `uv run ruff check --fix`
|
||||
- **Test coverage**: 149 comprehensive tests with 100% pass rate
|
||||
- **Code formatting**: Perfect formatting compliance maintained
|
||||
|
||||
### Code Quality Achieved
|
||||
- ✅ **ruff configuration**: Perfect compliance with zero issues across all modules
|
||||
- ✅ **Type hints**: Complete type coverage throughout entire codebase including new components
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,122 +0,0 @@
|
|||
"""
|
||||
Save confirmation modal for the hosts TUI application.
|
||||
|
||||
This module provides a modal dialog to confirm saving changes when exiting edit entry mode.
|
||||
"""
|
||||
|
||||
from textual.app import ComposeResult
|
||||
from textual.containers import Vertical, Horizontal
|
||||
from textual.widgets import Static, Button, Label
|
||||
from textual.screen import ModalScreen
|
||||
from textual.binding import Binding
|
||||
|
||||
|
||||
class SaveConfirmationModal(ModalScreen):
|
||||
"""
|
||||
Modal screen for save confirmation when exiting edit entry mode.
|
||||
|
||||
Provides a confirmation dialog asking whether to save or discard changes.
|
||||
"""
|
||||
|
||||
CSS = """
|
||||
SaveConfirmationModal {
|
||||
align: center middle;
|
||||
}
|
||||
|
||||
.save-confirmation-container {
|
||||
width: 60;
|
||||
height: 15;
|
||||
background: $surface;
|
||||
border: thick $primary;
|
||||
padding: 1;
|
||||
}
|
||||
|
||||
.save-confirmation-title {
|
||||
text-align: center;
|
||||
text-style: bold;
|
||||
color: $primary;
|
||||
margin-bottom: 1;
|
||||
}
|
||||
|
||||
.save-confirmation-message {
|
||||
text-align: center;
|
||||
margin-bottom: 2;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.button-row {
|
||||
align: center middle;
|
||||
}
|
||||
|
||||
.save-confirmation-button {
|
||||
margin: 0 1;
|
||||
min-width: 12;
|
||||
}
|
||||
|
||||
.save-confirmation-button:focus {
|
||||
border: thick $accent;
|
||||
}
|
||||
"""
|
||||
|
||||
BINDINGS = [
|
||||
Binding("escape", "cancel", "Cancel"),
|
||||
Binding("enter", "save", "Save"),
|
||||
Binding("s", "save", "Save"),
|
||||
Binding("d", "discard", "Discard"),
|
||||
]
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
"""Create the save confirmation modal layout."""
|
||||
with Vertical(classes="save-confirmation-container"):
|
||||
yield Static("Save Changes?", classes="save-confirmation-title")
|
||||
yield Label(
|
||||
"You have made changes to this entry.\nDo you want to save or discard them?",
|
||||
classes="save-confirmation-message",
|
||||
)
|
||||
|
||||
with Horizontal(classes="button-row"):
|
||||
yield Button(
|
||||
"Save (S)",
|
||||
variant="primary",
|
||||
id="save-button",
|
||||
classes="save-confirmation-button",
|
||||
)
|
||||
yield Button(
|
||||
"Discard (D)",
|
||||
variant="default",
|
||||
id="discard-button",
|
||||
classes="save-confirmation-button",
|
||||
)
|
||||
yield Button(
|
||||
"Cancel (ESC)",
|
||||
variant="default",
|
||||
id="cancel-button",
|
||||
classes="save-confirmation-button",
|
||||
)
|
||||
|
||||
def on_mount(self) -> None:
|
||||
"""Called when the modal is mounted. Set focus to the first button."""
|
||||
# Focus on the Save button by default
|
||||
save_button = self.query_one("#save-button", Button)
|
||||
save_button.focus()
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""Handle button presses."""
|
||||
if event.button.id == "save-button":
|
||||
self.action_save()
|
||||
elif event.button.id == "discard-button":
|
||||
self.action_discard()
|
||||
elif event.button.id == "cancel-button":
|
||||
self.action_cancel()
|
||||
|
||||
def action_save(self) -> None:
|
||||
"""Save changes and close modal."""
|
||||
self.dismiss("save")
|
||||
|
||||
def action_discard(self) -> None:
|
||||
"""Discard changes and close modal."""
|
||||
self.dismiss("discard")
|
||||
|
||||
def action_cancel(self) -> None:
|
||||
"""Cancel operation and close modal."""
|
||||
self.dismiss("cancel")
|
|
@ -1,296 +0,0 @@
|
|||
"""
|
||||
Tests for the save confirmation modal.
|
||||
|
||||
This module tests the save confirmation functionality when exiting edit entry mode.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from textual.widgets import Input, Checkbox, Button
|
||||
|
||||
from hosts.main import HostsManagerApp
|
||||
from hosts.core.models import HostsFile, HostEntry
|
||||
from hosts.tui.save_confirmation_modal import SaveConfirmationModal
|
||||
|
||||
|
||||
class TestSaveConfirmationModal:
|
||||
"""Test cases for the SaveConfirmationModal class."""
|
||||
|
||||
def test_modal_creation(self):
|
||||
"""Test that the modal can be created."""
|
||||
modal = SaveConfirmationModal()
|
||||
assert modal is not None
|
||||
|
||||
def test_modal_compose(self):
|
||||
"""Test that the modal composes correctly."""
|
||||
# Note: Cannot test compose() directly without app context
|
||||
# This is a basic existence check for the modal
|
||||
modal = SaveConfirmationModal()
|
||||
assert hasattr(modal, "compose")
|
||||
assert callable(modal.compose)
|
||||
|
||||
def test_action_save(self):
|
||||
"""Test save action dismisses with 'save'."""
|
||||
modal = SaveConfirmationModal()
|
||||
modal.dismiss = Mock()
|
||||
|
||||
modal.action_save()
|
||||
|
||||
modal.dismiss.assert_called_once_with("save")
|
||||
|
||||
def test_action_discard(self):
|
||||
"""Test discard action dismisses with 'discard'."""
|
||||
modal = SaveConfirmationModal()
|
||||
modal.dismiss = Mock()
|
||||
|
||||
modal.action_discard()
|
||||
|
||||
modal.dismiss.assert_called_once_with("discard")
|
||||
|
||||
def test_action_cancel(self):
|
||||
"""Test cancel action dismisses with 'cancel'."""
|
||||
modal = SaveConfirmationModal()
|
||||
modal.dismiss = Mock()
|
||||
|
||||
modal.action_cancel()
|
||||
|
||||
modal.dismiss.assert_called_once_with("cancel")
|
||||
|
||||
@patch.object(SaveConfirmationModal, "query_one")
|
||||
def test_on_mount_sets_focus(self, mock_query_one):
|
||||
"""Test that on_mount sets focus to the save button."""
|
||||
modal = SaveConfirmationModal()
|
||||
mock_save_button = Mock()
|
||||
mock_query_one.return_value = mock_save_button
|
||||
|
||||
modal.on_mount()
|
||||
|
||||
mock_query_one.assert_called_once_with("#save-button", Button)
|
||||
mock_save_button.focus.assert_called_once()
|
||||
|
||||
|
||||
class TestSaveConfirmationIntegration:
|
||||
"""Test cases for save confirmation integration with the main app."""
|
||||
|
||||
@pytest.fixture
|
||||
def app(self):
|
||||
"""Create a test app instance."""
|
||||
return HostsManagerApp()
|
||||
|
||||
def test_has_entry_changes_no_original_values(self, app):
|
||||
"""Test has_entry_changes returns False when no original values stored."""
|
||||
app.original_entry_values = None
|
||||
app.entry_edit_mode = True
|
||||
|
||||
assert not app.has_entry_changes()
|
||||
|
||||
def test_has_entry_changes_not_in_edit_mode(self, app):
|
||||
"""Test has_entry_changes returns False when not in edit mode."""
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = False
|
||||
|
||||
assert not app.has_entry_changes()
|
||||
|
||||
@patch.object(HostsManagerApp, "query_one")
|
||||
def test_has_entry_changes_no_changes(self, mock_query_one, app):
|
||||
"""Test has_entry_changes returns False when no changes made."""
|
||||
# Setup original values
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = True
|
||||
|
||||
# Mock form fields with original values
|
||||
mock_ip_input = Mock()
|
||||
mock_ip_input.value = "127.0.0.1"
|
||||
mock_hostname_input = Mock()
|
||||
mock_hostname_input.value = "localhost"
|
||||
mock_comment_input = Mock()
|
||||
mock_comment_input.value = ""
|
||||
mock_checkbox = Mock()
|
||||
mock_checkbox.value = True
|
||||
|
||||
def mock_query_side_effect(selector, widget_type=None):
|
||||
if selector == "#ip-input":
|
||||
return mock_ip_input
|
||||
elif selector == "#hostname-input":
|
||||
return mock_hostname_input
|
||||
elif selector == "#comment-input":
|
||||
return mock_comment_input
|
||||
elif selector == "#active-checkbox":
|
||||
return mock_checkbox
|
||||
|
||||
mock_query_one.side_effect = mock_query_side_effect
|
||||
|
||||
assert not app.has_entry_changes()
|
||||
|
||||
@patch.object(HostsManagerApp, "query_one")
|
||||
def test_has_entry_changes_ip_changed(self, mock_query_one, app):
|
||||
"""Test has_entry_changes returns True when IP address changed."""
|
||||
# Setup original values
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = True
|
||||
|
||||
# Mock form fields with changed IP
|
||||
mock_ip_input = Mock()
|
||||
mock_ip_input.value = "192.168.1.1" # Changed IP
|
||||
mock_hostname_input = Mock()
|
||||
mock_hostname_input.value = "localhost"
|
||||
mock_comment_input = Mock()
|
||||
mock_comment_input.value = ""
|
||||
mock_checkbox = Mock()
|
||||
mock_checkbox.value = True
|
||||
|
||||
def mock_query_side_effect(selector, widget_type=None):
|
||||
if selector == "#ip-input":
|
||||
return mock_ip_input
|
||||
elif selector == "#hostname-input":
|
||||
return mock_hostname_input
|
||||
elif selector == "#comment-input":
|
||||
return mock_comment_input
|
||||
elif selector == "#active-checkbox":
|
||||
return mock_checkbox
|
||||
|
||||
mock_query_one.side_effect = mock_query_side_effect
|
||||
|
||||
assert app.has_entry_changes()
|
||||
|
||||
@patch.object(HostsManagerApp, "query_one")
|
||||
def test_has_entry_changes_hostname_changed(self, mock_query_one, app):
|
||||
"""Test has_entry_changes returns True when hostname changed."""
|
||||
# Setup original values
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = True
|
||||
|
||||
# Mock form fields with changed hostname
|
||||
mock_ip_input = Mock()
|
||||
mock_ip_input.value = "127.0.0.1"
|
||||
mock_hostname_input = Mock()
|
||||
mock_hostname_input.value = "localhost, test.local" # Added hostname
|
||||
mock_comment_input = Mock()
|
||||
mock_comment_input.value = ""
|
||||
mock_checkbox = Mock()
|
||||
mock_checkbox.value = True
|
||||
|
||||
def mock_query_side_effect(selector, widget_type=None):
|
||||
if selector == "#ip-input":
|
||||
return mock_ip_input
|
||||
elif selector == "#hostname-input":
|
||||
return mock_hostname_input
|
||||
elif selector == "#comment-input":
|
||||
return mock_comment_input
|
||||
elif selector == "#active-checkbox":
|
||||
return mock_checkbox
|
||||
|
||||
mock_query_one.side_effect = mock_query_side_effect
|
||||
|
||||
assert app.has_entry_changes()
|
||||
|
||||
@patch.object(HostsManagerApp, "query_one")
|
||||
def test_has_entry_changes_comment_added(self, mock_query_one, app):
|
||||
"""Test has_entry_changes returns True when comment added."""
|
||||
# Setup original values
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = True
|
||||
|
||||
# Mock form fields with added comment
|
||||
mock_ip_input = Mock()
|
||||
mock_ip_input.value = "127.0.0.1"
|
||||
mock_hostname_input = Mock()
|
||||
mock_hostname_input.value = "localhost"
|
||||
mock_comment_input = Mock()
|
||||
mock_comment_input.value = "Test comment" # Added comment
|
||||
mock_checkbox = Mock()
|
||||
mock_checkbox.value = True
|
||||
|
||||
def mock_query_side_effect(selector, widget_type=None):
|
||||
if selector == "#ip-input":
|
||||
return mock_ip_input
|
||||
elif selector == "#hostname-input":
|
||||
return mock_hostname_input
|
||||
elif selector == "#comment-input":
|
||||
return mock_comment_input
|
||||
elif selector == "#active-checkbox":
|
||||
return mock_checkbox
|
||||
|
||||
mock_query_one.side_effect = mock_query_side_effect
|
||||
|
||||
assert app.has_entry_changes()
|
||||
|
||||
@patch.object(HostsManagerApp, "query_one")
|
||||
def test_has_entry_changes_active_state_changed(self, mock_query_one, app):
|
||||
"""Test has_entry_changes returns True when active state changed."""
|
||||
# Setup original values
|
||||
app.original_entry_values = {
|
||||
"ip_address": "127.0.0.1",
|
||||
"hostnames": ["localhost"],
|
||||
"comment": None,
|
||||
"is_active": True,
|
||||
}
|
||||
app.entry_edit_mode = True
|
||||
|
||||
# Mock form fields with changed active state
|
||||
mock_ip_input = Mock()
|
||||
mock_ip_input.value = "127.0.0.1"
|
||||
mock_hostname_input = Mock()
|
||||
mock_hostname_input.value = "localhost"
|
||||
mock_comment_input = Mock()
|
||||
mock_comment_input.value = ""
|
||||
mock_checkbox = Mock()
|
||||
mock_checkbox.value = False # Changed active state
|
||||
|
||||
def mock_query_side_effect(selector, widget_type=None):
|
||||
if selector == "#ip-input":
|
||||
return mock_ip_input
|
||||
elif selector == "#hostname-input":
|
||||
return mock_hostname_input
|
||||
elif selector == "#comment-input":
|
||||
return mock_comment_input
|
||||
elif selector == "#active-checkbox":
|
||||
return mock_checkbox
|
||||
|
||||
mock_query_one.side_effect = mock_query_side_effect
|
||||
|
||||
assert app.has_entry_changes()
|
||||
|
||||
def test_exit_edit_entry_mode(self, app):
|
||||
"""Test exit_edit_entry_mode cleans up properly."""
|
||||
app.entry_edit_mode = True
|
||||
app.original_entry_values = {"test": "data"}
|
||||
app.update_entry_details = Mock()
|
||||
app.query_one = Mock()
|
||||
app.update_status = Mock()
|
||||
|
||||
mock_table = Mock()
|
||||
app.query_one.return_value = mock_table
|
||||
|
||||
app.exit_edit_entry_mode()
|
||||
|
||||
assert not app.entry_edit_mode
|
||||
assert app.original_entry_values is None
|
||||
app.update_entry_details.assert_called_once()
|
||||
mock_table.focus.assert_called_once()
|
||||
app.update_status.assert_called_once_with("Exited entry edit mode")
|
Loading…
Add table
Add a link
Reference in a new issue