diff --git a/SLS_C/build_system/utils.py b/SLS_C/build_system/utils.py index 3623f5d..c1c6d4e 100644 --- a/SLS_C/build_system/utils.py +++ b/SLS_C/build_system/utils.py @@ -1,41 +1,14 @@ #!/usr/bin/env python3 """ Utility functions for the build system. -Provides common operations like directory creation, process execution, -file dependency checking, and more. +Provides common operations like process execution, +file dependency checking, and tool detection. """ import subprocess import shutil from pathlib import Path from typing import List, Union, Optional -import sys - - -# ----------------------------------------------------------------------------- -# Directory operations -# ----------------------------------------------------------------------------- - -def mkdir(path: Path) -> None: - """ - Create a directory and all parent directories if they don't exist. - - Args: - path: Directory path to create - """ - path.mkdir(parents=True, exist_ok=True) - - -def rmdir(path: Path, ignore_errors: bool = True) -> None: - """ - Recursively remove a directory and all its contents. - - Args: - path: Directory path to remove - ignore_errors: If True, ignore errors during removal - """ - if path.exists(): - shutil.rmtree(path, ignore_errors=ignore_errors) # ----------------------------------------------------------------------------- @@ -174,7 +147,7 @@ def which(tool: str) -> Optional[Path]: return Path(result) if result else None -def check_tool(tool: str, error_message: Optional[str] = None) -> bool: +def check_tool(tool: str) -> bool: """ Check if a tool is available in the system PATH. @@ -187,16 +160,13 @@ def check_tool(tool: str, error_message: Optional[str] = None) -> bool: """ if which(tool): return True - - if error_message: - print(f"ERROR: {error_message}") else: print(f"ERROR: Required tool '{tool}' not found in PATH") return False -def check_tools(tools: List[str], error_messages: Optional[List[str]] = None) -> bool: +def check_tools(tools: List[str]) -> bool: """ Check if multiple tools are available. @@ -209,186 +179,9 @@ def check_tools(tools: List[str], error_messages: Optional[List[str]] = None) -> """ all_found = True - for i, tool in enumerate(tools): - msg = error_messages[i] if error_messages and i < len(error_messages) else None - if not check_tool(tool, msg): + for tool in tools: + if not check_tool(tool): all_found = False return all_found - -# ----------------------------------------------------------------------------- -# File operations -# ----------------------------------------------------------------------------- - -def copy_file(src: Path, dst: Path) -> None: - """ - Copy a file from source to destination. - - Args: - src: Source file path - dst: Destination file path - """ - mkdir(dst.parent) - shutil.copy2(src, dst) - - -def get_files_recursive(directory: Path, pattern: str = "*") -> List[Path]: - """ - Get all files matching a pattern recursively in a directory. - - Args: - directory: Directory to search - pattern: Glob pattern to match (default: "*") - - Returns: - List of matching file paths - """ - if not directory.exists(): - return [] - return list(directory.rglob(pattern)) - - -def get_files(directory: Path, pattern: str = "*") -> List[Path]: - """ - Get all files matching a pattern in a directory (non-recursive). - - Args: - directory: Directory to search - pattern: Glob pattern to match (default: "*") - - Returns: - List of matching file paths - """ - if not directory.exists(): - return [] - return list(directory.glob(pattern)) - - -# ----------------------------------------------------------------------------- -# String formatting -# ----------------------------------------------------------------------------- - -def format_list(items: List[str], indent: int = 2) -> str: - """ - Format a list of items as an indented bulleted list. - - Args: - items: List of strings to format - indent: Number of spaces to indent - - Returns: - Formatted string with bullet points - """ - indent_str = " " * indent - return "\n".join(f"{indent_str}- {item}" for item in items) - - -def print_header(text: str, char: str = "=") -> None: - """ - Print a header with surrounding decoration. - - Args: - text: Header text - char: Character to use for decoration - """ - print() - print(char * len(text)) - print(text) - print(char * len(text)) - print() - - -def print_success(text: str) -> None: - """Print a success message.""" - print(f"✓ {text}") - - -def print_error(text: str) -> None: - """Print an error message to stderr.""" - print(f"✗ {text}", file=sys.stderr) - - -def print_warning(text: str) -> None: - """Print a warning message.""" - print(f"⚠ {text}") - - -# ----------------------------------------------------------------------------- -# Path operations -# ----------------------------------------------------------------------------- - -def get_relative_to_project(path: Path, project_root: Optional[Path] = None) -> Path: - """ - Get a path relative to the project root. - - Args: - path: Absolute or relative path - project_root: Project root directory (default: current directory) - - Returns: - Path relative to project root - """ - if project_root is None: - project_root = Path.cwd() - - try: - return path.relative_to(project_root) - except ValueError: - # Path is not relative to project root, return as-is - return path - - -def ensure_absolute(path: Path, base: Optional[Path] = None) -> Path: - """ - Ensure a path is absolute. - - Args: - path: Path to make absolute - base: Base directory for relative paths (default: current directory) - - Returns: - Absolute path - """ - if path.is_absolute(): - return path - - if base is None: - base = Path.cwd() - - return (base / path).resolve() - - -# ----------------------------------------------------------------------------- -# Version comparison -# ----------------------------------------------------------------------------- - -def compare_versions(v1: str, v2: str) -> int: - """ - Compare two version strings. - - Args: - v1: First version string (e.g., "1.2.3") - v2: Second version string (e.g., "1.2.4") - - Returns: - -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2 - """ - def normalize(v): - return [int(x) for x in v.split(".") if x.isdigit()] - - parts1 = normalize(v1) - parts2 = normalize(v2) - - # Pad shorter version with zeros - max_len = max(len(parts1), len(parts2)) - parts1.extend([0] * (max_len - len(parts1))) - parts2.extend([0] * (max_len - len(parts2))) - - for p1, p2 in zip(parts1, parts2): - if p1 < p2: - return -1 - elif p1 > p2: - return 1 - - return 0