Skip to content

Commit 6659d28

Browse files
committed
perf: display progress bar ASAP
1 parent 4678224 commit 6659d28

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

src/conjuring/spells/git.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from dataclasses import dataclass
1111
from functools import lru_cache
1212
from pathlib import Path
13+
from typing import TYPE_CHECKING
1314

1415
import typer
1516
from invoke import Context, UnexpectedExit, task
@@ -18,6 +19,9 @@
1819
from slugify import slugify
1920
from tqdm import tqdm
2021

22+
if TYPE_CHECKING:
23+
from collections.abc import Generator
24+
2125
from conjuring.colors import Color
2226
from conjuring.constants import REGEX_JIRA_TICKET_TITLE
2327
from conjuring.grimoire import (
@@ -440,9 +444,17 @@ def new_branch(c: Context, title: str) -> None:
440444
c.run(f"git checkout -b {branch_name}")
441445

442446

443-
def _find_git_repositories(c: Context, search_dirs: list[Path]) -> set[Path]:
444-
"""Find all Git repositories in the given directories using fd."""
445-
git_repos = set()
447+
def _find_git_repositories_streaming(c: Context, search_dirs: list[Path]) -> Generator[Path, None, None]:
448+
"""Find Git repositories and yield them as they're discovered.
449+
450+
This streaming version allows processing to start immediately without waiting
451+
for all repositories to be found first.
452+
453+
Yields:
454+
Path: Repository path as it's discovered
455+
456+
"""
457+
seen_repos = set()
446458
for search_dir in search_dirs:
447459
if not search_dir.exists():
448460
print_warning(f"Directory does not exist: {search_dir}")
@@ -454,13 +466,13 @@ def _find_git_repositories(c: Context, search_dirs: list[Path]) -> set[Path]:
454466
lines = run_lines(c, rf"fd -H -t d --no-ignore-vcs '^\.git$' '{search_dir}'", dry=False)
455467
for line in lines:
456468
repo_path = Path(line).parent
457-
git_repos.add(repo_path)
469+
if repo_path not in seen_repos:
470+
seen_repos.add(repo_path)
471+
yield repo_path
458472
except Exception as e: # noqa: BLE001
459473
print_warning(f"Error searching for Git repos in {search_dir}: {e}")
460474
continue
461475

462-
return git_repos
463-
464476

465477
def is_valid_git_repository(repo_path: Path) -> bool:
466478
"""Check if the given path is a valid Git repository."""
@@ -589,24 +601,25 @@ def dirty(c: Context, dir_: list[str | Path]) -> bool:
589601
# Convert to Path objects and expand user paths
590602
search_dirs = [Path(d).expanduser().resolve() for d in dir_]
591603

592-
# Find all Git repositories using fd
593-
git_repos = _find_git_repositories(c, search_dirs)
594-
595-
if not git_repos:
596-
print_warning("No Git repositories found")
597-
return False
598-
599-
# Check each repository for dirty status and collect data
604+
# Collect repositories as they're found and check them immediately
600605
dirty_repos_data = []
601-
sorted_repos = sorted(git_repos)
602-
with tqdm(total=len(sorted_repos), desc="Checking repositories", unit="repo") as pbar:
603-
for repo_path in sorted_repos:
606+
all_repos = []
607+
608+
# Use streaming approach: process repos as they're discovered
609+
# This makes the progress bar appear immediately
610+
with tqdm(desc="Finding dirty repositories", unit=" repos") as pbar:
611+
for repo_path in _find_git_repositories_streaming(c, search_dirs):
612+
all_repos.append(repo_path)
604613
pbar.set_postfix_str(str(repo_path))
605614
repo_data = _is_repo_dirty(c, repo_path)
606615
if repo_data:
607616
dirty_repos_data.append(repo_data)
608617
pbar.update(1)
609618

619+
if not all_repos:
620+
print_warning("No Git repositories found")
621+
return False
622+
610623
if not dirty_repos_data:
611624
print_warning("No dirty repositories found")
612625
return False

0 commit comments

Comments
 (0)