diff options
-rw-r--r-- | sources/pyside-tools/__init__.py | 0 | ||||
-rw-r--r-- | sources/pyside-tools/deploy.py | 76 | ||||
-rw-r--r-- | sources/pyside-tools/deploy/config.py | 127 | ||||
-rw-r--r-- | sources/pyside-tools/deploy/default.spec | 7 | ||||
-rw-r--r-- | sources/pyside-tools/deploy/python_helper.py | 6 |
5 files changed, 126 insertions, 90 deletions
diff --git a/sources/pyside-tools/__init__.py b/sources/pyside-tools/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/sources/pyside-tools/__init__.py diff --git a/sources/pyside-tools/deploy.py b/sources/pyside-tools/deploy.py index 2dde34ad3..a8d3e2b61 100644 --- a/sources/pyside-tools/deploy.py +++ b/sources/pyside-tools/deploy.py @@ -50,7 +50,7 @@ def clean(purge_path: Path): """remove the generated deployment files""" if purge_path.exists(): shutil.rmtree(purge_path) - logging.info("[DEPLOY]: deployment directory purged") + logging.info("[DEPLOY] deployment directory purged") else: print(f"{purge_path} does not exist") @@ -94,47 +94,35 @@ if __name__ == "__main__": else: config_file = Path.cwd() / "pysidedeploy.spec" - final_exec_path = None - config = Config(config_file=config_file) - - # set if available, else fetch from config_file - source_file = Path( - config.set_or_fetch(config_property_val=args.main_file, config_property_key="input_file") - ) - - if config.project_dir: - source_file = config.project_dir / source_file - - generated_files_path = source_file.parent / "deployment" - if generated_files_path.exists(): - clean(generated_files_path) - - logging.info("[DEPLOY]: Start") + logging.info("[DEPLOY] Start") try: python = None - python_path = config.get_value("python", "python_path") - if python_path and Path(python_path).exists(): - python = PythonExecutable(Path(python_path), dry_run=args.dry_run) - else: - # checking if inside virtual environment - if not PythonExecutable.is_venv(): - if not args.force: - response = input("Not in virtualenv. Do you want to create one? [Y/n]") - else: - response = "no" - - if response.lower() in "yes": - # creating new virtual environment - python = PythonExecutable(create_venv=True, dry_run=args.dry_run) - logging.info("[DEPLOY]: virutalenv created") - - # in venv or user entered no - if not python: - python = PythonExecutable(dry_run=args.dry_run) - logging.info(f"[DEPLOY]: using python at {sys.executable}") - - config.set_value("python", "python_path", str(python.exe)) + # checking if inside virtual environment + if not PythonExecutable.is_venv(): + if not args.force: + response = input("Not in virtualenv. Do you want to create one? [Y/n]") + else: + response = "no" + + if response.lower() in "yes": + # creating new virtual environment + python = PythonExecutable(create_venv=True, dry_run=args.dry_run) + logging.info("[DEPLOY] virutalenv created") + + # in venv or user entered no + if not python: + python = PythonExecutable(dry_run=args.dry_run) + logging.info(f"[DEPLOY] using python at {sys.executable}") + + config = Config(config_file=config_file, source_file=args.main_file, + python_exe=python.exe, dry_run=args.dry_run) + + source_file = config.project_dir / config.source_file + + generated_files_path = source_file.parent / "deployment" + if generated_files_path.exists(): + clean(generated_files_path) if not args.init and not args.dry_run: # install packages needed for deployment @@ -145,12 +133,6 @@ if __name__ == "__main__": if sys.platform.startswith("linux"): python.install(packages=["patchelf"]) - # identify and set qml files - config.find_and_set_qml_files() - - if not config.project_dir: - config.find_and_set_project_dir() - if config.project_dir == Path.cwd(): final_exec_path = config.project_dir.relative_to(Path.cwd()) else: @@ -166,7 +148,7 @@ if __name__ == "__main__": if args.init: # config file created above. Exiting. - logging.info(f"[DEPLOY]: Config file {args.config_file} created") + logging.info(f"[DEPLOY]: Config file {config.config_file} created") sys.exit(0) # create executable @@ -192,4 +174,4 @@ if __name__ == "__main__": ) clean(generated_files_path) - logging.info("[DEPLOY]: End") + logging.info("[DEPLOY] End") diff --git a/sources/pyside-tools/deploy/config.py b/sources/pyside-tools/deploy/config.py index 3e1c72abe..d02558cca 100644 --- a/sources/pyside-tools/deploy/config.py +++ b/sources/pyside-tools/deploy/config.py @@ -6,7 +6,8 @@ import configparser from configparser import ConfigParser import shutil import logging -import os + +from project import ProjectData class Config: @@ -14,24 +15,50 @@ class Config: Wrapper class around config file, whose options are used to control the executable creation """ - def __init__(self, config_file: Path) -> None: + def __init__(self, config_file: Path, source_file: Path, python_exe: Path, dry_run: bool): self.config_file = config_file self.parser = ConfigParser(comment_prefixes="/", allow_no_value=True) if not self.config_file.exists(): - logging.info(f"[DEPLOY]: Creating config file {self.config_file}") + logging.info(f"[DEPLOY] Creating config file {self.config_file}") shutil.copy(Path(__file__).parent / "default.spec", self.config_file) else: print(f"Using existing config file {config_file}") self.parser.read(self.config_file) + self.dry_run = dry_run + # set source_file + self.source_file = Path( + self.set_or_fetch(config_property_val=source_file, config_property_key="input_file") + ) + + # set python path + self.python_path = Path( + self.set_or_fetch( + config_property_val=python_exe, + config_property_key="python_path", + config_property_group="python", + ) + ) + self.project_dir = None if self.get_value("app", "project_dir"): self.project_dir = Path(self.get_value("app", "project_dir")).absolute() + else: + self._find_and_set_project_dir() + + self.project_data: ProjectData = None + if self.get_value("app", "project_file"): + project_file = Path(self.get_value("app", "project_file")).absolute() + self.project_data = ProjectData(project_file=project_file) + else: + self._find_and_set_project_file() self.qml_files = [] config_qml_files = self.get_value("qt", "qml_files") if config_qml_files and self.project_dir: self.qml_files = [Path(self.project_dir) / file for file in config_qml_files.split(",")] + else: + self._find_and_set_qml_files() def update_config(self): logging.info("[DEPLOY] Creating {config_file}") @@ -44,17 +71,17 @@ class Config: if current_value != new_value: self.parser.set(section, key, new_value) except configparser.NoOptionError: - logging.warning(f"[DEPLOY]: key {key} does not exist") + logging.warning(f"[DEPLOY] key {key} does not exist") except configparser.NoSectionError: - logging.warning(f"[DEPLOY]: section {section} does not exist") + logging.warning(f"[DEPLOY] section {section} does not exist") def get_value(self, section: str, key: str): try: return self.parser.get(section, key) except configparser.NoOptionError: - logging.warning(f"[DEPLOY]: key {key} does not exist") + logging.warning(f"[DEPLOY] key {key} does not exist") except configparser.NoSectionError: - logging.warning(f"[DEPLOY]: section {section} does not exist") + logging.warning(f"[DEPLOY] section {section} does not exist") def set_or_fetch(self, config_property_val, config_property_key, config_property_group="app"): """ @@ -90,16 +117,31 @@ class Config: def project_dir(self, project_dir): self._project_dir = project_dir - def find_and_set_qml_files(self): + @property + def source_file(self): + return self._source_file + + @source_file.setter + def source_file(self, source_file): + self._source_file = source_file + + @property + def python_path(self): + return self._python_path + + @python_path.setter + def python_path(self, python_path): + self._python_path = python_path + + def _find_and_set_qml_files(self): """Fetches all the qml_files in the folder and sets them if the field qml_files is empty in the config_dir""" - if self.project_dir: - qml_files_str = self.get_value("qt", "qml_files") - self.qml_files = [] - for file in qml_files_str.split(","): - if file: - self.qml_files.append(Path(self.project_dir) / file) + if self.project_data: + qml_files = self.project_data.qml_files + for sub_project_file in self.project_data.sub_projects_files: + qml_files.extend(ProjectData(project_file=sub_project_file).qml_files) + self.qml_files = qml_files else: qml_files_temp = None source_file = ( @@ -140,38 +182,45 @@ class Config: if qml_files_temp: extra_qml_files = [Path(file) for file in qml_files_temp] self.qml_files.extend(extra_qml_files) - self.set_value( - "qt", "qml_files", ",".join([str(file) for file in self.qml_files]) - ) - logging.info("[DEPLOY] QML files identified and set in config_file") - - def find_and_set_project_dir(self): - source_file = ( - Path(self.get_value("app", "input_file")) - if self.get_value("app", "input_file") - else None - ) - - if self.qml_files and source_file: - paths = self.qml_files.copy() - paths.append(source_file.absolute()) - self.project_dir = Path(os.path.commonpath(paths=paths)) - - # update all qml paths - logging.info("[DEPLOY] Update QML files paths to relative paths") - qml_relative_paths = ",".join( - [str(qml_file.relative_to(self.project_dir)) for qml_file in self.qml_files] + if self.qml_files: + self.set_value( + "qt", + "qml_files", + ",".join([str(file.relative_to(self.project_dir)) for file in self.qml_files]), ) - self.set_value("qt", "qml_files", qml_relative_paths) - else: - self.project_dir = source_file.parent + logging.info("[DEPLOY] QML files identified and set in config_file") + + def _find_and_set_project_dir(self): + # there is no other way to find the project_dir than assume it is the parent directory + # of source_file + self.project_dir = self.source_file.parent # update input_file path logging.info("[DEPLOY] Update input_file path") - self.set_value("app", "input_file", str(source_file.relative_to(self.project_dir))) + self.set_value("app", "input_file", str(self.source_file.relative_to(self.project_dir))) logging.info("[DEPLOY] Update project_dir path") if self.project_dir != Path.cwd(): self.set_value("app", "project_dir", str(self.project_dir)) else: self.set_value("app", "project_dir", str(self.project_dir.relative_to(Path.cwd()))) + + def _find_and_set_project_file(self): + logging.info("[DEPLOY] Searching for .pyproject file") + + if self.project_dir: + files = list(self.project_dir.glob("*.pyproject")) + else: + logging.exception("[DEPLOY] Project directory not set in config file") + raise + + if not files: + logging.info("[DEPLOY] No .pyproject file found. Project file not set") + elif len(files) > 1: + logging.warning("DEPLOY: More that one .pyproject files found. Project file not set") + raise + else: + self.project_data = ProjectData(files[0]) + self.set_value("app", "project_file", str(files[0].relative_to(self.project_dir))) + logging.info(f"[DEPLOY] Project file {files[0]} found and set in config file") + diff --git a/sources/pyside-tools/deploy/default.spec b/sources/pyside-tools/deploy/default.spec index 181efe105..4558ae161 100644 --- a/sources/pyside-tools/deploy/default.spec +++ b/sources/pyside-tools/deploy/default.spec @@ -3,7 +3,8 @@ # Title of your application title = My Application -# Project Directory +# Project Directory. The general assumption is that project_dir is the parent directory +# of input_file project_dir = # Source file path @@ -12,6 +13,10 @@ input_file = # Directory where exec is stored exec_directory = +# Path to .pyproject project file +project_file = + + [python] # Python path diff --git a/sources/pyside-tools/deploy/python_helper.py b/sources/pyside-tools/deploy/python_helper.py index ea5859cea..35c3fb35c 100644 --- a/sources/pyside-tools/deploy/python_helper.py +++ b/sources/pyside-tools/deploy/python_helper.py @@ -48,13 +48,13 @@ class PythonExecutable: elif sys.platform in ["linux", "darwin"]: self.exe = venv_path / "bin" / "python" else: - logging.info("[DEPLOY]: You are already in virtual environment!") + logging.info("[DEPLOY] You are already in virtual environment!") def install(self, packages: list = None): if packages: for package in packages: if not self.is_installed(package=package): - logging.info(f"[DEPLOY]: Installing package: {package}") + logging.info(f"[DEPLOY] Installing package: {package}") run_command( command=[self.exe, "-m", "pip", "install", package], dry_run=self.dry_run, @@ -71,7 +71,7 @@ class PythonExecutable: def create_executable(self, source_file: Path, extra_args: str, config: Config): if config.qml_files: - logging.info(f"[DEPLOY]: Included QML files: {config.qml_files}") + logging.info(f"[DEPLOY] Included QML files: {config.qml_files}") self.nuitka.create_executable( source_file=source_file, |