treex-cli 0.1.5__tar.gz → 0.1.7__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,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: treex-cli
3
- Version: 0.1.5
4
- Summary: List directory contents as a tree with file metadata
3
+ Version: 0.1.7
4
+ Summary: List directory contents as a tree with file and directory metadata
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
7
7
  License-Expression: MIT
@@ -25,7 +25,7 @@ Dynamic: license-file
25
25
 
26
26
  # treex
27
27
 
28
- ## List directory contents as a tree with file metadata
28
+ ## List directory contents as a tree with file and directory metadata
29
29
 
30
30
  - Copyright (c) 2026 [Corey Goldberg][github-profile]
31
31
  - Development: [GitHub][github-repo]
@@ -37,12 +37,13 @@ Dynamic: license-file
37
37
  ## About
38
38
 
39
39
  `treex` is a command-line utility that recursively scans a directory and
40
- displays its contents as a tree along with file metadata.
40
+ lists its contents as a tree along with file and directory metadata.
41
41
 
42
- - Displays human-readable file sizes
42
+ - Shows human-readable file sizes
43
+ - Shows recursive directory sizes
43
44
  - Shows line counts for text files
44
45
  - Identifies binary and unreadable files by type
45
- - Optionally displays modification timestamps
46
+ - Optionally shows modification timestamps
46
47
  - Respects `.gitignore` rules when Git is installed
47
48
 
48
49
  ----
@@ -101,7 +102,7 @@ Install `treex` from [PyPI][pypi-home] using either `pip` or `pipx`:
101
102
  $ treex --help
102
103
  usage: treex [-h] [-a] [-m] [-q] [-s] [directory]
103
104
 
104
- List directory contents as a tree with file metadata.
105
+ List directory contents as a tree with file and directory metadata.
105
106
 
106
107
  positional arguments:
107
108
  directory directory to scan (default: current directory)
@@ -1,6 +1,6 @@
1
1
  # treex
2
2
 
3
- ## List directory contents as a tree with file metadata
3
+ ## List directory contents as a tree with file and directory metadata
4
4
 
5
5
  - Copyright (c) 2026 [Corey Goldberg][github-profile]
6
6
  - Development: [GitHub][github-repo]
@@ -12,12 +12,13 @@
12
12
  ## About
13
13
 
14
14
  `treex` is a command-line utility that recursively scans a directory and
15
- displays its contents as a tree along with file metadata.
15
+ lists its contents as a tree along with file and directory metadata.
16
16
 
17
- - Displays human-readable file sizes
17
+ - Shows human-readable file sizes
18
+ - Shows recursive directory sizes
18
19
  - Shows line counts for text files
19
20
  - Identifies binary and unreadable files by type
20
- - Optionally displays modification timestamps
21
+ - Optionally shows modification timestamps
21
22
  - Respects `.gitignore` rules when Git is installed
22
23
 
23
24
  ----
@@ -76,7 +77,7 @@ Install `treex` from [PyPI][pypi-home] using either `pip` or `pipx`:
76
77
  $ treex --help
77
78
  usage: treex [-h] [-a] [-m] [-q] [-s] [directory]
78
79
 
79
- List directory contents as a tree with file metadata.
80
+ List directory contents as a tree with file and directory metadata.
80
81
 
81
82
  positional arguments:
82
83
  directory directory to scan (default: current directory)
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "treex-cli"
7
- version = "0.1.5"
8
- description="List directory contents as a tree with file metadata"
7
+ version = "0.1.7"
8
+ description="List directory contents as a tree with file and directory metadata"
9
9
  license = "MIT"
10
10
  license-files = ["LICENSE"]
11
11
  authors = [{name = "Corey Goldberg"}]
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- """List directory contents as a tree with file metadata.
5
+ """List directory contents as a tree with file and directory metadata.
6
6
 
7
7
  The directory tree is rendered using Unicode box-drawing characters.
8
8
 
@@ -14,6 +14,7 @@ filesystem is scanned normally without Git filtering.
14
14
 
