Skip to content

Commit 1387f55

Browse files
committed
cli/add_from_fs(feat[UX]): Improve output for many existing repositories
why: When scanning directories with many existing repos (37+), the output was overwhelming and buried the important information about new repos. what: - Show summary only when >5 existing repos instead of full list - Add clear "Found X new repositories to add:" section before confirmation - Display new repos prominently with + prefix before asking to add - Keep detailed output for ≤5 existing repos - Add test for many existing repos scenario This dramatically improves signal-to-noise ratio when adding repos to large existing configurations. refs: User feedback about 37-39 repo output drowning out 2 new additions
1 parent 04a7ff0 commit 1387f55

File tree

2 files changed

+95
-11
lines changed

2 files changed

+95
-11
lines changed

src/vcspull/cli/add_from_fs.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,18 +239,27 @@ def add_from_filesystem(
239239
repos_to_add.append((name, url, key))
240240

241241
if existing_repos:
242-
log.info(
243-
f"{Fore.YELLOW}!{Style.RESET_ALL} Found "
244-
f"{Fore.CYAN}{len(existing_repos)}{Style.RESET_ALL} "
245-
f"existing repositories in configuration:"
246-
)
247-
for name, url, key in existing_repos:
242+
# Show summary only when there are many existing repos
243+
if len(existing_repos) > 5:
244+
log.info(
245+
f"{Fore.YELLOW}!{Style.RESET_ALL} Found "
246+
f"{Fore.CYAN}{len(existing_repos)}{Style.RESET_ALL} "
247+
f"existing repositories already in configuration."
248+
)
249+
else:
250+
# Show details only for small numbers
248251
log.info(
249-
f" {Fore.BLUE}{Style.RESET_ALL} {Fore.CYAN}{name}{Style.RESET_ALL} "
250-
f"({Fore.YELLOW}{url}{Style.RESET_ALL}) at "
251-
f"{Fore.MAGENTA}{key}{name}{Style.RESET_ALL} "
252-
f"in {Fore.BLUE}{config_file_path}{Style.RESET_ALL}"
252+
f"{Fore.YELLOW}!{Style.RESET_ALL} Found "
253+
f"{Fore.CYAN}{len(existing_repos)}{Style.RESET_ALL} "
254+
f"existing repositories in configuration:"
253255
)
256+
for name, url, key in existing_repos:
257+
log.info(
258+
f" {Fore.BLUE}{Style.RESET_ALL} {Fore.CYAN}{name}{Style.RESET_ALL} "
259+
f"({Fore.YELLOW}{url}{Style.RESET_ALL}) at "
260+
f"{Fore.MAGENTA}{key}{name}{Style.RESET_ALL} "
261+
f"in {Fore.BLUE}{config_file_path}{Style.RESET_ALL}"
262+
)
254263

255264
if not repos_to_add:
256265
if existing_repos:
@@ -260,9 +269,20 @@ def add_from_filesystem(
260269
)
261270
return
262271

272+
# Show what will be added
273+
log.info(
274+
f"\n{Fore.GREEN}Found {len(repos_to_add)} new "
275+
f"{'repository' if len(repos_to_add) == 1 else 'repositories'} to add:{Style.RESET_ALL}"
276+
)
277+
for repo_name, repo_url, determined_base_key in repos_to_add:
278+
log.info(
279+
f" {Fore.GREEN}+{Style.RESET_ALL} {Fore.CYAN}{repo_name}{Style.RESET_ALL} "
280+
f"({Fore.YELLOW}{repo_url}{Style.RESET_ALL})"
281+
)
282+
263283
if not yes:
264284
confirm = input(
265-
f"{Fore.CYAN}Add these repositories? [y/N]: {Style.RESET_ALL}"
285+
f"\n{Fore.CYAN}Add these repositories? [y/N]: {Style.RESET_ALL}"
266286
).lower()
267287
if confirm not in {"y", "yes"}:
268288
log.info(f"{Fore.RED}{Style.RESET_ALL} Aborted by user.")

tests/cli/test_add_from_fs.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,3 +582,67 @@ def test_mixed_existing_and_new_repos(
582582
assert f"Adding '{repo_name}' ({remote_url})" in caplog.text
583583

584584
assert "Successfully updated" in caplog.text
585+
586+
def test_many_existing_repos_summary(
587+
self,
588+
create_git_remote_repo: CreateRepoPytestFixtureFn,
589+
tmp_path: pathlib.Path,
590+
git_commit_envvars: dict[str, str],
591+
caplog: LogCaptureFixture,
592+
) -> None:
593+
"""Test that many existing repos show summary instead of full list."""
594+
caplog.set_level("INFO")
595+
596+
# Create scan directory
597+
scan_dir = tmp_path / "many_repos"
598+
scan_dir.mkdir()
599+
600+
# Create many existing repos (more than 5)
601+
existing_repo_data = []
602+
for i in range(8):
603+
repo_name = f"existing{i}"
604+
remote_path = create_git_remote_repo()
605+
remote_url = f"file://{remote_path}"
606+
local_repo_path = scan_dir / repo_name
607+
608+
subprocess.run(
609+
["git", "clone", remote_url, str(local_repo_path)],
610+
check=True,
611+
capture_output=True,
612+
env=git_commit_envvars,
613+
)
614+
existing_repo_data.append((repo_name, remote_url))
615+
616+
# Create one new repo
617+
new_remote = create_git_remote_repo()
618+
new_url = f"file://{new_remote}"
619+
subprocess.run(
620+
["git", "clone", new_url, str(scan_dir / "new_repo")],
621+
check=True,
622+
capture_output=True,
623+
env=git_commit_envvars,
624+
)
625+
626+
# Pre-create config with existing repos
627+
config_file = tmp_path / ".vcspull.yaml"
628+
config_data = {str(scan_dir) + "/": dict(existing_repo_data)}
629+
save_config_yaml(config_file, config_data)
630+
631+
# Run add_from_filesystem
632+
add_from_filesystem(
633+
scan_dir_str=str(scan_dir),
634+
config_file_path_str=str(config_file),
635+
recursive=True,
636+
base_dir_key_arg=None,
637+
yes=True,
638+
)
639+
640+
# Verify summary message for many repos
641+
assert "Found 8 existing repositories already in configuration." in caplog.text
642+
# Should NOT list individual repos
643+
assert "• existing0" not in caplog.text
644+
assert "• existing7" not in caplog.text
645+
646+
# Verify new repo is shown clearly
647+
assert "Found 1 new repository to add:" in caplog.text
648+
assert "+ new_repo" in caplog.text

0 commit comments

Comments
 (0)