Coverage for src / ezqt_app / services / bootstrap / contracts / options.py: 80.65%

27 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-26 07:07 +0000

1# /////////////////////////////////////////////////////////////// 

2# SERVICES.BOOTSTRAP.CONTRACTS.OPTIONS - Init options and policies 

3# Project: ezqt_app 

4# /////////////////////////////////////////////////////////////// 

5 

6"""Contracts for initialization options and overwrite behavior.""" 

7 

8from __future__ import annotations 

9 

10# /////////////////////////////////////////////////////////////// 

11# IMPORTS 

12# /////////////////////////////////////////////////////////////// 

13from dataclasses import dataclass 

14from enum import StrEnum 

15from pathlib import Path 

16 

17 

18# /////////////////////////////////////////////////////////////// 

19# TYPES 

20# /////////////////////////////////////////////////////////////// 

21class OverwritePolicy(StrEnum): 

22 """Policy used when generated files already exist.""" 

23 

24 ASK = "ask" 

25 SKIP = "skip" 

26 FORCE = "force" 

27 

28 

29# /////////////////////////////////////////////////////////////// 

30# MODELS 

31# /////////////////////////////////////////////////////////////// 

32@dataclass(slots=True) 

33class InitOptions: 

34 """Options driving initialization behavior across API and CLI. 

35 

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 """ 

56 

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 

66 

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: 70 ↛ 72line 70 didn't jump to line 72 because the condition on line 70 was always true

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 

76 

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 )