|
5 | 5 | # -------------------------------------------------------------------------- |
6 | 6 | import os |
7 | 7 | import re |
8 | | -import subprocess |
9 | | -import sys |
10 | | -from typing import Dict, List, Optional |
| 8 | +from typing import Dict, List |
11 | 9 |
|
12 | 10 | from fastapi_fastkit import console |
| 11 | +from fastapi_fastkit.backend.package_managers import PackageManagerFactory |
13 | 12 | from fastapi_fastkit.backend.transducer import copy_and_convert_template_file |
14 | 13 | from fastapi_fastkit.core.exceptions import BackendExceptions, TemplateExceptions |
15 | 14 | from fastapi_fastkit.core.settings import settings |
@@ -246,99 +245,94 @@ def _process_config_file(config_py: str, project_name: str) -> None: |
246 | 245 | raise BackendExceptions(f"Failed to process config file: {e}") |
247 | 246 |
|
248 | 247 |
|
| 248 | +def create_venv_with_manager(project_dir: str, manager_type: str = "pip") -> str: |
| 249 | + """ |
| 250 | + Create a virtual environment using the specified package manager. |
| 251 | +
|
| 252 | + :param project_dir: Path to the project directory |
| 253 | + :param manager_type: Type of package manager to use |
| 254 | + :return: Path to the virtual environment |
| 255 | + :raises: BackendExceptions if virtual environment creation fails |
| 256 | + """ |
| 257 | + try: |
| 258 | + package_manager = PackageManagerFactory.create_manager( |
| 259 | + manager_type, project_dir, auto_detect=True |
| 260 | + ) |
| 261 | + return package_manager.create_virtual_environment() |
| 262 | + except Exception as e: |
| 263 | + debug_log( |
| 264 | + f"Error creating virtual environment with {manager_type}: {e}", "error" |
| 265 | + ) |
| 266 | + raise BackendExceptions(f"Failed to create virtual environment: {str(e)}") |
| 267 | + |
| 268 | + |
249 | 269 | def create_venv(project_dir: str) -> str: |
250 | 270 | """ |
251 | 271 | Create a Python virtual environment in the project directory. |
252 | 272 |
|
| 273 | + This is a backward compatibility wrapper that uses pip by default. |
| 274 | +
|
253 | 275 | :param project_dir: Path to the project directory |
254 | 276 | :return: Path to the virtual environment |
255 | 277 | """ |
256 | | - venv_path = os.path.join(project_dir, ".venv") |
| 278 | + return create_venv_with_manager(project_dir, "pip") |
257 | 279 |
|
258 | | - try: |
259 | | - with console.status("[bold green]Creating virtual environment..."): |
260 | | - subprocess.run( |
261 | | - [sys.executable, "-m", "venv", venv_path], |
262 | | - check=True, |
263 | | - capture_output=True, |
264 | | - text=True, |
265 | | - ) |
266 | 280 |
|
267 | | - debug_log(f"Virtual environment created at {venv_path}", "info") |
268 | | - print_success("Virtual environment created successfully") |
269 | | - return venv_path |
| 281 | +def install_dependencies_with_manager( |
| 282 | + project_dir: str, venv_path: str, manager_type: str = "pip" |
| 283 | +) -> None: |
| 284 | + """ |
| 285 | + Install dependencies using the specified package manager. |
270 | 286 |
|
271 | | - except subprocess.CalledProcessError as e: |
272 | | - debug_log(f"Error creating virtual environment: {e.stderr}", "error") |
273 | | - handle_exception(e, f"Error creating virtual environment: {str(e)}") |
274 | | - raise BackendExceptions("Failed to create venv") |
275 | | - except OSError as e: |
276 | | - debug_log(f"System error creating virtual environment: {e}", "error") |
277 | | - handle_exception(e, f"Error creating virtual environment: {str(e)}") |
278 | | - raise BackendExceptions(f"Failed to create venv: {str(e)}") |
| 287 | + :param project_dir: Path to the project directory |
| 288 | + :param venv_path: Path to the virtual environment |
| 289 | + :param manager_type: Type of package manager to use |
| 290 | + :return: None |
| 291 | + :raises: BackendExceptions if dependency installation fails |
| 292 | + """ |
| 293 | + try: |
| 294 | + package_manager = PackageManagerFactory.create_manager( |
| 295 | + manager_type, project_dir, auto_detect=True |
| 296 | + ) |
| 297 | + package_manager.install_dependencies(venv_path) |
| 298 | + except Exception as e: |
| 299 | + debug_log(f"Error installing dependencies with {manager_type}: {e}", "error") |
| 300 | + raise BackendExceptions(f"Failed to install dependencies: {str(e)}") |
279 | 301 |
|
280 | 302 |
|
281 | 303 | def install_dependencies(project_dir: str, venv_path: str) -> None: |
282 | 304 | """ |
283 | 305 | Install dependencies in the virtual environment. |
284 | 306 |
|
| 307 | + This is a backward compatibility wrapper that uses pip by default. |
| 308 | +
|
285 | 309 | :param project_dir: Path to the project directory |
286 | 310 | :param venv_path: Path to the virtual environment |
287 | 311 | :return: None |
288 | 312 | """ |
289 | | - try: |
290 | | - if not os.path.exists(venv_path): |
291 | | - debug_log( |
292 | | - "Virtual environment does not exist. Creating it first.", "warning" |
293 | | - ) |
294 | | - print_error("Virtual environment does not exist. Creating it first.") |
295 | | - venv_path = create_venv(project_dir) |
296 | | - if not venv_path: |
297 | | - raise BackendExceptions("Failed to create venv") |
298 | | - |
299 | | - requirements_path = os.path.join(project_dir, "requirements.txt") |
300 | | - if not os.path.exists(requirements_path): |
301 | | - debug_log(f"Requirements file not found at {requirements_path}", "error") |
302 | | - print_error(f"Requirements file not found at {requirements_path}") |
303 | | - raise BackendExceptions("Requirements file not found") |
304 | | - |
305 | | - # Determine pip path based on OS |
306 | | - if os.name == "nt": # Windows |
307 | | - pip_path = os.path.join(venv_path, "Scripts", "pip") |
308 | | - else: # Unix-based |
309 | | - pip_path = os.path.join(venv_path, "bin", "pip") |
310 | | - |
311 | | - # Upgrade pip first |
312 | | - subprocess.run( |
313 | | - [pip_path, "install", "--upgrade", "pip"], |
314 | | - check=True, |
315 | | - capture_output=True, |
316 | | - text=True, |
317 | | - ) |
| 313 | + install_dependencies_with_manager(project_dir, venv_path, "pip") |
318 | 314 |
|
319 | | - # Install dependencies |
320 | | - with console.status("[bold green]Installing dependencies..."): |
321 | | - subprocess.run( |
322 | | - [pip_path, "install", "-r", "requirements.txt"], |
323 | | - cwd=project_dir, |
324 | | - check=True, |
325 | | - capture_output=True, |
326 | | - text=True, |
327 | | - ) |
328 | 315 |
|
329 | | - debug_log("Dependencies installed successfully", "info") |
330 | | - print_success("Dependencies installed successfully") |
331 | | - |
332 | | - except subprocess.CalledProcessError as e: |
333 | | - debug_log(f"Error during dependency installation: {e.stderr}", "error") |
334 | | - handle_exception(e, f"Error during dependency installation: {str(e)}") |
335 | | - if hasattr(e, "stderr"): |
336 | | - print_error(f"Error details: {e.stderr}") |
337 | | - raise BackendExceptions("Failed to install dependencies") |
338 | | - except OSError as e: |
339 | | - debug_log(f"System error during dependency installation: {e}", "error") |
340 | | - handle_exception(e, f"Error during dependency installation: {str(e)}") |
341 | | - raise BackendExceptions(f"Failed to install dependencies: {str(e)}") |
| 316 | +def generate_dependency_file_with_manager( |
| 317 | + project_dir: str, dependencies: List[str], manager_type: str = "pip" |
| 318 | +) -> None: |
| 319 | + """ |
| 320 | + Generate a dependency file using the specified package manager. |
| 321 | +
|
| 322 | + :param project_dir: Path to the project directory |
| 323 | + :param dependencies: List of dependency specifications |
| 324 | + :param manager_type: Type of package manager to use |
| 325 | + :return: None |
| 326 | + :raises: BackendExceptions if dependency file generation fails |
| 327 | + """ |
| 328 | + try: |
| 329 | + package_manager = PackageManagerFactory.create_manager( |
| 330 | + manager_type, project_dir, auto_detect=True |
| 331 | + ) |
| 332 | + package_manager.generate_dependency_file(dependencies) |
| 333 | + except Exception as e: |
| 334 | + debug_log(f"Error generating dependency file with {manager_type}: {e}", "error") |
| 335 | + raise BackendExceptions(f"Failed to generate dependency file: {str(e)}") |
342 | 336 |
|
343 | 337 |
|
344 | 338 | # ------------------------------------------------------------ |
|
0 commit comments