File size: 1,850 Bytes
60a5d0b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | """
scanner.py
Project scanning
"""
from __future__ import annotations
from pathlib import Path
from filters import (
is_probably_binary,
should_ignore_dir,
should_ignore_file,
)
def scan_files(
root: Path,
extra_ignore_dirs: set[str],
max_size_mb: float,
allowed_extensions: set[str] | None,
) -> list[Path]:
"""
Scan project recursively.
"""
files = []
max_bytes = int(max_size_mb * 1024 * 1024)
for path in root.rglob("*"):
if path.is_dir():
continue
rel_parts = path.relative_to(root).parts[:-1]
if any(
should_ignore_dir(
part,
extra_ignore_dirs,
)
for part in rel_parts
):
continue
if should_ignore_file(
path,
allowed_extensions,
):
continue
try:
if path.stat().st_size > max_bytes:
continue
except OSError:
continue
if is_probably_binary(path):
continue
files.append(path)
files.sort(
key=lambda p: p.relative_to(root).as_posix()
)
return files
def build_tree_text(
root: Path,
files: list[Path],
) -> str:
"""
Render project tree.
"""
if not files:
return "(No files found)"
lines = []
for file in files:
rel = file.relative_to(root)
indent = " " * (len(rel.parts) - 1)
lines.append(
f"{indent}├── {rel.name}"
)
return "\n".join(lines)
def total_project_size(
files: list[Path],
) -> int:
"""
Sum file sizes.
"""
total = 0
for file in files:
try:
total += file.stat().st_size
except OSError:
pass
return total |