Skip to content

Commit 1b49b04

Browse files
committed
🐛 Enforce max_depth limit in flat and tree renderers
Add early return in recursive rendering functions to skip nodes beyond max_depth, ensuring the parameter is respected and preventing excessive output or recursion in deep directory structures.
1 parent 484fabc commit 1b49b04

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

src/cedarmapper/render/flat.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ def render_flat(
6161
rows: list[_DisplayRow] = []
6262

6363
def _render_node(node: DirInfo | FileInfo, depth: int, parent_path: str) -> None:
64+
# Only include this node if it's within max_depth
65+
if depth > max_depth:
66+
return
67+
6468
display_path = (
6569
f"{parent_path}{node.path.name}"
6670
if isinstance(node, FileInfo)

src/cedarmapper/render/tree.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ def _render_node(
6262
is_last_stack: list[bool], # stack indicating whether current ancestor is last
6363
parent_display_path: str,
6464
) -> None:
65+
# Only include this node if it's within max_depth
66+
if depth > max_depth:
67+
return
68+
6569
# Build prefix either with numbered indent or with branch characters
6670
if numbered_indent:
6771
prefix = f"{depth:>3} "

tests/test_max_depth_repro.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import tempfile
2+
from pathlib import Path
3+
from cedarmapper.cli.main import run_cli
4+
5+
def test_max_depth_filtering():
6+
"""
7+
Verify strict max-depth filtering behavior.
8+
Structure:
9+
root/
10+
d1.txt (depth 1)
11+
sub1/ (depth 1)
12+
d2.txt (depth 2)
13+
sub2/ (depth 2)
14+
d3.txt (depth 3)
15+
"""
16+
with tempfile.TemporaryDirectory() as tmpdir:
17+
root = Path(tmpdir)
18+
19+
# Create structure
20+
(root / "d1.txt").write_text("depth 1 file")
21+
22+
sub1 = root / "sub1"
23+
sub1.mkdir()
24+
(sub1 / "d2.txt").write_text("depth 2 file")
25+
26+
sub2 = sub1 / "sub2"
27+
sub2.mkdir()
28+
(sub2 / "d3.txt").write_text("depth 3 file")
29+
30+
# Case 0: max-depth 0 (root only) - usually just shows the root itself or immediate children depending on definition
31+
# But commonly max-depth 0 means "just the argument itself".
32+
# However, many tools treat max-depth 1 as "argument + immediate children".
33+
# Let's test standard assumptions:
34+
35+
# Test max-depth 1: Should show d1.txt and sub1/, but NOT d2.txt or sub2
36+
code, out = run_cli([str(root), "--max-depth", "1", "--tree"])
37+
assert code == 0
38+
assert "d1.txt" in out, "depth 1 file should be visible"
39+
assert "sub1/" in out, "depth 1 dir should be visible"
40+
assert "d2.txt" not in out, "depth 2 file should NOT be visible with max-depth 1"
41+
assert "sub2/" not in out, "depth 2 dir should NOT be visible with max-depth 1"
42+
assert "d3.txt" not in out, "depth 3 file should NOT be visible with max-depth 1"
43+
44+
# Test max-depth 2: Should show d2.txt and sub2/, but NOT d3.txt
45+
code, out = run_cli([str(root), "--max-depth", "2", "--tree"])
46+
assert code == 0
47+
assert "d1.txt" in out
48+
assert "d2.txt" in out, "depth 2 file should be visible with max-depth 2"
49+
assert "d3.txt" not in out, "depth 3 file should NOT be visible with max-depth 2"
50+
51+
# Test flat mode as well
52+
code, out = run_cli([str(root), "--max-depth", "1"])
53+
assert code == 0
54+
assert "d1.txt" in out
55+
assert "d2.txt" not in out

0 commit comments

Comments
 (0)