-
-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathfile_filter.py
More file actions
91 lines (79 loc) · 2.57 KB
/
Copy pathfile_filter.py
File metadata and controls
91 lines (79 loc) · 2.57 KB
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
"""Lightweight file-listing utilities for @-mention path completion.
Provides two strategies:
- ``list_files_git`` — fast, uses ``git ls-files`` when inside a repo.
- ``list_files_walk`` — fallback, walks the directory tree manually.
- ``detect_git`` — returns True if *root* is inside a git work-tree.
"""
from __future__ import annotations
import os
import subprocess
from pathlib import Path
from typing import List, Optional
# Directories to always skip during manual walk
_SKIP_DIRS = frozenset((
".git", "__pycache__", "node_modules", ".venv", "venv",
".mypy_cache", ".pytest_cache", ".tox", "dist", "build",
".eggs", "*.egg-info",
))
def detect_git(root: Path | str) -> bool:
"""Return True if *root* is inside a Git work-tree."""
try:
result = subprocess.run(
["git", "rev-parse", "--is-inside-work-tree"],
cwd=str(root),
capture_output=True,
text=True,
timeout=3,
)
return result.returncode == 0 and result.stdout.strip() == "true"
except Exception:
return False
def list_files_git(root: Path | str, scope: Optional[str] = None) -> List[str]:
"""List tracked files via ``git ls-files``.
*scope* optionally restricts to a sub-directory (relative to *root*).
"""
cmd = ["git", "ls-files"]
if scope:
cmd.append(scope)
try:
result = subprocess.run(
cmd,
cwd=str(root),
capture_output=True,
text=True,
timeout=5,
)
if result.returncode != 0:
return []
return [line for line in result.stdout.splitlines() if line]
except Exception:
return []
def list_files_walk(
root: Path | str,
scope: Optional[str] = None,
*,
limit: int = 1000,
) -> List[str]:
"""Walk the directory tree and return relative paths (up to *limit*)."""
base = Path(root)
if scope:
base = base / scope
if not base.is_dir():
return []
paths: List[str] = []
for dirpath, dirnames, filenames in os.walk(base):
# Prune skipped directories in-place
dirnames[:] = [
d for d in dirnames
if d not in _SKIP_DIRS and not d.endswith(".egg-info")
]
for fname in filenames:
full = Path(dirpath) / fname
try:
rel = str(full.relative_to(root))
except ValueError:
rel = str(full)
paths.append(rel.replace("\\", "/"))
if len(paths) >= limit:
return paths
return paths