15
15
  import argparse
16
16
  import subprocess
17
+ import sys
17
18
  from contextlib import suppress
18
19
  from datetime import datetime
19
20
  from pathlib import Path
@@ -60,15 +61,17 @@ class GitIgnore:
60
61
  return result.returncode == 0
61
62
 
62
63
 
63
- def _format_size(size): # noqa: RET503
64
+ def _format_size(size):
64
65
  """Format bytes as a human-readable size."""
65
66
  units = ["B", "KB", "MB", "GB", "TB"]
66
67
  for unit in units:
67
- if size < 1024 or unit == units[-1]:
68
+ if size < 1024:
68
69
  if unit == "B":
69
70
  return f"{size} B"
70
71
  return f"{size:.1f} {unit}"
71
72
  size /= 1024
73
+ # Anything above 1 TB is shown in TB
74
+ return f"{size:.1f} TB"
72
75
 
73
76
 
74
77
  def _format_modified(timestamp):
@@ -154,17 +157,19 @@ def _collect_tree(
154
157
  entries = _get_tree_entries(path, gitignore)
155
158
  if entries is None:
156
159
  rows.append((prefix + "└── [permission denied]", None))
157
- return
160
+ return 0
161
+ total_size = 0
158
162
  for index, entry in enumerate(entries):
159
163
  is_last = index == len(entries) - 1
160
164
  connector = "└── " if is_last else "├── "
161
165
  tree_name = prefix + connector + entry.name
162
166
  if entry.is_dir():
163
167
  stats["directories"] += 1
168
+ row_index = len(rows)
164
169
  rows.append((tree_name, None))
165
170
  # Indent nested entries, preserving the tree's vertical branch
166
171
  extension = " " if is_last else "│ "
167
- _collect_tree(
172
+ dir_size = _collect_tree(
168
173
  entry,
169
174
  prefix + extension,
170
175
  stats,
@@ -173,24 +178,32 @@ def _collect_tree(
173
178
  show_metadata,
174
179
  show_modified,
175
180
  )
181
+ total_size += dir_size
182
+ if show_metadata:
183
+ rows[row_index] = (tree_name, (_format_size(dir_size), None, None))
176
184
  elif entry.is_file():
177
- stats["files"] += 1
178
185
  if show_metadata:
179
186
  size_text, info, size, modified = _file_metadata(entry)
187
+ stats["files"] += 1
180
188
  stats["total_size"] += size
189
+ total_size += size
181
190
  timestamp = modified if show_modified else None
182
191
  rows.append((tree_name, (size_text, info, timestamp)))
183
192
  else:
193
+ stats["files"] += 1
184
194
  stats["total_size"] = None
185
195
  rows.append((tree_name, None))
196
+ return total_size
186
197
 
187
198
 
188
199
  def print_summary(stats):
189
200
  directories = stats["directories"]
190
201
  files = stats["files"]
191
202
  total_size = stats["total_size"]
192
- summary = f"{directories:,} directories • {files:,} files"
193
- if total_size:
203
+ directory_label = "directory" if directories == 1 else "directories"
204
+ file_label = "file" if files == 1 else "files"
205
+ summary = f"{directories:,} {directory_label} • {files:,} {file_label}"
206
+ if total_size is not None:
194
207
  summary += f" • {_format_size(total_size)}"
195
208
  print(summary)
196
209
 
@@ -229,7 +242,9 @@ def print_tree(
229
242
  print(tree_name)
230
243
  continue
231
244
  size_text, info, modified = file_info_data
232
- output = f"{tree_name:<{max_tree_name_width}}{size_text:>10} {info:<10}"
245
+ output = f"{tree_name:<{max_tree_name_width}}{size_text:>10}"
246
+ if info is not None:
247
+ output += f" {info:<10}"
233
248
  if modified is not None:
234
249
  output += f" {modified}"
235
250
  print(output)
@@ -239,7 +254,8 @@ def print_tree(
239
254
  def parse_args(argv=None):
240
255
  """Parse command-line arguments."""
241
256
  parser = argparse.ArgumentParser(
242
- description="List directory contents as a tree with file metadata.",
257
+ description="List directory contents as a tree with "
258
+ "file and directory metadata.",
243
259
  )
244
260
  parser.add_argument(
245
261
  "directory",
@@ -276,28 +292,33 @@ def parse_args(argv=None):
276
292
 
277
293
 
278
294
  def main():
279
- args = parse_args()
280
- path = args.directory
281
- if not path.is_dir():
282
- print(f"Not a directory: {path}")
283
- return 1
284
- # Only initialize Git support if it will be used
285
- gitignore = None if args.all else GitIgnore(path)
286
- show_tree = not args.summary
287
- show_metadata = not args.quiet
288
- if show_tree:
289
- print(path)
290
- stats = print_tree(
291
- path,
292
- gitignore=gitignore,
293
- show_metadata=show_metadata,
294
- show_modified=args.modified,
295
- show_tree=show_tree,
296
- )
297
- if show_tree:
298
- print()
299
- print_summary(stats)
300
- return 0
295
+ try:
296
+ args = parse_args()
297
+ path = args.directory
298
+ if not path.is_dir():
299
+ print(f"Not a directory: {path}", file=sys.stderr)
300
+ return 1
301
+ # Only initialize Git support if it will be used
302
+ gitignore = None if args.all else GitIgnore(path)
303
+ show_tree = not args.summary
304
+ show_metadata = not args.quiet
305
+ if show_tree:
306
+ print(path)
307
+ stats = print_tree(
308
+ path,
309
+ gitignore=gitignore,
310
+ show_metadata=show_metadata,
311
+ show_modified=args.modified,
312
+ show_tree=show_tree,
313
+ )
314
+ if show_tree:
315
+ print()
316
+ print_summary(stats)
317
+ except KeyboardInterrupt:
318
+ print("\nInterrupted", file=sys.stderr)
319
+ return 130
320
+ else:
321
+ return 0
301
322
 
302
323
 
303
324
  if __name__ == "__main__":
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: treex-cli
3
- Version: 0.1.5
4
- Summary: List directory contents as a tree with file metadata
3
+ Version: 0.1.7
4
+ Summary: List directory contents as a tree with file and directory metadata
5
5
  Author: Corey Goldberg
6
6
  Maintainer: Corey Goldberg
7
7
  License-Expression: MIT
@@ -25,7 +25,7 @@ Dynamic: license-file
25
25
 
26
26
  # treex
27
27
 
28
- ## List directory contents as a tree with file metadata
28
+ ## List directory contents as a tree with file and directory metadata
29
29
 
30
30
  - Copyright (c) 2026 [Corey Goldberg][github-profile]
31
31
  - Development: [GitHub][github-repo]
@@ -37,12 +37,13 @@ Dynamic: license-file
37
37
  ## About
38
38
 
39
39
  `treex` is a command-line utility that recursively scans a directory and
40
- displays its contents as a tree along with file metadata.
40
+ lists its contents as a tree along with file and directory metadata.
41
41
 
42
- - Displays human-readable file sizes
42
+ - Shows human-readable file sizes
43
+ - Shows recursive directory sizes
43
44
  - Shows line counts for text files
44
45
  - Identifies binary and unreadable files by type
45
- - Optionally displays modification timestamps
46
+ - Optionally shows modification timestamps
46
47
  - Respects `.gitignore` rules when Git is installed
47
48
 
48
49
  ----
@@ -101,7 +102,7 @@ Install `treex` from [PyPI][pypi-home] using either `pip` or `pipx`:
101
102
  $ treex --help
102
103
  usage: treex [-h] [-a] [-m] [-q] [-s] [directory]
103
104
 
104
- List directory contents as a tree with file metadata.
105
+ List directory contents as a tree with file and directory metadata.
105
106
 
106
107
  positional arguments:
107
108
  directory directory to scan (default: current directory)
File without changes
File without changes