Coverage for src / rhiza / commands / tree.py: 100%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-02 07:04 +0000

1# This file is part of the jebel-quant/rhiza repository 

2# (https://github.com/jebel-quant/rhiza). 

3# 

4"""Command for listing files managed by Rhiza in tree style. 

5 

6This module provides functionality to read .rhiza/template.lock and display 

7the managed files in a tree-style view. 

8""" 

9 

10from pathlib import Path 

11 

12from loguru import logger 

13from rich.console import Console 

14from rich.tree import Tree 

15 

16from rhiza.commands._sync_helpers import _load_lock_or_warn 

17 

18 

19def _build_rich_tree(paths: list[str]) -> Tree: 

20 """Build a Rich Tree from a list of file paths. 

21 

22 Args: 

23 paths: List of file path strings. 

24 

25 Returns: 

26 A Rich Tree rooted at ".". 

27 """ 

28 rich_tree = Tree(".") 

29 node_cache: dict = {} 

30 for path in sorted(paths): 

31 parts = Path(path).parts 

32 parent: Tree = rich_tree 

33 current_path: tuple = () 

34 for part in parts: 

35 key = (*current_path, part) 

36 if key not in node_cache: 

37 node_cache[key] = parent.add(part) 

38 parent = node_cache[key] 

39 current_path = key 

40 return rich_tree 

41 

42 

43def tree(target: Path) -> None: 

44 """Display files managed by Rhiza in a tree-style view. 

45 

46 Reads .rhiza/template.lock and prints the list of managed files as a 

47 directory tree, similar to the Unix ``tree`` command. 

48 

49 Args: 

50 target: Path to the target repository root. 

51 """ 

52 lock = _load_lock_or_warn(target) 

53 if lock is None: 

54 return 

55 

56 if not lock.files: 

57 logger.info("No files are tracked in template.lock") 

58 return 

59 

60 rich_tree = _build_rich_tree(lock.files) 

61 console = Console() 

62 console.print(rich_tree) 

63 

64 file_count = len(lock.files) 

65 console.print(f"\n{file_count} file{'s' if file_count != 1 else ''} managed by Rhiza")