treex-cli 0.1.10__tar.gz → 0.1.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: treex-cli
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: List directory contents as a tree with file and directory metadata
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "treex-cli"
7
- version = "0.1.10"
7
+ version = "0.1.11"
8
8
  description="List directory contents as a tree with file and directory metadata"
9
9
  license = "MIT"
10
10
  license-files = ["LICENSE"]
@@ -43,22 +43,40 @@ class GitIgnore:
43
43
  self.enabled = True
44
44
 
45
45
  def ignored(self, path):
46
- """Check if Git considers the path ignored."""
47
- if not self.enabled:
48
- return False
46
+ """Check if Git considers a path ignored."""
47
+ return bool(self.ignored_many([path]))
48
+
49
+ def ignored_many(self, paths):
50
+ """Check which paths Git considers ignored."""
51
+ if not self.enabled or self.repo_root is None:
52
+ return set()
53
+ relative_paths = []
54
+ for path in paths:
55
+ try:
56
+ relative = path.resolve().relative_to(self.repo_root)
57
+ except (ValueError, OSError):
58
+ continue
59
+ relative_paths.append(relative.as_posix())
60
+ if not relative_paths:
61
+ return set()
49
62
  try:
50
- relative_path = path.resolve().relative_to(self.repo_root)
63
+ # Check all paths in one Git call.
64
+ # -z uses NUL delimiters to safely handle filenames
65
+ # containing special characters.
51
66
  result = subprocess.run(
52
- ["git", "check-ignore", "--quiet", "--", str(relative_path)],
67
+ ["git", "check-ignore", "--stdin", "-z"],
53
68
  cwd=self.repo_root,
54
- stdout=subprocess.DEVNULL,
69
+ input="\0".join(relative_paths) + "\0",
70
+ stdout=subprocess.PIPE,
55
71
  stderr=subprocess.DEVNULL,
72
+ text=True,
56
73
  check=False,
57
74
  )
58
- except (ValueError, OSError):
59
- return False
60
- else:
61
- return result.returncode == 0
75
+ except OSError:
76
+ return set()
77
+ if result.returncode not in (0, 1):
78
+ return set()
79
+ return set(result.stdout.split("\0")) - {""}
62
80
 
63
81
 
64
82
  def _format_size(size):
@@ -132,14 +150,21 @@ def _get_tree_entries(path, gitignore):
132
150
  entries = list(path.iterdir())
133
151
  except PermissionError:
134
152
  return None
135
- # Filter ignored entries and Git's internal directory
136
- entries = [
137
- entry
138
- for entry in entries
139
- if not entry.is_symlink()
140
- and (not gitignore or (entry.name != ".git" and not gitignore.ignored(entry)))
141
- ]
142
- # Group directories first and sort names case-insensitive
153
+ entries = [entry for entry in entries if not entry.is_symlink()]
154
+ if gitignore is not None:
155
+ entries = [entry for entry in entries if entry.name != ".git"]
156
+ if gitignore.enabled and gitignore.repo_root is not None:
157
+ ignored = gitignore.ignored_many(entries)
158
+ filtered_entries = []
159
+ for entry in entries:
160
+ try:
161
+ relative = entry.resolve().relative_to(gitignore.repo_root)
162
+ except (ValueError, OSError):
163
+ filtered_entries.append(entry)
164
+ continue
165
+ if relative.as_posix() not in ignored:
166
+ filtered_entries.append(entry)
167
+ entries = filtered_entries
143
168
  entries.sort(key=lambda p: (p.is_file(), p.name.casefold()))
144
169
  return entries
145
170
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: treex-cli
3
- Version: 0.1.10
3
+ Version: 0.1.11
4
4
  Summary: List directory contents as a tree with file and directory metadata
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
File without changes
File without changes
File without changes