--- type: Operations title: Build & Betrieb description: Build-Prozess für Windows-Distribution (ZIP, MSI, Setup.exe), Tests, Code-Style-Richtlinien und Lizenzmanagement. tags: [build, pyinstaller, wix, msi, tests, ruff, lizenzen] --- # Build & Betrieb ## Paketverwaltung Das Projekt verwendet **uv** (nicht pip oder poetry): ```bash uv sync # Abhängigkeiten installieren uv sync --all-groups # Inkl. Dev-Abhängigkeiten (PyInstaller, Pillow) uv run python src/main.py # Anwendung starten ``` Python-Version: 3.13+ (max. 3.14), konfiguriert in `pyproject.toml`. ## Code-Qualität ```bash uv run ruff check # Linting (Zeilenlänge: 120) uv run ruff format # Formatierung ``` Ruff ist in `pyproject.toml` konfiguriert: - `line-length = 120` - `extend-exclude = ["*_ui.py"]` – generierte UI-Dateien werden nicht gelintet ### Code-Style-Konventionen | Bereich | Konvention | |---------|-----------| | Imports | 1. Standard Library → 2. Drittanbieter → 3. Lokale (immer absolut, nie relativ) | | Type Annotations | Moderne Union-Syntax: `str \| None`, `list[Path]`, `dict[str, str]` | | Klassen | PascalCase | | Funktionen/Methoden | snake_case | | Private Methoden | `_snake_case` mit Unterstrich | | Konstanten | UPPER_CASE | | Strings | Double-Quotes bevorzugt | | Error Handling | Stets `logging` statt `print()` | | Docstrings | Google-Style auf Deutsch | | Pfade | Immer `pathlib.Path`, nie Strings | | Sprache | UI-Texte, Kommentare, Log-Meldungen auf Deutsch | ### Zirkuläre Imports `TYPE_CHECKING` aus `typing` verwenden, um zirkuläre Imports zu vermeiden: ```python from typing import TYPE_CHECKING if TYPE_CHECKING: from saxon_pool import SaxonWorkerPool ``` ## Tests DocuMentor verwendet **keine** pytest/unittest-Frameworks. Tests sind standalone Python-Skripte: ```bash uv run python test_hash_implementation.py # Hash-Implementierung uv run python test_xml_hash_duplicate_detection.py # Duplikatserkennung ``` ## Build: Windows-Distribution Die Build-Skripte befinden sich im Repository-Root. Ausführliche Anleitung in `BUILD.md`. ### ZIP-Distribution (empfohlen) ```bash uv run python build_windows.py ``` Erstellt automatisch: 1. App-Icon (`resources/icon.ico`) via `create_icon.py` (falls nicht vorhanden) 2. Versionsinformationen (`version_info.txt`) via `create_version_info.py` 3. PyInstaller-Build (`DocuMentor.spec` → `dist/DocuMentor/DocuMentor.exe`) 4. ZIP-Archiv (`dist/DocuMentor-YYYYMMDD-Windows.zip`) ### Manueller PyInstaller-Build ```bash rm -rf build/ dist/ uv run pyinstaller --clean DocuMentor.spec ``` ### MSI-Installer (WiX Toolset) Voraussetzung: WiX Toolset v6 (`dotnet tool install --global wix --version 6.*`) ```bash # 1. PyInstaller-Build erstellen uv run python build_windows.py # 2. ProductFiles.wxs generieren (WiX v6 hat `heat` entfernt) uv run python generate_wix_files.py # 3. MSI kompilieren wix build DocuMentor.wxs ProductFiles.wxs -o DocuMentor.msi # 4. Testen msiexec /i DocuMentor.msi # Installation msiexec /i DocuMentor.msi /quiet /qn # Silent Installation msiexec /x DocuMentor.msi # Deinstallation ``` ### Setup.exe (Inno Setup) Alternative zum MSI: `installer.iss` für Inno Setup. ### Build-Skripte im Überblick | Skript | Zweck | |--------|------| | `build_windows.py` | Automatischer Build (Icon, Version, PyInstaller, ZIP) | | `build_msi.py` | MSI-Build-Wrapper | | `create_icon.py` | Icon-Generierung mit Pillow | | `create_version_info.py` | Windows-Versionsinformationen | | `generate_wix_files.py` | ProductFiles.wxs aus dist/ generieren | | `generate_guid.py` | GUID-Generierung für WiX | | `DocuMentor.spec` | PyInstaller-Spezifikation | | `DocuMentor.wxs` | WiX-Main-Definition | | `ProductFiles.wxs` | WiX-Datei-Inventar (generiert) | | `installer.iss` | Inno Setup-Skript | ## Versionierung - Version in `pyproject.toml` (`version = "1.7.3"`) - `versions.json` enthält Paketversionen für PyInstaller-Bundles (da `importlib.metadata` im Bundle nicht funktioniert) - Version-Bump via Skill `/version-bump` (verwendet `uv version --bump`) ## Lizenzmanagement - Projekt-Lizenz: MIT (`LICENSE`) - `LICENSES.md`: Vollständige Lizenzanalyse aller Abhängigkeiten - `THIRD_PARTY_LICENSES.txt`: Third-Party-Lizenztexte (wird ins PyInstaller-Bundle gepackt) - `src/license_parser.py`: Parst `THIRD_PARTY_LICENSES.txt` und ergänzt mit installierten Paketversionen (via `importlib.metadata` oder `versions.json` im Bundle) - Bei jedem Commit: Skill `/license-check` ausführen ## Externe Tool-Lizenzen | Tool | Lizenz | |------|--------| | Saxon-HE | Mozilla Public License 2.0 | | Apache FOP | Apache License 2.0 | | diff-pdf | GPL | ## CI/CD GitHub Actions Workflow `.github/workflows/openwiki-update.yml`: - Täglicher Cron (08:00 UTC) oder manuell - Führt `openwiki code --update --print` aus - Erstellt Pull Request mit aktualisierten Wiki-Seiten