This commit is contained in:
92
.code_doc_cli/utils/file_utils.py
Normal file
92
.code_doc_cli/utils/file_utils.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
"""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
|
||||||
Reference in New Issue
Block a user