Skip to content

Commit 55db768

Browse files
committed
ajout dun systeme de config pour les engines
1 parent 7b9d008 commit 55db768

4 files changed

Lines changed: 741 additions & 1 deletion

File tree

Core/engines_loader/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222

2323
from . import registry as registry # re-export registry module
2424
from .base import CompilerEngine # re-export base type
25+
from .config_manager import (
26+
EnginesConfigManager,
27+
get_engines_config_manager,
28+
reset_engines_config_manager,
29+
)
2530
from .validator import (
2631
EngineCompatibilityCheckResult,
2732
check_engine_compatibility,
@@ -89,4 +94,10 @@ def _auto_discover() -> None:
8994
except Exception:
9095
pass
9196

92-
__all__ = ["CompilerEngine", "registry"]
97+
__all__ = [
98+
"CompilerEngine",
99+
"registry",
100+
"EnginesConfigManager",
101+
"get_engines_config_manager",
102+
"reset_engines_config_manager",
103+
]
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Copyright 2025 Ague Samuel Amen
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
"""
17+
Engines Configuration Manager
18+
Manages engine-specific configurations stored in ark_engines_config directory
19+
"""
20+
21+
from __future__ import annotations
22+
23+
import json
24+
import os
25+
from pathlib import Path
26+
from typing import Any, Optional, Dict
27+
28+
29+
class EnginesConfigManager:
30+
"""
31+
Manages engine configurations in a centralized directory structure.
32+
33+
Directory structure:
34+
workspace_root/
35+
└── ark_engines_config/
36+
├── engine_id_1/
37+
│ └── config.json
38+
├── engine_id_2/
39+
│ └── config.json
40+
└── ...
41+
"""
42+
43+
CONFIG_DIR_NAME = "ark_engines_config"
44+
CONFIG_FILENAME = "config.json"
45+
46+
def __init__(self, workspace_dir: str):
47+
"""
48+
Initialize the engines config manager.
49+
50+
Args:
51+
workspace_dir: Root directory of the workspace
52+
"""
53+
self.workspace_dir = Path(workspace_dir) if workspace_dir else None
54+
self._config_root = None
55+
self._ensure_config_root()
56+
57+
def _ensure_config_root(self) -> None:
58+
"""Ensure the ark_engines_config directory exists at workspace root."""
59+
if not self.workspace_dir:
60+
return
61+
62+
self._config_root = self.workspace_dir / self.CONFIG_DIR_NAME
63+
try:
64+
self._config_root.mkdir(parents=True, exist_ok=True)
65+
except Exception as e:
66+
print(f"Warning: Failed to create engines config directory: {e}")
67+
self._config_root = None
68+
69+
def get_engine_config_dir(self, engine_id: str) -> Optional[Path]:
70+
"""
71+
Get or create the configuration directory for a specific engine.
72+
73+
Args:
74+
engine_id: The engine identifier
75+
76+
Returns:
77+
Path to the engine's config directory, or None if creation failed
78+
"""
79+
if not self._config_root or not engine_id:
80+
return None
81+
82+
engine_config_dir = self._config_root / engine_id
83+
try:
84+
engine_config_dir.mkdir(parents=True, exist_ok=True)
85+
return engine_config_dir
86+
except Exception as e:
87+
print(f"Warning: Failed to create config directory for engine '{engine_id}': {e}")
88+
return None
89+
90+
def get_engine_config_file(self, engine_id: str) -> Optional[Path]:
91+
"""
92+
Get the configuration file path for a specific engine.
93+
94+
Args:
95+
engine_id: The engine identifier
96+
97+
Returns:
98+
Path to the engine's config.json file, or None if directory creation failed
99+
"""
100+
engine_dir = self.get_engine_config_dir(engine_id)
101+
if not engine_dir:
102+
return None
103+
return engine_dir / self.CONFIG_FILENAME
104+
105+
def load_engine_config(self, engine_id: str) -> Dict[str, Any]:
106+
"""
107+
Load configuration for a specific engine.
108+
109+
Args:
110+
engine_id: The engine identifier
111+
112+
Returns:
113+
Dictionary containing the engine configuration, or empty dict if not found
114+
"""
115+
config_file = self.get_engine_config_file(engine_id)
116+
if not config_file or not config_file.exists():
117+
return {}
118+
119+
try:
120+
with open(config_file, "r", encoding="utf-8") as f:
121+
config = json.load(f)
122+
return config if isinstance(config, dict) else {}
123+
except Exception as e:
124+
print(f"Warning: Failed to load config for engine '{engine_id}': {e}")
125+
return {}
126+
127+
def save_engine_config(self, engine_id: str, config: Dict[str, Any]) -> bool:
128+
"""
129+
Save configuration for a specific engine.
130+
131+
Args:
132+
engine_id: The engine identifier
133+
config: Dictionary containing the configuration to save
134+
135+
Returns:
136+
True if successful, False otherwise
137+
"""
138+
if not isinstance(config, dict):
139+
print(f"Warning: Config for engine '{engine_id}' must be a dictionary")
140+
return False
141+
142+
config_file = self.get_engine_config_file(engine_id)
143+
if not config_file:
144+
return False
145+
146+
try:
147+
# Ensure parent directory exists
148+
config_file.parent.mkdir(parents=True, exist_ok=True)
149+
150+
with open(config_file, "w", encoding="utf-8") as f:
151+
json.dump(config, f, indent=2, ensure_ascii=False)
152+
return True
153+
except Exception as e:
154+
print(f"Warning: Failed to save config for engine '{engine_id}': {e}")
155+
return False
156+
157+
def update_engine_config(self, engine_id: str, updates: Dict[str, Any]) -> bool:
158+
"""
159+
Update specific keys in an engine's configuration.
160+
161+
Args:
162+
engine_id: The engine identifier
163+
updates: Dictionary containing the keys to update
164+
165+
Returns:
166+
True if successful, False otherwise
167+
"""
168+
if not isinstance(updates, dict):
169+
print(f"Warning: Updates for engine '{engine_id}' must be a dictionary")
170+
return False
171+
172+
# Load existing config
173+
config = self.load_engine_config(engine_id)
174+
175+
# Update with new values
176+
config.update(updates)
177+
178+
# Save updated config
179+
return self.save_engine_config(engine_id, config)
180+
181+
def delete_engine_config(self, engine_id: str) -> bool:
182+
"""
183+
Delete configuration directory for a specific engine.
184+
185+
Args:
186+
engine_id: The engine identifier
187+
188+
Returns:
189+
True if successful, False otherwise
190+
"""
191+
engine_dir = self.get_engine_config_dir(engine_id)
192+
if not engine_dir or not engine_dir.exists():
193+
return False
194+
195+
try:
196+
import shutil
197+
shutil.rmtree(engine_dir)
198+
return True
199+
except Exception as e:
200+
print(f"Warning: Failed to delete config directory for engine '{engine_id}': {e}")
201+
return False
202+
203+
def list_engine_configs(self) -> list[str]:
204+
"""
205+
List all engine IDs that have configurations.
206+
207+
Returns:
208+
List of engine IDs with existing configurations
209+
"""
210+
if not self._config_root or not self._config_root.exists():
211+
return []
212+
213+
try:
214+
engine_ids = []
215+
for item in self._config_root.iterdir():
216+
if item.is_dir():
217+
engine_ids.append(item.name)
218+
return sorted(engine_ids)
219+
except Exception as e:
220+
print(f"Warning: Failed to list engine configs: {e}")
221+
return []
222+
223+
def get_config_root_path(self) -> Optional[Path]:
224+
"""
225+
Get the root configuration directory path.
226+
227+
Returns:
228+
Path to ark_engines_config directory, or None if not available
229+
"""
230+
return self._config_root
231+
232+
def engine_has_config(self, engine_id: str) -> bool:
233+
"""
234+
Check if an engine has a configuration file.
235+
236+
Args:
237+
engine_id: The engine identifier
238+
239+
Returns:
240+
True if config file exists, False otherwise
241+
"""
242+
config_file = self.get_engine_config_file(engine_id)
243+
return config_file is not None and config_file.exists()
244+
245+
246+
# Global instance (lazy-loaded)
247+
_global_config_manager: Optional[EnginesConfigManager] = None
248+
249+
250+
def get_engines_config_manager(workspace_dir: Optional[str] = None) -> EnginesConfigManager:
251+
"""
252+
Get or create the global engines config manager instance.
253+
254+
Args:
255+
workspace_dir: Workspace directory (required for first call)
256+
257+
Returns:
258+
EnginesConfigManager instance
259+
"""
260+
global _global_config_manager
261+
262+
if _global_config_manager is None:
263+
if not workspace_dir:
264+
raise ValueError("workspace_dir is required for first initialization")
265+
_global_config_manager = EnginesConfigManager(workspace_dir)
266+
267+
return _global_config_manager
268+
269+
270+
def reset_engines_config_manager() -> None:
271+
"""Reset the global config manager instance (useful for testing)."""
272+
global _global_config_manager
273+
_global_config_manager = None
274+
275+
276+
__all__ = [
277+
"EnginesConfigManager",
278+
"get_engines_config_manager",
279+
"reset_engines_config_manager",
280+
]

0 commit comments

Comments
 (0)