aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside-tools/deploy_lib
diff options
context:
space:
mode:
authorShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2024-09-20 17:00:39 +0200
committerShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2024-10-07 13:54:03 +0200
commit1e5fe140b485209a30d7dd38b3334440c58cbb05 (patch)
tree43511980e289c57b6208ad0bf9b0c09ea58a483e /sources/pyside-tools/deploy_lib
parent9a10caa1e22773ce7563f82680c67596293178e4 (diff)
Deployment: Support Design Studio projects
- new class 'DesignStudio' to handle Design Studio projects. - Currently uses a way of monkey patching to override the 'main.py' to use 'main_patch.py' which has the same content but with 'app_dir' set to the parent of `main.py``. The reason for doing this is that Nuitka requires the `main.py` to be in the same directory as other resources required for the project. Once the corresponding patch, to alternate between evaluating 'app_dir' based on whether the application is deployed or called through the Python interpreter, is merged then this temporary fix of creating 'main_patch.py' can be removed. - Add tests. Pick-to: 6.7 Change-Id: I79e6572bdbbf4576fbdd9039a4922997a22139f8 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside-tools/deploy_lib')
-rw-r--r--sources/pyside-tools/deploy_lib/__init__.py1
-rw-r--r--sources/pyside-tools/deploy_lib/config.py57
-rw-r--r--sources/pyside-tools/deploy_lib/design_studio.py57
-rw-r--r--sources/pyside-tools/deploy_lib/nuitka_helper.py27
4 files changed, 108 insertions, 34 deletions
diff --git a/sources/pyside-tools/deploy_lib/__init__.py b/sources/pyside-tools/deploy_lib/__init__.py
index 98179ecf0..3417f7a29 100644
--- a/sources/pyside-tools/deploy_lib/__init__.py
+++ b/sources/pyside-tools/deploy_lib/__init__.py
@@ -54,6 +54,7 @@ def get_all_pyside_modules():
return [module[2:] for module in PySide6.__all__]
+from .design_studio import DesignStudio
from .commands import run_command, run_qmlimportscanner
from .dependency_util import find_pyside_modules, find_permission_categories, QtDependencyReader
from .nuitka_helper import Nuitka
diff --git a/sources/pyside-tools/deploy_lib/config.py b/sources/pyside-tools/deploy_lib/config.py
index c400348ec..d34489b97 100644
--- a/sources/pyside-tools/deploy_lib/config.py
+++ b/sources/pyside-tools/deploy_lib/config.py
@@ -12,7 +12,7 @@ from pathlib import Path
from enum import Enum
from project import ProjectData
-from . import (DEFAULT_APP_ICON, DEFAULT_IGNORE_DIRS, find_pyside_modules,
+from . import (DEFAULT_APP_ICON, DEFAULT_IGNORE_DIRS, DesignStudio, find_pyside_modules,
find_permission_categories, QtDependencyReader, run_qmlimportscanner)
# Some QML plugins like QtCore are excluded from this list as they don't contribute much to
@@ -165,7 +165,10 @@ class Config(BaseConfig):
else:
self.excluded_qml_plugins = self._find_excluded_qml_plugins()
- self._generated_files_path = self.project_dir / "deployment"
+ if DesignStudio.isDSProject(self.source_file):
+ self._generated_files_path = self.project_dir / "Python" / "deployment"
+ else:
+ self._generated_files_path = self.project_dir / "deployment"
self.modules = []
@@ -208,9 +211,10 @@ class Config(BaseConfig):
@qml_files.setter
def qml_files(self, qml_files):
self._qml_files = qml_files
- self.set_value("qt", "qml_files",
- ",".join([str(file.absolute().relative_to(self.project_dir.absolute()))
- for file in self.qml_files]))
+ qml_files = [str(file.absolute().relative_to(self.project_dir.absolute()))
+ if file.absolute().is_relative_to(self.project_dir) else str(file.absolute())
+ for file in self.qml_files]
+ self.set_value("qt", "qml_files", ",".join(qml_files))
@property
def project_dir(self):
@@ -254,6 +258,11 @@ class Config(BaseConfig):
@source_file.setter
def source_file(self, source_file: Path):
self._source_file = source_file
+ # FIXME: Remove when new DS is released
+ # for DS project, set self._source_file to main_patch.py, but don't change the value
+ # in the config file as main_patch.py is a temporary file
+ if DesignStudio.isDSProject(source_file):
+ self._source_file = DesignStudio(source_file).ds_source_file
self.set_value("app", "input_file", str(source_file))
@property
@@ -314,30 +323,28 @@ class Config(BaseConfig):
qml_files.extend([self.project_dir / str(qml_file) for qml_file in
ProjectData(project_file=sub_project_file).qml_files])
else:
- qml_files_temp = None
- if self.source_file and self.python_path:
- if not self.qml_files:
- # filter out files from DEFAULT_IGNORE_DIRS
- qml_files_temp = [file for file in self.source_file.parent.glob("**/*.qml")
- if all(part not in file.parts for part in
- DEFAULT_IGNORE_DIRS)]
-
- if len(qml_files_temp) > 500:
- warnings.warn(
- "You seem to include a lot of QML files. This can lead to errors in "
- "deployment."
- )
-
- if qml_files_temp:
- extra_qml_files = [Path(file) for file in qml_files_temp]
- qml_files.extend(extra_qml_files)
+ # Filter out files from DEFAULT_IGNORE_DIRS
+ qml_files = [
+ file for file in self.project_dir.glob("**/*.qml")
+ if all(part not in file.parts for part in DEFAULT_IGNORE_DIRS)
+ ]
+
+ if len(qml_files) > 500:
+ warnings.warn(
+ "You seem to include a lot of QML files from "
+ f"{self.project_dir}. This can lead to errors in deployment."
+ )
return qml_files
def _find_project_dir(self) -> Path:
- # there is no other way to find the project_dir than assume it is the parent directory
- # of source_file
- project_dir = self.source_file.parent
+ if DesignStudio.isDSProject(self.source_file):
+ ds = DesignStudio(self.source_file)
+ project_dir = ds.project_dir
+ else:
+ # there is no other way to find the project_dir than assume it is the parent directory
+ # of source_file
+ project_dir = self.source_file.parent
return project_dir
def _find_project_file(self) -> Path:
diff --git a/sources/pyside-tools/deploy_lib/design_studio.py b/sources/pyside-tools/deploy_lib/design_studio.py
new file mode 100644
index 000000000..1fc1a4cc8
--- /dev/null
+++ b/sources/pyside-tools/deploy_lib/design_studio.py
@@ -0,0 +1,57 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import logging
+import atexit
+from pathlib import Path
+
+# FIXME: Remove this idea of creating main_patch.py once the corresponding changes are
+# made in Design Studio main.py file:
+# if '__compiled__' in globals(): #nuitka
+# app_dir = Path(__file__).parent
+# else:
+# app_dir = Path(__file__).parent.parent
+
+
+class DesignStudio:
+ """
+ Class to handle Design Studio projects
+ """
+
+ def __init__(self, main_file: Path):
+ self.ds_project_dir = main_file.parent.parent
+ self.current_main_file = main_file
+ self.new_main_file = main_file.parent / 'main_patch.py'
+ self._create_new_main_file()
+ atexit.register(self._delete_main_patch_file)
+
+ def _create_new_main_file(self):
+ # read the content of main file
+ content = ""
+ with open(self.current_main_file, 'r', encoding='utf-8') as main_file:
+ content = main_file.read()
+
+ # replace app_dir
+ content = content.replace("app_dir = Path(__file__).parent.parent", # old value
+ "app_dir = Path(__file__).parent") # new value
+
+ # write the content to new main file
+ with open(self.new_main_file, 'w', encoding="utf-8") as main_file:
+ main_file.write(content)
+
+ def _delete_main_patch_file(self):
+ if self.new_main_file.exists():
+ logging.info(f"[DEPLOY] Removing {self.new_main_file}")
+ self.new_main_file.unlink()
+
+ @staticmethod
+ def isDSProject(main_file: Path) -> bool:
+ return (main_file.parent / 'autogen/settings.py').exists()
+
+ @property
+ def project_dir(self) -> str:
+ return self.ds_project_dir
+
+ @property
+ def ds_source_file(self) -> Path:
+ return self.new_main_file
diff --git a/sources/pyside-tools/deploy_lib/nuitka_helper.py b/sources/pyside-tools/deploy_lib/nuitka_helper.py
index f0acfb720..2d46dcf8a 100644
--- a/sources/pyside-tools/deploy_lib/nuitka_helper.py
+++ b/sources/pyside-tools/deploy_lib/nuitka_helper.py
@@ -11,7 +11,7 @@ import shlex
import sys
from pathlib import Path
-from . import MAJOR_VERSION, run_command
+from . import MAJOR_VERSION, DesignStudio, run_command
from .config import DesktopConfig
@@ -104,14 +104,23 @@ class Nuitka:
qml_args = []
if qml_files:
- # This will generate options for each file using:
- # --include-data-files=ABSOLUTE_PATH_TO_FILE=RELATIVE_PATH_TO ROOT
- # for each file. This will preserve the directory structure of QML resources.
- qml_args.extend(
- [f"--include-data-files={qml_file.resolve()}="
- f"./{qml_file.resolve().relative_to(source_file.resolve().parent)}"
- for qml_file in qml_files]
- )
+ if DesignStudio.isDSProject(source_file):
+ ds = DesignStudio(source_file)
+ # include all subdirectories of ds.project_directory as data directories
+ # this will contain all the qml files and other resources
+ for subdir in ds.project_dir.iterdir():
+ if subdir.is_dir():
+ extra_args.append(f"--include-data-dir={subdir}="
+ f"./{subdir.name}")
+ else:
+ # This will generate options for each file using:
+ # --include-data-files=ABSOLUTE_PATH_TO_FILE=RELATIVE_PATH_TO ROOT
+ # for each file. This will preserve the directory structure of QML resources.
+ qml_args.extend(
+ [f"--include-data-files={qml_file.resolve()}="
+ f"./{qml_file.resolve().relative_to(source_file.resolve().parent)}"
+ for qml_file in qml_files]
+ )
# add qml plugin. The `qml`` plugin name is not present in the module json files shipped
# with Qt and hence not in `qt_plugins``. However, Nuitka uses the 'qml' plugin name to
# include the necessary qml plugins. There we have to add it explicitly for a qml