---
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
