treecap 0.1.0__py3-none-any.whl
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.
treecap/__init__.py
ADDED
treecap/cli.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""treecap CLI — print a directory tree, capping entries shown per folder.
|
|
2
|
+
|
|
3
|
+
Unlike `tree --filelimit`, which hides a directory entirely once it has too
|
|
4
|
+
many entries, treecap always recurses but caps the *display* per directory,
|
|
5
|
+
collapsing the overflow into a "... (N more)" line.
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from . import __version__
|
|
12
|
+
|
|
13
|
+
# Directories we never descend into by default.
|
|
14
|
+
DEFAULT_SKIP = {".git", "node_modules", "__pycache__", ".venv", "venv"}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def list_entries(path, show_all, skip):
|
|
18
|
+
try:
|
|
19
|
+
entries = sorted(
|
|
20
|
+
os.scandir(path), key=lambda e: (not e.is_dir(), e.name.lower())
|
|
21
|
+
)
|
|
22
|
+
except (PermissionError, FileNotFoundError):
|
|
23
|
+
return []
|
|
24
|
+
out = []
|
|
25
|
+
for e in entries:
|
|
26
|
+
if not show_all and e.name.startswith("."):
|
|
27
|
+
continue
|
|
28
|
+
if e.is_dir() and e.name in skip:
|
|
29
|
+
continue
|
|
30
|
+
out.append(e)
|
|
31
|
+
return out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def walk(path, prefix, width, max_depth, depth, show_all, skip):
|
|
35
|
+
if max_depth is not None and depth >= max_depth:
|
|
36
|
+
return
|
|
37
|
+
entries = list_entries(path, show_all, skip)
|
|
38
|
+
shown = entries if width is None else entries[:width]
|
|
39
|
+
hidden = len(entries) - len(shown)
|
|
40
|
+
|
|
41
|
+
for i, e in enumerate(shown):
|
|
42
|
+
last = (i == len(shown) - 1) and hidden == 0
|
|
43
|
+
connector = "└── " if last else "├── "
|
|
44
|
+
print(prefix + connector + e.name + ("/" if e.is_dir() else ""))
|
|
45
|
+
if e.is_dir():
|
|
46
|
+
extension = " " if last else "│ "
|
|
47
|
+
walk(e.path, prefix + extension, width, max_depth,
|
|
48
|
+
depth + 1, show_all, skip)
|
|
49
|
+
|
|
50
|
+
if hidden > 0:
|
|
51
|
+
print(prefix + f"└── ... ({hidden} more)")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def build_parser():
|
|
55
|
+
p = argparse.ArgumentParser(
|
|
56
|
+
prog="treecap",
|
|
57
|
+
description="A directory tree that caps how many entries are shown "
|
|
58
|
+
"per folder (the rest collapse into '... (N more)').",
|
|
59
|
+
)
|
|
60
|
+
p.add_argument("root", nargs="?", default=".",
|
|
61
|
+
help="directory to walk (default: current dir)")
|
|
62
|
+
p.add_argument("-W", "--width", type=int, default=5, metavar="N",
|
|
63
|
+
help="max entries shown per directory (default: 5; "
|
|
64
|
+
"use 0 for unlimited)")
|
|
65
|
+
p.add_argument("-L", "--level", type=int, default=None, metavar="DEPTH",
|
|
66
|
+
help="max display depth (default: unlimited)")
|
|
67
|
+
p.add_argument("-a", "--all", action="store_true",
|
|
68
|
+
help="include hidden files/dirs (dotfiles)")
|
|
69
|
+
p.add_argument("--no-skip", action="store_true",
|
|
70
|
+
help="don't skip .git/node_modules/__pycache__/.venv")
|
|
71
|
+
p.add_argument("--version", action="version",
|
|
72
|
+
version=f"%(prog)s {__version__}")
|
|
73
|
+
return p
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def main(argv=None):
|
|
77
|
+
args = build_parser().parse_args(argv)
|
|
78
|
+
width = None if args.width == 0 else args.width
|
|
79
|
+
skip = set() if args.no_skip else DEFAULT_SKIP
|
|
80
|
+
|
|
81
|
+
print(args.root.rstrip("/") + "/")
|
|
82
|
+
try:
|
|
83
|
+
walk(args.root, "", width, args.level, 0, args.all, skip)
|
|
84
|
+
except BrokenPipeError: # e.g. piped into `head`
|
|
85
|
+
try:
|
|
86
|
+
sys.stdout.close()
|
|
87
|
+
except Exception:
|
|
88
|
+
pass
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: treecap
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A directory tree that caps how many entries are shown per folder.
|
|
5
|
+
Author: Dheeraj Pai
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dheerajpai/treecap
|
|
8
|
+
Keywords: tree,cli,filesystem,directory
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# treecap
|
|
17
|
+
|
|
18
|
+
A directory tree that shows the **full structure** but caps how many entries
|
|
19
|
+
are shown per folder. The overflow collapses into a `... (N more)` line — so a
|
|
20
|
+
folder with 698 files doesn't drown the rest of the tree.
|
|
21
|
+
|
|
22
|
+
Unlike `tree -L` (which limits depth) or `tree --filelimit` (which hides big
|
|
23
|
+
directories entirely), `treecap` always recurses but caps the *display* width
|
|
24
|
+
per directory.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pipx install . # recommended — isolated, on your PATH
|
|
30
|
+
# or
|
|
31
|
+
pip install -e . # editable install into the current environment
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
treecap # current dir, 5 entries per folder
|
|
38
|
+
treecap -W 10 # show 10 entries per folder
|
|
39
|
+
treecap -L 3 # limit display depth to 3 levels
|
|
40
|
+
treecap -W 5 -L 4 data # 5 per folder, 4 deep, starting at ./data
|
|
41
|
+
treecap -a # include hidden dotfiles
|
|
42
|
+
treecap --no-skip # don't auto-skip .git/node_modules/etc.
|
|
43
|
+
treecap > dir.tree # save to a file
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Options
|
|
47
|
+
|
|
48
|
+
| Flag | Meaning |
|
|
49
|
+
|------|---------|
|
|
50
|
+
| `-W, --width N` | Max entries shown per directory (default 5; `0` = unlimited) |
|
|
51
|
+
| `-L, --level DEPTH` | Max display depth (default: unlimited) |
|
|
52
|
+
| `-a, --all` | Include hidden files/dirs |
|
|
53
|
+
| `--no-skip` | Don't skip `.git`, `node_modules`, `__pycache__`, `.venv`, `venv` |
|
|
54
|
+
| `--version` | Print version |
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
treecap/__init__.py,sha256=HY_NJswjG_fzZnzxJ5OfeZKzfy6Nk6RZ8HT9kILwu2I,86
|
|
2
|
+
treecap/cli.py,sha256=Ufq-q6pUgySG4oTv-2fFsR5SkKF2zh7nRh57CzCMLWc,3219
|
|
3
|
+
treecap-0.1.0.dist-info/METADATA,sha256=75X0JjZrvFA4bFDBIQVtwhBCXMcpHNO5Pse9QcwTRs4,1843
|
|
4
|
+
treecap-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
treecap-0.1.0.dist-info/entry_points.txt,sha256=RzfPCN9hQjOt6zk5BrPDOKa_MtfRIp_X1cpMOqKLjMQ,45
|
|
6
|
+
treecap-0.1.0.dist-info/top_level.txt,sha256=YLX5s6KQh3XIhQGzi9VNUYLhU5S2DMavZofNH8exGRA,8
|
|
7
|
+
treecap-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
treecap
|