Filesystem
Utilities for directory traversal, file metadata, and batch operations.
Overview
DirTree and FileMetadataReader are static utility classes under buvis.pybase.filesystem. Each exposes class-level helpers—no instantiation is required—to inspect directory depth, prune files, or read timestamps. DirTree bundles cleanup routines (counting files, normalizing extensions, removing empty folders, and merging Mac metadata), while FileMetadataReader surfaces creation and first-commit datetimes with platform-aware fallbacks.
Quick Start
from pathlib import Path
from buvis.pybase.filesystem import DirTree, FileMetadataReader
project_root = Path(__file__).resolve().parent
# Static utilities: no DirTree() or FileMetadataReader() instantiation.
total_files = DirTree.count_files(project_root / "src")
creation_dt = FileMetadataReader.get_creation_datetime(project_root / "pyproject.toml")
first_commit = FileMetadataReader.get_first_commit_datetime(project_root / "pyproject.toml")
print(total_files, creation_dt, first_commit)
API Reference
DirTree
- class buvis.pybase.filesystem.DirTree
Bases:
objectUtility with static directory operations.
Provides static methods for counting files, cleanup routines, and normalization helpers. No instantiation is required.
Example
>>> from buvis.pybase.filesystem import DirTree >>> from pathlib import Path >>> count = DirTree.count_files(Path('/data'))
- static count_files(directory: Path) int
Count the number of files in the directory and its subdirectories.
- Parameters:
directory – Path to the directory to process.
- Returns:
Number of files in the directory and its subdirectories.
- static delete_by_extension(directory: Path, extensions_to_delete: list[str]) None
Delete files with specific extensions in the given directory.
- Parameters:
directory – Path to the directory to process.
extensions_to_delete – List of file extensions to delete.
- Returns:
None. The function modifies the directory in place.
- static get_max_depth(directory: Path) int
Determine the maximum depth of the directory tree.
- Parameters:
directory – Path to the directory to process.
- Returns:
Maximum depth of the directory tree.
- static merge_mac_metadata(directory: Path) None
Restore macOS metadata from AppleDouble helper files.
Walks the directory tree for AppleDouble files (._*) and, when not on Windows, applies their extended attributes back to the corresponding originals before cleaning up any orphaned helper files. This serves as a post-copy cleanup for macOS metadata files.
- Parameters:
directory – Directory containing files and AppleDouble metadata.
- static normalize_file_extensions(directory: Path) None
Normalize file extensions in the given directory: 1) lowercase the extensions 2) replace equivalents
- Parameters:
directory – Path to the directory to process.
- Returns:
None. The function modifies the directory in place.
- static remove_empty_directories(directory: Path) None
Recursively remove all empty directories.
Traverses bottom-up to remove directories that become empty after their children are removed.
- Parameters:
directory – Root directory to clean.
Note
Modifies the directory tree in place. Non-empty directories and files are preserved.
FileMetadataReader
- class buvis.pybase.filesystem.FileMetadataReader
Bases:
objectUtility reader that exposes static helpers for file metadata.
The class is not meant to be instantiated; callers just need to invoke the static helpers to obtain timestamps such as the file creation datetime or the first commit datetime in a Git repository. Creation-time resolution is platform specific (Windows uses st_ctime while Unix systems prefer st_birthtime with a fallback to modification time).
Example
>>> FileMetadataReader.get_creation_datetime(Path("example.txt")) datetime(2024, 7, 8, 12, 34, tzinfo=...)
- static get_creation_datetime(file_path: Path) datetime
Retrieve the creation date of a file, falling back to modification date if creation date is unavailable.
- Parameters:
file_path (Path) – Path to the file.
- Returns:
Datetime when file was created.
- Return type:
datetime
- static get_first_commit_datetime(file_path: Path) datetime | None
Retrieve the date a file was first added to a Git repository located at the parent directory of file_path.
- Parameters:
file_path (Path) – Path to the file.
- Returns:
- Datetime of the first commit involving the file
or None if the file wasn’t committed to any Git repository.
- Return type:
datatime | None
Examples
DirTree Example
Use DirTree to profile and clean a release artifact directory before publishing.
from pathlib import Path
from buvis.pybase.filesystem import DirTree
project_root = Path(__file__).resolve().parent
artifacts_dir = project_root / "dist" / "artifacts"
file_count = DirTree.count_files(artifacts_dir)
max_depth = DirTree.get_max_depth(artifacts_dir)
print(f"Artifact tree: {file_count} files across {max_depth} levels.")
DirTree.delete_by_extension(artifacts_dir, [".tmp", ".log"])
DirTree.normalize_file_extensions(artifacts_dir)
DirTree.remove_empty_directories(artifacts_dir)
DirTree.merge_mac_metadata(artifacts_dir)
# The cleanup routine removes stray caches, coerces extensions to the
# project standard, prunes empty folders, and restores macOS metadata.
FileMetadataReader Example
FileMetadataReader can guard metadata-dependent builds while accounting for non-git working trees.
from pathlib import Path
from buvis.pybase.filesystem import FileMetadataReader
project_root = Path(__file__).resolve().parent
config_file = project_root / "pyproject.toml"
created = FileMetadataReader.get_creation_datetime(config_file)
print(f"{config_file.name} born at {created.isoformat()}")
first_commit = FileMetadataReader.get_first_commit_datetime(config_file)
if first_commit is None:
raise RuntimeError(
f"{config_file} lives outside a Git repository; commit metadata unavailable."
)
print(f"First commit touching {config_file.name} occurred on {first_commit.date()}")