Add utility modules: encryption, file_utils, git_utils, path_utils
Some checks failed
CI / test (push) Failing after 7s
CI / build (push) Has been skipped

This commit is contained in:
2026-02-04 20:07:53 +00:00
parent ab4de66334
commit c51c1f3369

View File

@@ -0,0 +1,80 @@
"""Path utility functions for ConfSync."""
import os
from pathlib import Path
from typing import List
def expand_path(path: str) -> str:
"""Expand user home directory and environment variables in path."""
return os.path.expandvars(os.path.expanduser(path))
def normalize_path(path: str) -> str:
"""Normalize a path to absolute form."""
return str(Path(expand_path(path)).resolve())
def get_home_directory() -> str:
"""Get the user's home directory."""
return str(Path.home())
def get_xdg_config_dir() -> str:
"""Get the XDG config directory, falling back to ~/.config."""
xdg_config = os.environ.get('XDG_CONFIG_HOME')
if xdg_config:
return xdg_config
return os.path.join(get_home_directory(), '.config')
def get_xdg_data_dir() -> str:
"""Get the XDG data directory, falling back to ~/.local/share."""
xdg_data = os.environ.get('XDG_DATA_HOME')
if xdg_data:
return xdg_data
return os.path.join(get_home_directory(), '.local', 'share')
def list_directories(path: str) -> List[str]:
"""List all directories in a path."""
try:
return [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
except OSError:
return []
def path_components(path: str) -> List[str]:
"""Get all components of a path."""
return list(Path(path).parts)
def get_relative_path(path: str, base: str) -> str:
"""Get the relative path from base to path."""
try:
return str(Path(path).relative_to(base))
except ValueError:
return path
def is_subpath(path: str, parent: str) -> bool:
"""Check if path is a subpath of parent."""
try:
path_resolved = Path(expand_path(path)).resolve()
parent_resolved = Path(expand_path(parent)).resolve()
return path_resolved == parent_resolved or parent_resolved in path_resolved.parents
except (OSError, ValueError):
return False
def safe_join(base: str, *parts: str) -> str:
"""Safely join paths, preventing directory traversal."""
base_path = Path(expand_path(base)).resolve()
for part in parts:
if part.startswith('/') or part.startswith('..'):
if '..' in part:
part = part.replace('..', '')
base_path /= part
return str(base_path)