Coverage for src / ezcompiler / utils / compiler_utils.py: 39.02%
33 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 06:49 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 06:49 +0000
1# ///////////////////////////////////////////////////////////////
2# COMPILER_UTILS - Compiler-specific utility functions
3# Project: ezcompiler
4# ///////////////////////////////////////////////////////////////
6"""
7Compiler utilities - Compiler-specific utility functions for EzCompiler.
9This module provides specialized utility functions for compiler operations,
10including configuration validation, output directory preparation, and include
11files formatting. Uses thematic utils (FileUtils, ValidationUtils) internally.
13Utils layer can only use DEBUG and ERROR log levels.
14"""
16from __future__ import annotations
18# ///////////////////////////////////////////////////////////////
19# IMPORTS
20# ///////////////////////////////////////////////////////////////
21# Standard library imports
22from pathlib import Path
24# Local imports
25from ..shared.compiler_config import CompilerConfig
26from ..shared.exceptions.utils import (
27 CompilerConfigValidationError,
28 MainFileNotFoundError,
29 OutputDirectoryError,
30)
31from .file_utils import FileUtils
33# ///////////////////////////////////////////////////////////////
34# CLASSES
35# ///////////////////////////////////////////////////////////////
38class CompilerUtils:
39 """
40 Utility class for compiler-specific operations.
42 Provides static methods for compiler-related tasks such as configuration
43 validation, output directory preparation, and include files formatting.
44 Uses thematic utils (FileUtils, ValidationUtils) internally.
46 Example:
47 >>> config = CompilerConfig(...)
48 >>> CompilerUtils.validate_compiler_config(config)
49 >>> CompilerUtils.prepare_compiler_output_directory(config)
50 >>> files = CompilerUtils.format_include_files_data(config)
51 """
53 # ////////////////////////////////////////////////
54 # VALIDATION METHODS
55 # ////////////////////////////////////////////////
57 @staticmethod
58 def validate_compiler_config(config: CompilerConfig) -> None:
59 """
60 Validate configuration for compilation.
62 Checks that all required configuration fields are present
63 and valid (main file exists, output folder is set).
65 Args:
66 config: CompilerConfig instance to validate
68 Raises:
69 MainFileNotFoundError: If main file doesn't exist or is required but missing
70 OutputDirectoryError: If output folder is not set
72 Note:
73 Uses FileUtils for file existence checks.
75 Example:
76 >>> config = CompilerConfig(...)
77 >>> CompilerUtils.validate_compiler_config(config)
78 """
79 if not config.main_file:
80 raise CompilerConfigValidationError("Main file is required")
82 main_file_path = Path(config.main_file)
83 if not main_file_path.exists() or not main_file_path.is_file():
84 raise MainFileNotFoundError(f"Main file not found: {config.main_file}")
86 if not config.output_folder:
87 raise OutputDirectoryError("Output folder is required")
89 # ////////////////////////////////////////////////
90 # PREPARATION METHODS
91 # ////////////////////////////////////////////////
93 @staticmethod
94 def prepare_compiler_output_directory(config: CompilerConfig) -> None:
95 """
96 Prepare the output directory for compilation.
98 Creates the output directory if it doesn't exist, including
99 any parent directories as needed.
101 Args:
102 config: CompilerConfig instance with output_folder path
104 Note:
105 Uses FileUtils.create_directory_if_not_exists() internally.
107 Example:
108 >>> config = CompilerConfig(..., output_folder=Path("dist"))
109 >>> CompilerUtils.prepare_compiler_output_directory(config)
110 """
111 FileUtils.create_directory_if_not_exists(config.output_folder)
113 # ////////////////////////////////////////////////
114 # DATA FORMATTING METHODS
115 # ////////////////////////////////////////////////
117 @staticmethod
118 def format_include_files_data(config: CompilerConfig) -> list[str]:
119 """
120 Format include files data for compilation.
122 Combines individual files and folders from configuration,
123 formatting folders with trailing slashes for compatibility
124 with different compilers.
126 Args:
127 config: CompilerConfig instance with include_files
129 Returns:
130 list[str]: List of formatted include paths
132 Note:
133 Files are included as-is, folders are formatted with
134 trailing slashes for Cx_Freeze compatibility.
136 Example:
137 >>> config.include_files = {
138 ... "files": ["config.yaml"],
139 ... "folders": ["lib", "assets"]
140 ... }
141 >>> files = CompilerUtils.format_include_files_data(config)
142 >>> print(files)
143 ['config.yaml', 'lib/', 'assets/']
144 """
145 files = config.include_files.get("files", [])
146 folders = [f"{folder}/" for folder in config.include_files.get("folders", [])]
147 return files + folders
149 # ////////////////////////////////////////////////
150 # COMPILER-SPECIFIC HELPERS
151 # ////////////////////////////////////////////////
153 @staticmethod
154 def get_windows_base_for_console(console: bool) -> str | None:
155 """
156 Get Windows base executable type based on console setting.
158 Args:
159 console: Whether to show console window
161 Returns:
162 str | None: "Win32GUI" if console=False on Windows, None otherwise
164 Note:
165 Used by Cx_Freeze to determine executable base type.
167 Example:
168 >>> base = CompilerUtils.get_windows_base_for_console(False)
169 >>> print(base)
170 'Win32GUI' # On Windows
171 """
172 import sys
174 if sys.platform == "win32" and not console:
175 return "Win32GUI"
176 return None
178 @staticmethod
179 def check_onefile_mode() -> bool:
180 """
181 Check if onefile mode is requested via command-line arguments.
183 Returns:
184 bool: True if --onefile is in sys.argv, False otherwise
186 Note:
187 Used by PyInstaller and Nuitka to determine output format.
189 Example:
190 >>> # When run with: python script.py --onefile
191 >>> is_onefile = CompilerUtils.check_onefile_mode()
192 >>> print(is_onefile)
193 True
194 """
195 import sys
197 return "--onefile" in sys.argv