Initial commit
Dieser Commit ist enthalten in:
324
REFACTORING_PLAN.md
Normale Datei
324
REFACTORING_PLAN.md
Normale Datei
@ -0,0 +1,324 @@
|
||||
# Refactoring Plan: main_window.py
|
||||
|
||||
## 🎯 Ziel
|
||||
Sichere Refaktorierung der `gui/main_window.py` (2.704 Zeilen, 81 Methoden) ohne Breaking Changes.
|
||||
|
||||
## 📊 Ausgangslage
|
||||
|
||||
### Datei-Statistiken
|
||||
- **Datei**: `gui/main_window.py`
|
||||
- **Zeilen**: 2.704
|
||||
- **Methoden**: 81
|
||||
- **Problem**: God Class Anti-Pattern, duplizierte Methoden, überlange Funktionen
|
||||
|
||||
### Identifizierte Duplikate
|
||||
```
|
||||
Zeile 1844 & 2602: verify_repository_on_gitea()
|
||||
Zeile 1462 & 2388: manage_branches()
|
||||
Zeile 1466 & 2444: link_to_gitea()
|
||||
Zeile 1809 & 2503: test_gitea_connection()
|
||||
```
|
||||
|
||||
### Überlange Methoden
|
||||
```
|
||||
init_and_push_to_gitea: 211 Zeilen
|
||||
push_to_gitea: 184 Zeilen
|
||||
verify_repository_on_gitea: 104 Zeilen
|
||||
test_gitea_connection: 99 Zeilen
|
||||
```
|
||||
|
||||
## 🛡️ Sicherheitsprinzipien
|
||||
|
||||
1. **Keine Breaking Changes** - Alle bestehenden Funktionen bleiben erhalten
|
||||
2. **Facade Pattern** - Alte APIs bleiben, leiten intern um
|
||||
3. **Feature Flags** - Neuer Code kann zur Laufzeit aktiviert/deaktiviert werden
|
||||
4. **Schrittweise Migration** - Kleine, reversible Änderungen
|
||||
|
||||
## 📋 Phasen-Plan
|
||||
|
||||
### Phase 0: Vorbereitung
|
||||
```bash
|
||||
# 1. Backup erstellen
|
||||
git checkout -b refactoring/main-window-backup
|
||||
git add -A && git commit -m "Backup before refactoring"
|
||||
|
||||
# 2. Tests erstellen
|
||||
# Datei: tests/test_main_window_api.py
|
||||
# - Dokumentiere alle public methods
|
||||
# - Erstelle Smoke Tests für kritische Funktionen
|
||||
```
|
||||
|
||||
### Phase 1: Duplikate-Analyse
|
||||
**WICHTIG: In dieser Phase wird KEIN Code geändert!**
|
||||
|
||||
```python
|
||||
# Aufgaben für KI:
|
||||
1. Vergleiche die duplizierten Methoden Zeile für Zeile
|
||||
2. Dokumentiere Unterschiede in DUPLICATE_ANALYSIS.md
|
||||
3. Identifiziere welche Version wo aufgerufen wird
|
||||
4. Empfehle welche Version behalten werden soll
|
||||
```
|
||||
|
||||
### Phase 2: Handler-Struktur erstellen
|
||||
|
||||
#### Neue Dateistruktur:
|
||||
```
|
||||
gui/
|
||||
├── main_window.py # Original, wird schrittweise reduziert
|
||||
├── handlers/
|
||||
│ ├── __init__.py
|
||||
│ ├── gitea_operations.py # Git/Gitea Operationen
|
||||
│ ├── process_manager.py # Prozess-Überwachung
|
||||
│ ├── project_manager.py # Projekt-Operationen
|
||||
│ └── ui_helpers.py # Dialog und UI-Hilfen
|
||||
```
|
||||
|
||||
#### Beispiel-Implementation:
|
||||
```python
|
||||
# gui/handlers/gitea_operations.py
|
||||
class GiteaOperationsHandler:
|
||||
def __init__(self, main_window):
|
||||
self.main_window = main_window
|
||||
self.repo_manager = main_window.repo_manager
|
||||
self.project_manager = main_window.project_manager
|
||||
# Alle benötigten Referenzen
|
||||
|
||||
def init_and_push_to_gitea(self, project):
|
||||
# EXAKTE Kopie der Original-Methode
|
||||
# TODO: Später refactoren
|
||||
pass
|
||||
|
||||
# gui/main_window.py - Facade Pattern
|
||||
class MainWindow:
|
||||
def __init__(self):
|
||||
# ... existing code ...
|
||||
self._init_handlers()
|
||||
|
||||
def _init_handlers(self):
|
||||
"""Initialize refactored handlers"""
|
||||
from gui.handlers.gitea_operations import GiteaOperationsHandler
|
||||
self._gitea_handler = GiteaOperationsHandler(self)
|
||||
|
||||
# Facade method - alte API bleibt
|
||||
def init_and_push_to_gitea(self, project):
|
||||
if hasattr(self, '_gitea_handler') and ENABLE_REFACTORED_HANDLERS:
|
||||
return self._gitea_handler.init_and_push_to_gitea(project)
|
||||
else:
|
||||
# Original Code bleibt unverändert
|
||||
# ... existing code ...
|
||||
```
|
||||
|
||||
### Phase 3: Feature Flags
|
||||
|
||||
```python
|
||||
# gui/config.py
|
||||
REFACTORING_FLAGS = {
|
||||
'USE_GITEA_HANDLER': False,
|
||||
'USE_PROCESS_HANDLER': False,
|
||||
'USE_PROJECT_HANDLER': False,
|
||||
'USE_UI_HELPERS': False,
|
||||
}
|
||||
|
||||
# Umgebungsvariable für Tests
|
||||
import os
|
||||
if os.getenv('CPM_USE_NEW_HANDLERS'):
|
||||
REFACTORING_FLAGS['USE_GITEA_HANDLER'] = True
|
||||
```
|
||||
|
||||
### Phase 4: Methoden-Migration (Priorität nach Komplexität)
|
||||
|
||||
#### Level 1 - Einfache Methoden (keine/wenige Abhängigkeiten)
|
||||
```
|
||||
update_status()
|
||||
download_log()
|
||||
load_and_apply_theme()
|
||||
_show_scrollable_info()
|
||||
```
|
||||
|
||||
#### Level 2 - Moderate Komplexität
|
||||
```
|
||||
create_header()
|
||||
create_content_area()
|
||||
create_status_bar()
|
||||
refresh_ui()
|
||||
```
|
||||
|
||||
#### Level 3 - Hohe Komplexität
|
||||
```
|
||||
refresh_projects()
|
||||
add_new_project()
|
||||
open_project()
|
||||
delete_project()
|
||||
```
|
||||
|
||||
#### Level 4 - Sehr hohe Komplexität (zuletzt)
|
||||
```
|
||||
init_and_push_to_gitea()
|
||||
push_to_gitea()
|
||||
manage_branches()
|
||||
verify_repository_on_gitea()
|
||||
```
|
||||
|
||||
### Phase 5: Refactoring der Handler
|
||||
|
||||
Nach erfolgreicher Migration:
|
||||
|
||||
```python
|
||||
# Vorher: 211 Zeilen Methode
|
||||
def init_and_push_to_gitea(self, project):
|
||||
# ... 211 Zeilen Code ...
|
||||
|
||||
# Nachher: Aufgeteilt in logische Einheiten
|
||||
class GiteaOperationsHandler:
|
||||
def init_and_push_to_gitea(self, project):
|
||||
"""Hauptmethode - koordiniert den Ablauf"""
|
||||
if not self._validate_project(project):
|
||||
return False
|
||||
|
||||
if not self._ensure_git_initialized(project):
|
||||
return False
|
||||
|
||||
repo = self._create_or_get_repository(project)
|
||||
if not repo:
|
||||
return False
|
||||
|
||||
return self._push_to_repository(project, repo)
|
||||
|
||||
def _validate_project(self, project):
|
||||
"""Validiert Projekt-Voraussetzungen"""
|
||||
# ~20 Zeilen
|
||||
|
||||
def _ensure_git_initialized(self, project):
|
||||
"""Stellt sicher dass Git initialisiert ist"""
|
||||
# ~30 Zeilen
|
||||
|
||||
def _create_or_get_repository(self, project):
|
||||
"""Erstellt oder holt Repository von Gitea"""
|
||||
# ~50 Zeilen
|
||||
|
||||
def _push_to_repository(self, project, repo):
|
||||
"""Führt den Push durch"""
|
||||
# ~40 Zeilen
|
||||
```
|
||||
|
||||
## 🧪 Test-Strategie
|
||||
|
||||
### 1. API-Kompatibilitäts-Tests
|
||||
```python
|
||||
# tests/test_api_compatibility.py
|
||||
def test_all_public_methods_exist():
|
||||
"""Stellt sicher dass alle öffentlichen Methoden noch existieren"""
|
||||
window = MainWindow()
|
||||
required_methods = [
|
||||
'init_and_push_to_gitea',
|
||||
'push_to_gitea',
|
||||
'manage_branches',
|
||||
# ... alle 81 Methoden
|
||||
]
|
||||
for method in required_methods:
|
||||
assert hasattr(window, method), f"Method {method} missing!"
|
||||
```
|
||||
|
||||
### 2. Verhaltens-Tests
|
||||
```python
|
||||
# tests/test_behavior.py
|
||||
def test_gitea_push_workflow():
|
||||
"""Testet kompletten Push-Workflow"""
|
||||
# 1. Projekt erstellen
|
||||
# 2. Git initialisieren
|
||||
# 3. Push zu Gitea
|
||||
# 4. Verifizieren
|
||||
```
|
||||
|
||||
### 3. Performance-Tests
|
||||
```python
|
||||
# tests/test_performance.py
|
||||
def test_refactoring_performance():
|
||||
"""Vergleicht Performance vor/nach Refactoring"""
|
||||
# Messe Zeit für kritische Operationen
|
||||
# Stelle sicher dass keine Regression
|
||||
```
|
||||
|
||||
## 🔄 Rollback-Plan
|
||||
|
||||
### 1. Git-Strategie
|
||||
```bash
|
||||
# Jede Phase in eigenem Branch
|
||||
git checkout -b refactoring/phase-1-duplicates
|
||||
git checkout -b refactoring/phase-2-handlers
|
||||
# etc.
|
||||
|
||||
# Rollback einfach durch Branch-Wechsel
|
||||
git checkout main
|
||||
```
|
||||
|
||||
### 2. Code-Level Rollback
|
||||
```python
|
||||
# Quick disable aller Änderungen
|
||||
ENABLE_REFACTORED_HANDLERS = False # Sofort alles auf Original
|
||||
```
|
||||
|
||||
### 3. Methoden-Level Rollback
|
||||
```python
|
||||
def init_and_push_to_gitea(self, project):
|
||||
if FORCE_ORIGINAL_IMPLEMENTATION:
|
||||
return self._init_and_push_to_gitea_original(project)
|
||||
# ... rest of facade code
|
||||
```
|
||||
|
||||
## 📊 Erfolgs-Metriken
|
||||
|
||||
### Muss-Kriterien (Go/No-Go)
|
||||
- [ ] Alle bestehenden Features funktionieren
|
||||
- [ ] Keine Performance-Regression (±5%)
|
||||
- [ ] Alle Tests grün
|
||||
- [ ] Keine neuen Bugs gemeldet
|
||||
|
||||
### Soll-Kriterien (Qualität)
|
||||
- [ ] Code-Zeilen pro Datei < 500
|
||||
- [ ] Methoden-Länge < 50 Zeilen
|
||||
- [ ] Keine duplizierten Methoden
|
||||
- [ ] Cyclomatic Complexity < 10 pro Methode
|
||||
|
||||
## 🚀 Ausführungs-Anweisungen für KI
|
||||
|
||||
### Für jede Phase:
|
||||
1. **Lese** diese Datei komplett
|
||||
2. **Erstelle** einen Branch: `git checkout -b refactoring/phase-X`
|
||||
3. **Implementiere** NUR die beschriebenen Änderungen
|
||||
4. **Teste** mit den vorgegebenen Tests
|
||||
5. **Dokumentiere** in `REFACTORING_PROGRESS.md`
|
||||
6. **Committe** mit aussagekräftiger Message
|
||||
|
||||
### Wichtige Regeln:
|
||||
- **NIEMALS** die Original-Funktionalität brechen
|
||||
- **IMMER** Facade Pattern für API-Kompatibilität nutzen
|
||||
- **IMMER** Feature Flags für neue Implementierungen
|
||||
- **NIEMALS** mehr als eine Phase gleichzeitig
|
||||
|
||||
### Bei Problemen:
|
||||
1. Stoppe sofort
|
||||
2. Dokumentiere das Problem in `REFACTORING_ISSUES.md`
|
||||
3. Warte auf menschliche Entscheidung
|
||||
4. Nutze Rollback wenn nötig
|
||||
|
||||
## 📝 Progress Tracking
|
||||
|
||||
### Template für REFACTORING_PROGRESS.md:
|
||||
```markdown
|
||||
# Refactoring Progress
|
||||
|
||||
## Phase 1: Duplikate-Analyse
|
||||
- Status: ⏳ In Progress / ✅ Complete / ❌ Failed
|
||||
- Datum: YYYY-MM-DD
|
||||
- Durchgeführt von: [KI-Name]
|
||||
- Änderungen:
|
||||
- ...
|
||||
- Tests: X/Y bestanden
|
||||
- Probleme:
|
||||
- ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**WICHTIG**: Dieser Plan ist für schrittweise, sichere Ausführung designed. Jede Phase muss vollständig abgeschlossen und getestet sein, bevor die nächste beginnt.
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren