Fix: Version und Drittanbieter-Lizenzen im PyInstaller-Build anzeigen (v1.2.6)

pyproject.toml und THIRD_PARTY_LICENSES.txt werden nun ins PyInstaller-Bundle
eingebunden. Pfadauflösung nutzt sys._MEIPASS im Bundle-Kontext.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-28 19:32:03 +01:00
parent 09312dbd66
commit d7282082f4
7 changed files with 59 additions and 48 deletions
+43 -40
View File
@@ -4,46 +4,49 @@ PyInstaller Konfiguration für DocuMentor
Erstellt eine eigenständige Windows-Executable ohne Python-Installation Erstellt eine eigenständige Windows-Executable ohne Python-Installation
""" """
import sys import sys
from pathlib import Path from pathlib import Path
from PyInstaller.utils.hooks import collect_all from PyInstaller.utils.hooks import collect_all
block_cipher = None block_cipher = None
# Projektpfad # Projektpfad
project_root = Path(SPECPATH) project_root = Path(SPECPATH)
src_path = project_root / 'src' src_path = project_root / 'src'
# connectorx komplett sammeln (Python-Code, native .pyd und Metadaten) # connectorx komplett sammeln (Python-Code, native .pyd und Metadaten)
# PyInstaller erkennt connectorx nicht automatisch, da es zur Laufzeit # PyInstaller erkennt connectorx nicht automatisch, da es zur Laufzeit
# von polars per importlib.import_module() geladen wird # von polars per importlib.import_module() geladen wird
cx_datas, cx_binaries, cx_hiddenimports = collect_all('connectorx') cx_datas, cx_binaries, cx_hiddenimports = collect_all('connectorx')
# Alle UI-Dateien sammeln # Alle UI-Dateien sammeln
ui_files = [] ui_files = []
for ui_file in (src_path / 'ui').glob('*.ui'): for ui_file in (src_path / 'ui').glob('*.ui'):
ui_files.append((str(ui_file), 'ui')) ui_files.append((str(ui_file), 'ui'))
# Ressource-Dateien (SQL, CSV) einbinden # Ressource-Dateien (SQL, CSV) einbinden
res_files = [] res_files = []
for res_file in (src_path / 'res').glob('*'): for res_file in (src_path / 'res').glob('*'):
res_files.append((str(res_file), 'res')) res_files.append((str(res_file), 'res'))
a = Analysis( a = Analysis(
[str(src_path / 'main.py')], [str(src_path / 'main.py')],
pathex=[str(src_path)], pathex=[str(src_path)],
binaries=cx_binaries, binaries=cx_binaries,
datas=ui_files + res_files + cx_datas, datas=ui_files + res_files + cx_datas + [
hiddenimports=[ (str(project_root / 'pyproject.toml'), '.'),
'PySide6.QtCore', (str(project_root / 'THIRD_PARTY_LICENSES.txt'), '.'),
'PySide6.QtGui', ],
'PySide6.QtWidgets', hiddenimports=[
'pydantic', 'PySide6.QtCore',
'pydantic_settings', 'PySide6.QtGui',
'pydantic_yaml', 'PySide6.QtWidgets',
'polars', 'pydantic',
'pyarrow', 'pydantic_settings',
] + cx_hiddenimports, 'pydantic_yaml',
'polars',
'pyarrow',
] + cx_hiddenimports,
hookspath=[], hookspath=[],
hooksconfig={}, hooksconfig={},
runtime_hooks=[], runtime_hooks=[],
+1 -1
View File
@@ -4,7 +4,7 @@
<!-- Paket-Definition (ersetzt Product in v4) --> <!-- Paket-Definition (ersetzt Product in v4) -->
<Package <Package
Name="DocuMentor" Name="DocuMentor"
Version="1.2.5" Version="1.2.6"
Manufacturer="Vitali Graf / Software- und Datenbankentwicklung" Manufacturer="Vitali Graf / Software- und Datenbankentwicklung"
UpgradeCode="F498B66C-726D-44AA-95F4-CB4FBDCEF26E" UpgradeCode="F498B66C-726D-44AA-95F4-CB4FBDCEF26E"
Language="1031" Language="1031"
+1 -1
View File
@@ -253,5 +253,5 @@ HINWEISE
================================================================================ ================================================================================
Stand: März 2026 Stand: März 2026
Erstellt für: DocuMentor v1.2.5 Erstellt für: DocuMentor v1.2.6
================================================================================ ================================================================================
+1 -1
View File
@@ -10,7 +10,7 @@
; Build-Befehl: iscc installer.iss ; Build-Befehl: iscc installer.iss
#define MyAppName "DocuMentor" #define MyAppName "DocuMentor"
#define MyAppVersion "1.2.5" #define MyAppVersion "1.2.6"
#define MyAppPublisher "Ihr Name/Organisation" #define MyAppPublisher "Ihr Name/Organisation"
#define MyAppURL "https://github.com/yourusername/xsl-validator" #define MyAppURL "https://github.com/yourusername/xsl-validator"
#define MyAppExeName "DocuMentor.exe" #define MyAppExeName "DocuMentor.exe"
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "DocuMentor" name = "DocuMentor"
version = "1.2.5" version = "1.2.6"
description = "Professionelle XSL-Transformations-Verwaltung und PDF-Generierung" description = "Professionelle XSL-Transformations-Verwaltung und PDF-Generierung"
readme = "README.md" readme = "README.md"
license = {text = "MIT"} license = {text = "MIT"}
+7 -2
View File
@@ -6,14 +6,19 @@ mit den tatsächlich installierten Paketversionen via importlib.metadata.
""" """
import logging import logging
import re import re
import sys
from dataclasses import dataclass, field from dataclasses import dataclass, field
from importlib.metadata import PackageNotFoundError, version from importlib.metadata import PackageNotFoundError, version
from pathlib import Path from pathlib import Path
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Pfad zur Lizenzdatei relativ zum Projektroot # Pfad zur Lizenzdatei: im PyInstaller-Bundle aus sys._MEIPASS,
LICENSE_FILE = Path(__file__).parent.parent / "THIRD_PARTY_LICENSES.txt" # im Entwicklungsmodus relativ zum Projektroot
if hasattr(sys, "_MEIPASS"):
LICENSE_FILE = Path(sys._MEIPASS) / "THIRD_PARTY_LICENSES.txt" # type: ignore[attr-defined]
else:
LICENSE_FILE = Path(__file__).parent.parent / "THIRD_PARTY_LICENSES.txt"
# Mapping von Anzeigenamen zu PyPI-Paketnamen für Sonderfälle # Mapping von Anzeigenamen zu PyPI-Paketnamen für Sonderfälle
_PACKAGE_NAME_MAP: dict[str, str] = { _PACKAGE_NAME_MAP: dict[str, str] = {
+5 -2
View File
@@ -45,11 +45,14 @@ class AboutDialog(QDialog):
try: try:
return version("DocuMentor") return version("DocuMentor")
except PackageNotFoundError: except PackageNotFoundError:
# Fallback: pyproject.toml parsen (Entwicklungsmodus ohne Installation) # Fallback: pyproject.toml parsen (PyInstaller-Bundle oder Entwicklungsmodus)
try: try:
import tomllib import tomllib
pyproject = Path(__file__).parent.parent.parent / "pyproject.toml" if hasattr(sys, "_MEIPASS"):
pyproject = Path(sys._MEIPASS) / "pyproject.toml" # type: ignore[attr-defined]
else:
pyproject = Path(__file__).parent.parent.parent / "pyproject.toml"
with open(pyproject, "rb") as f: with open(pyproject, "rb") as f:
return tomllib.load(f)["project"]["version"] return tomllib.load(f)["project"]["version"]
except Exception: except Exception: