Source code for irorun.helpers

# Copyright 2025 Faith O. Oyedemi
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# For more details, see the full text of the Apache License at:
# http://www.apache.org/licenses/LICENSE-2.0

import os
import subprocess
from collections.abc import Iterable
from contextlib import contextmanager
from enum import Enum
from pathlib import Path
from typing import Optional

import typer


[docs] class EnvManager(Enum): POETRY = 'poetry' UV = 'uv' VIRTUALENV = 'virtualenv'
[docs] @contextmanager def change_dir(new_dir: str): """Context manager for changing the current working directory.""" previous_dir = os.getcwd() os.chdir(new_dir) try: yield finally: os.chdir(previous_dir)
[docs] def run_command(cmd: list[str], cwd: Optional[str] = None) -> None: """Wrapper for subprocess.run to execute a command and handle errors.""" try: subprocess.run(cmd, check=True, cwd=cwd) except subprocess.CalledProcessError as e: typer.echo(f'Error running command {cmd}: {e}', err=True) raise typer.Exit(1) from e
[docs] def add_dependencies(package_manager: EnvManager, dependencies: list[str]) -> None: """ Adds dependencies using the specified package manager. Only supports POETRY and UV. """ if package_manager not in (EnvManager.POETRY, EnvManager.UV): typer.echo('Invalid package manager', err=True) raise typer.Exit(1) run_command([package_manager.value, 'add'] + dependencies) typer.echo(f'Added dependencies: {dependencies}')
[docs] def create_poetry_project( project_dir: str, dependencies: Optional[list[str]] = None ) -> None: """ Creates a new Poetry project and optionally installs dependencies. """ run_command(['poetry', 'new', project_dir]) typer.echo(f'Created new Poetry project in {project_dir}') with change_dir(project_dir): if dependencies: typer.echo(f'Installing dependencies: {dependencies}') add_dependencies(EnvManager.POETRY, dependencies)
[docs] def create_uv_project( project_dir: str, venv_name: str, dependencies: Optional[list[str]] = None ) -> None: """ Creates a new project with a virtual environment using uv. """ run_command(['uv', 'init', project_dir]) with change_dir(project_dir): run_command(['uv', 'venv', venv_name]) typer.echo(f'Created virtual environment "{venv_name}" in {project_dir}') if dependencies: typer.echo(f'Installing dependencies: {dependencies}') add_dependencies(EnvManager.UV, dependencies)
[docs] def create_virtualenv_project( project_dir: str, venv_name: str, dependencies: Optional[list[str]] = None ) -> None: """ Creates a new project directory and virtual environment using virtualenv. """ Path(project_dir).mkdir(parents=True, exist_ok=True) with change_dir(project_dir): run_command(['virtualenv', venv_name]) # Determine the correct path for the pip executable in the virtual environment. venv_path = Path(venv_name) bin_dir = 'Scripts' if os.name == 'nt' else 'bin' pip_executable = str(venv_path / bin_dir / 'pip') run_command([pip_executable, 'install', '-U', 'pip']) if dependencies: typer.echo(f'Installing dependencies: {dependencies}') run_command([pip_executable, 'install'] + dependencies) typer.echo('Dependencies installed successfully.') typer.echo(f'Created virtual environment project in {project_dir}')
[docs] def create_subdirectories(project_dir: str, subdirectories: Iterable[str]) -> None: """ Creates subdirectories within a project directory. Parameters: project_dir: The base project directory. subdirectories: An iterable of subdirectory names to create under project_dir. """ base = Path(project_dir) for subdir in subdirectories: sub_path = base / subdir sub_path.mkdir(parents=True, exist_ok=True) typer.echo(f'Created subdirectory: {sub_path}')