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:
+43
-40
@@ -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
@@ -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"
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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"}
|
||||||
|
|||||||
@@ -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] = {
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user