Source code for scitex_core.path._find

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File: ./src/scitex_core/path/_find.py

"""
File and directory search utilities for scitex-core.

Provides Unix find-like functionality for locating files and directories,
with optional git repository detection.
"""

import fnmatch
import os
from typing import List, Optional, Union


[docs] def find_git_root(start_path: str = ".") -> Optional[str]: """ Find the root directory of a git repository. Parameters ---------- start_path : str, optional Starting directory for search. Default is current directory. Returns ------- str or None Path to git repository root, or None if not in a git repository Examples -------- >>> from scitex_core.path import find_git_root >>> root = find_git_root() >>> print(root) # e.g., '/home/user/my-project' Notes ----- This function searches for a .git directory by walking up the directory tree. It does not require the gitpython package. """ current = os.path.abspath(start_path) while True: git_dir = os.path.join(current, ".git") if os.path.isdir(git_dir): return current parent = os.path.dirname(current) if parent == current: # Reached root directory return None current = parent
[docs] def find_dir(root_dir: str, pattern: Union[str, List[str]] = "*") -> List[str]: """ Find directories matching a pattern. Parameters ---------- root_dir : str Root directory to start search pattern : str or list of str, optional Pattern(s) to match directory names. Default is "*" (all). Returns ------- list of str List of matching directory paths Examples -------- >>> from scitex_core.path import find_dir >>> dirs = find_dir("/home/user", "test_*") >>> dirs = find_dir("/home/user", ["src", "lib"]) """ return _find(root_dir, type="d", pattern=pattern)
[docs] def find_file(root_dir: str, pattern: Union[str, List[str]] = "*") -> List[str]: """ Find files matching a pattern. Parameters ---------- root_dir : str Root directory to start search pattern : str or list of str, optional Pattern(s) to match file names. Default is "*" (all). Returns ------- list of str List of matching file paths Examples -------- >>> from scitex_core.path import find_file >>> files = find_file("/home/user", "*.py") >>> files = find_file("/home/user", ["*.txt", "*.md"]) """ return _find(root_dir, type="f", pattern=pattern)
def _find( rootdir: str, type: str = "f", pattern: Union[str, List[str]] = "*", exclude: Optional[List[str]] = None, ) -> List[str]: """ Core find implementation mimicking Unix find command. Parameters ---------- rootdir : str Root directory to search type : str, optional Type to search for: 'f' (files), 'd' (directories), or None (both) pattern : str or list of str, optional Pattern(s) to match names against exclude : list of str, optional Path patterns to exclude from results Returns ------- list of str List of matching paths Notes ----- Default exclusions: /lib/, /env/, /build/, __pycache__ """ if isinstance(pattern, str): pattern = [pattern] if exclude is None: exclude = ["/lib/", "/env/", "/build/", "__pycache__"] matches = [] for pat in pattern: for root, dirs, files in os.walk(rootdir): # Choose list based on type if type == "f": # Files only names = files elif type == "d": # Directories only names = dirs else: # All entries names = files + dirs for name in names: # Construct full path path = os.path.join(root, name) # Pattern matching if pat and not fnmatch.fnmatch(name, pat): continue # Type checking if type == "f" and not os.path.isfile(path): continue if type == "d" and not os.path.isdir(path): continue # Exclusions if any(ex in path for ex in exclude): continue matches.append(path) return matches __all__ = ["find_git_root", "find_dir", "find_file"] # EOF