93 lines
2.1 KiB
Python
93 lines
2.1 KiB
Python
"""File utility functions."""
|
|
|
|
import os
|
|
from typing import Generator, Optional
|
|
|
|
|
|
def find_files(
|
|
pattern: str,
|
|
base_path: Optional[str] = None,
|
|
recursive: bool = True,
|
|
) -> Generator[str, None, None]:
|
|
"""Find files matching a pattern.
|
|
|
|
Args:
|
|
pattern: File pattern (e.g., "**/*.py")
|
|
base_path: Base path to search from
|
|
recursive: Whether to search recursively
|
|
|
|
Yields:
|
|
Matching file paths
|
|
"""
|
|
import glob
|
|
|
|
search_pattern = pattern
|
|
if base_path:
|
|
search_pattern = os.path.join(base_path, pattern)
|
|
|
|
matches = glob.glob(search_pattern, recursive=recursive)
|
|
for match in sorted(matches):
|
|
if os.path.isfile(match):
|
|
yield match
|
|
|
|
|
|
def read_file_safe(file_path: str, encoding: str = "utf-8") -> tuple[str, Optional[str]]:
|
|
"""Read file contents safely.
|
|
|
|
Args:
|
|
file_path: Path to file
|
|
encoding: File encoding
|
|
|
|
Returns:
|
|
Tuple of (content, None) on success or (None, error_message) on failure
|
|
"""
|
|
try:
|
|
with open(file_path, "r", encoding=encoding) as f:
|
|
return f.read(), None
|
|
except UnicodeDecodeError:
|
|
try:
|
|
with open(file_path, "r", encoding="latin-1") as f:
|
|
return f.read(), None
|
|
except Exception as e:
|
|
return None, str(e)
|
|
except Exception as e:
|
|
return None, str(e)
|
|
|
|
|
|
def get_file_extension(file_path: str) -> str:
|
|
"""Get file extension in lowercase.
|
|
|
|
Args:
|
|
file_path: Path to file
|
|
|
|
Returns:
|
|
File extension including the dot
|
|
"""
|
|
_, ext = os.path.splitext(file_path)
|
|
return ext.lower()
|
|
|
|
|
|
def ensure_directory_exists(path: str) -> None:
|
|
"""Ensure directory exists, create if needed.
|
|
|
|
Args:
|
|
path: Directory path
|
|
"""
|
|
os.makedirs(path, exist_ok=True)
|
|
|
|
|
|
def get_relative_path(file_path: str, base_path: str) -> str:
|
|
"""Get relative path from base path.
|
|
|
|
Args:
|
|
file_path: Full file path
|
|
base_path: Base path
|
|
|
|
Returns:
|
|
Relative path
|
|
"""
|
|
try:
|
|
return os.path.relpath(file_path, base_path)
|
|
except ValueError:
|
|
return file_path
|