Coverage for src / ezqt_app / services / bootstrap / contracts / options.py: 100.00%
27 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-06 13:12 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-06 13:12 +0000
1# ///////////////////////////////////////////////////////////////
2# SERVICES.BOOTSTRAP.CONTRACTS.OPTIONS - Init options and policies
3# Project: ezqt_app
4# ///////////////////////////////////////////////////////////////
6"""Contracts for initialization options and overwrite behavior."""
8from __future__ import annotations
10# ///////////////////////////////////////////////////////////////
11# IMPORTS
12# ///////////////////////////////////////////////////////////////
13from dataclasses import dataclass
14from enum import StrEnum
15from pathlib import Path
18# ///////////////////////////////////////////////////////////////
19# TYPES
20# ///////////////////////////////////////////////////////////////
21class OverwritePolicy(StrEnum):
22 """Policy used when generated files already exist."""
24 ASK = "ask"
25 SKIP = "skip"
26 FORCE = "force"
29# ///////////////////////////////////////////////////////////////
30# MODELS
31# ///////////////////////////////////////////////////////////////
32@dataclass(slots=True)
33class InitOptions:
34 """Options driving initialization behavior across API and CLI.
36 Attributes:
37 project_root: Absolute path to the project root directory. When
38 ``None``, defaults to ``Path.cwd()`` at resolve time.
39 bin_path: Directory where generated assets (``resources_rc.py``,
40 ``app_icons.py``, ``app_images.py``, themes) are written.
41 When ``None``, defaults to ``<project_root>/bin``. A relative
42 value is resolved against ``project_root``; an absolute value is
43 used as-is.
44 mk_theme: Generate QSS theme files under ``bin_path/themes/``.
45 mk_config: Generate the ``config/`` YAML files.
46 mk_translations: Generate the ``translations/`` TS source files.
47 build_resources: Compile the QRC file with ``pyside6-rcc`` and write
48 ``resources_rc.py``, ``app_icons.py``, and ``app_images.py``
49 into ``bin_path``. Raises ``ResourceCompilationError`` if
50 ``pyside6-rcc`` is not found on ``PATH``.
51 generate_main: Write a ``main.py`` entrypoint in the project root.
52 verbose: Print step-by-step progress to stdout.
53 overwrite_policy: Controls behavior when generated files already
54 exist. See :class:`OverwritePolicy`.
55 """
57 project_root: Path | None = None
58 bin_path: Path | None = None
59 mk_theme: bool = True
60 mk_config: bool = True
61 mk_translations: bool = True
62 build_resources: bool = True
63 generate_main: bool = False
64 verbose: bool = True
65 overwrite_policy: OverwritePolicy = OverwritePolicy.ASK
67 def resolve(self) -> InitOptions:
68 """Return a copy with normalized paths and defaults resolved."""
69 root = self.project_root or Path.cwd()
70 if self.bin_path is None:
71 bin_path = root / "bin"
72 elif not self.bin_path.is_absolute():
73 bin_path = (root / self.bin_path).resolve()
74 else:
75 bin_path = self.bin_path
77 return InitOptions(
78 project_root=root,
79 bin_path=bin_path,
80 mk_theme=self.mk_theme,
81 mk_config=self.mk_config,
82 mk_translations=self.mk_translations,
83 build_resources=self.build_resources,
84 generate_main=self.generate_main,
85 verbose=self.verbose,
86 overwrite_policy=self.overwrite_policy,
87 )