Skip to content

Commit 70af03b

Browse files
aclark4lifeCopilot
andcommitted
Use tree-style output for flat-mode dbx list
Repos are now grouped under their config group headers in a tree, matching the visual style of the non-flat layout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c2557bd commit 70af03b

1 file changed

Lines changed: 40 additions & 26 deletions

File tree

src/dbx_python_cli/utils/repo.py

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -748,19 +748,11 @@ def list_repos(base_dir, format_style="default", config=None):
748748
if not repos and not available_repos:
749749
return None
750750

751-
# Flat mode: render a plain list (no group-subdir tree)
751+
# Flat mode: render a tree grouped by config group
752752
if config and is_flat_mode(config):
753-
# Collect all repo names: cloned + available from config
754753
cloned_names = {r["name"] for r in repos}
755-
all_available_names = set()
756-
for names in available_repos.values():
757-
all_available_names.update(names)
758-
all_names = sorted(cloned_names | all_available_names)
759754

760-
if not all_names:
761-
return None
762-
763-
# Build repo → [group, ...] mapping from config (non-global groups only)
755+
# Build repo → groups mapping from config (non-global groups only)
764756
repo_to_groups = defaultdict(list)
765757
for gname, gconfig in groups.items():
766758
if gname in global_group_names:
@@ -769,27 +761,49 @@ def list_repos(base_dir, format_style="default", config=None):
769761
rname = extract_repo_name_from_url(url)
770762
repo_to_groups[rname].append(gname)
771763

764+
# Cloned repos that belong to no config group are rendered ungrouped at the end
765+
ungrouped_cloned = sorted(r for r in cloned_names if not repo_to_groups.get(r))
766+
767+
all_groups = set(available_repos.keys()) - global_group_names
768+
if not all_groups and not ungrouped_cloned:
769+
return None
770+
772771
lines = []
773-
for i, repo_name in enumerate(all_names):
774-
is_last = i == len(all_names) - 1
775-
prefix = "└──" if is_last else "├──"
776-
group_list = repo_to_groups.get(repo_name, [])
777-
group_label = (
778-
" " + typer.style(f"[{', '.join(group_list)}]", fg=typer.colors.CYAN)
779-
if group_list
780-
else ""
781-
)
782-
if config:
783-
if repo_name in cloned_names and repo_name in all_available_names:
772+
sorted_groups = sorted(all_groups)
773+
total_sections = len(sorted_groups) + (1 if ungrouped_cloned else 0)
774+
for i, group in enumerate(sorted_groups):
775+
is_last_group = i == total_sections - 1
776+
group_prefix = "└──" if is_last_group else "├──"
777+
group_label = typer.style(f"{group}/", fg=typer.colors.CYAN, bold=True)
778+
lines.append(f"{group_prefix} {group_label}")
779+
780+
available_in_group = set(available_repos.get(group, []))
781+
cloned_in_group = {
782+
r for r in cloned_names if group in repo_to_groups.get(r, [])
783+
}
784+
all_repos_in_group = sorted(available_in_group | cloned_in_group)
785+
786+
for j, repo_name in enumerate(all_repos_in_group):
787+
is_last_repo = j == len(all_repos_in_group) - 1
788+
continuation = " " if is_last_group else "│ "
789+
repo_prefix = "└──" if is_last_repo else "├──"
790+
is_cloned = repo_name in cloned_names
791+
is_available = repo_name in available_in_group
792+
if is_cloned and is_available:
784793
status = typer.style("✓", fg=typer.colors.GREEN)
785-
elif repo_name in cloned_names:
794+
elif is_cloned:
786795
status = typer.style("?", fg=typer.colors.MAGENTA)
787796
else:
788797
status = typer.style("○", fg=typer.colors.YELLOW)
789-
lines.append(f"{prefix} {status} {repo_name}{group_label}")
790-
else:
791-
lines.append(f"{prefix} {repo_name}{group_label}")
792-
return "\n".join(lines)
798+
lines.append(f"{continuation}{repo_prefix} {status} {repo_name}")
799+
800+
for k, repo_name in enumerate(ungrouped_cloned):
801+
is_last = k == len(ungrouped_cloned) - 1
802+
prefix = "└──" if is_last else "├──"
803+
status = typer.style("?", fg=typer.colors.MAGENTA)
804+
lines.append(f"{prefix} {status} {repo_name}")
805+
806+
return "\n".join(lines) if lines else None
793807

794808
if format_style == "tree":
795809
# Tree format with group as parent

0 commit comments

Comments
 (0)