Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b213bf8
config(feat): Add save_config_yaml utility function
tony Sep 3, 2025
117450f
cli/add(feat): Implement 'vcspull add' command
tony Sep 3, 2025
56bc705
cli/add-from-fs(feat): Implement filesystem scanner for bulk repo add…
tony Sep 3, 2025
eb3df60
cli/sync(fix): Make config parameter optional in sync function
tony Sep 3, 2025
ca2e493
log(feat): Add SimpleLogFormatter for clean CLI output
tony Sep 3, 2025
894fb55
tests/cli/add(feat): Add comprehensive tests for add command
tony Sep 3, 2025
d5b78cd
tests/cli/add-from-fs(feat): Add comprehensive tests for filesystem s…
tony Sep 3, 2025
48aa803
tests/log(feat): Add comprehensive tests for logging utilities
tony Sep 3, 2025
c9adc9a
tests/cli(fix): Include stderr in output capture for CLI tests
tony Sep 3, 2025
4970243
tests/cli/add(refactor): Rewrite tests following vcspull conventions
tony Sep 3, 2025
400faf1
tests/cli/add-from-fs(refactor): Rewrite tests following vcspull conv…
tony Sep 3, 2025
4a86b20
cli/add(fix[error-handling]): Use early return instead of raise in ex…
tony Sep 3, 2025
4063518
cli/add_from_fs(fix[error-handling]): Use early return instead of rai…
tony Sep 3, 2025
a30b0ba
style(cli): Fix ruff warnings and improve code quality
tony Sep 3, 2025
8e27365
test(cli): Fix docstring style in test_add_from_fs
tony Sep 3, 2025
ac29c30
cli/fmt(feat): Add fmt command for formatting configuration files
tony Sep 3, 2025
874b86c
cli/__init__(feat[create_parser]): Add fmt subparser to CLI
tony Sep 3, 2025
ee9be13
tests/cli/test_fmt(test): Add comprehensive tests for fmt command
tony Sep 3, 2025
f30acf3
cli/__init__(fix[fmt]): Fix mypy type error in format_config_file call
tony Sep 3, 2025
a06b007
cli/__init__(refactor[cli]): Remove unnecessary hasattr checks and si…
tony Sep 3, 2025
8aad0b6
style(cli/fmt): Apply formatting fixes
tony Sep 3, 2025
f698733
test(cli): Fix conflicting logging fixtures between test files
tony Sep 3, 2025
a19d689
log.py(fix[setup_logger]): Add vcspull.cli.fmt to CLI loggers list
tony Sep 3, 2025
a5b9686
test_fmt(fix[reset_logging]): Fix logging fixture to prevent test int…
tony Sep 3, 2025
56025f9
cli/fmt(feat[--all]): Add --all flag to format all discovered configs
tony Sep 3, 2025
0e3b93e
style: Apply ruff linting and formatting fixes
tony Sep 3, 2025
095d919
cli/fmt.py(style): Fix ruff linting issues
tony Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
style(cli): Fix ruff warnings and improve code quality
why: Address ruff linting warnings to improve code quality and consistency
what:
- Move traceback imports to module level instead of conditional imports
- Convert f-string logging to % formatting for better performance
- Fix line length issues to meet 88 character limit
- Maintain all functionality while improving code style

All tests passing after changes.
  • Loading branch information
tony committed Sep 13, 2025
commit a30b0ba13b79829fec4750c5aee802f12cb2012f
28 changes: 18 additions & 10 deletions src/vcspull/cli/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging
import pathlib
import traceback
import typing as t

import yaml
Expand Down Expand Up @@ -105,8 +106,6 @@ def add_repo(
except Exception:
log.exception("Error loading YAML from %s. Aborting.", config_file_path)
if log.isEnabledFor(logging.DEBUG):
import traceback

traceback.print_exc()
return
else:
Expand Down Expand Up @@ -157,7 +156,8 @@ def add_repo(
current_url = str(existing_config)

log.warning(
"Repository '%s' already exists under '%s'. Current URL: %s. To update, remove and re-add, or edit the YAML file manually.",
"Repository '%s' already exists under '%s'. Current URL: %s. "
"To update, remove and re-add, or edit the YAML file manually.",
name,
base_dir_key,
current_url,
Expand All @@ -171,16 +171,24 @@ def add_repo(
try:
save_config_yaml(config_file_path, raw_config)
log.info(
f"{Fore.GREEN}✓{Style.RESET_ALL} Successfully added "
f"{Fore.CYAN}'{name}'{Style.RESET_ALL} "
f"({Fore.YELLOW}{url}{Style.RESET_ALL}) to "
f"{Fore.BLUE}{config_file_path}{Style.RESET_ALL} under "
f"'{Fore.MAGENTA}{base_dir_key}{Style.RESET_ALL}'.",
"%s✓%s Successfully added %s'%s'%s (%s%s%s) to %s%s%s under '%s%s%s'.",
Fore.GREEN,
Style.RESET_ALL,
Fore.CYAN,
name,
Style.RESET_ALL,
Fore.YELLOW,
url,
Style.RESET_ALL,
Fore.BLUE,
config_file_path,
Style.RESET_ALL,
Fore.MAGENTA,
base_dir_key,
Style.RESET_ALL,
)
except Exception:
log.exception("Error saving config to %s", config_file_path)
if log.isEnabledFor(logging.DEBUG):
import traceback

traceback.print_exc()
return
134 changes: 94 additions & 40 deletions src/vcspull/cli/add_from_fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os
import pathlib
import subprocess
import traceback
import typing as t

import yaml
Expand Down Expand Up @@ -114,9 +115,13 @@ def add_from_filesystem(
if not home_configs:
config_file_path = pathlib.Path.cwd() / ".vcspull.yaml"
log.info(
f"{Fore.CYAN}i{Style.RESET_ALL} No config specified and no default "
f"home config, will use/create "
f"{Fore.BLUE}{config_file_path}{Style.RESET_ALL}",
"%si%s No config specified and no default "
"home config, will use/create %s%s%s",
Fore.CYAN,
Style.RESET_ALL,
Fore.BLUE,
config_file_path,
Style.RESET_ALL,
)
elif len(home_configs) > 1:
log.error(
Expand All @@ -140,15 +145,16 @@ def add_from_filesystem(
except Exception:
log.exception("Error loading YAML from %s. Aborting.", config_file_path)
if log.isEnabledFor(logging.DEBUG):
import traceback

traceback.print_exc()
return
else:
log.info(
f"{Fore.CYAN}i{Style.RESET_ALL} Config file "
f"{Fore.BLUE}{config_file_path}{Style.RESET_ALL} "
f"not found. A new one will be created.",
"%si%s Config file %s%s%s not found. A new one will be created.",
Fore.CYAN,
Style.RESET_ALL,
Fore.BLUE,
config_file_path,
Style.RESET_ALL,
)

found_repos: list[
Expand All @@ -164,7 +170,8 @@ def add_from_filesystem(

if not repo_url:
log.warning(
"Could not determine remote URL for git repository at %s. Skipping.",
"Could not determine remote URL for git repository "
"at %s. Skipping.",
repo_path,
)
continue
Expand Down Expand Up @@ -197,7 +204,8 @@ def add_from_filesystem(

if not repo_url:
log.warning(
"Could not determine remote URL for git repository at %s. Skipping.",
"Could not determine remote URL for git repository "
"at %s. Skipping.",
item,
)
continue
Expand All @@ -223,8 +231,12 @@ def add_from_filesystem(

if not found_repos:
log.info(
f"{Fore.YELLOW}!{Style.RESET_ALL} No git repositories found in "
f"{Fore.BLUE}{scan_dir}{Style.RESET_ALL}. Nothing to add.",
"%s!%s No git repositories found in %s%s%s. Nothing to add.",
Fore.YELLOW,
Style.RESET_ALL,
Fore.BLUE,
scan_dir,
Style.RESET_ALL,
)
return

Expand All @@ -242,52 +254,82 @@ def add_from_filesystem(
# Show summary only when there are many existing repos
if len(existing_repos) > 5:
log.info(
f"{Fore.YELLOW}!{Style.RESET_ALL} Found "
f"{Fore.CYAN}{len(existing_repos)}{Style.RESET_ALL} "
f"existing repositories already in configuration.",
"%s!%s Found %s%d%s existing repositories already in configuration.",
Fore.YELLOW,
Style.RESET_ALL,
Fore.CYAN,
len(existing_repos),
Style.RESET_ALL,
)
else:
# Show details only for small numbers
log.info(
f"{Fore.YELLOW}!{Style.RESET_ALL} Found "
f"{Fore.CYAN}{len(existing_repos)}{Style.RESET_ALL} "
f"existing repositories in configuration:",
"%s!%s Found %s%d%s existing repositories in configuration:",
Fore.YELLOW,
Style.RESET_ALL,
Fore.CYAN,
len(existing_repos),
Style.RESET_ALL,
)
for name, url, key in existing_repos:
log.info(
f" {Fore.BLUE}•{Style.RESET_ALL} "
f"{Fore.CYAN}{name}{Style.RESET_ALL} "
f"({Fore.YELLOW}{url}{Style.RESET_ALL}) at "
f"{Fore.MAGENTA}{key}{name}{Style.RESET_ALL} "
f"in {Fore.BLUE}{config_file_path}{Style.RESET_ALL}",
" %s•%s %s%s%s (%s%s%s) at %s%s%s%s in %s%s%s",
Fore.BLUE,
Style.RESET_ALL,
Fore.CYAN,
name,
Style.RESET_ALL,
Fore.YELLOW,
url,
Style.RESET_ALL,
Fore.MAGENTA,
key,
name,
Style.RESET_ALL,
Fore.BLUE,
config_file_path,
Style.RESET_ALL,
)

if not repos_to_add:
if existing_repos:
log.info(
f"{Fore.GREEN}✓{Style.RESET_ALL} All found repositories already exist "
f"in the configuration. {Fore.GREEN}Nothing to do.{Style.RESET_ALL}",
"%s✓%s All found repositories already exist in the configuration. "
"%sNothing to do.%s",
Fore.GREEN,
Style.RESET_ALL,
Fore.GREEN,
Style.RESET_ALL,
)
return

# Show what will be added
log.info(
f"\n{Fore.GREEN}Found {len(repos_to_add)} new "
f"{'repository' if len(repos_to_add) == 1 else 'repositories'} "
f"to add:{Style.RESET_ALL}",
"\n%sFound %d new %s to add:%s",
Fore.GREEN,
len(repos_to_add),
"repository" if len(repos_to_add) == 1 else "repositories",
Style.RESET_ALL,
)
for repo_name, repo_url, _determined_base_key in repos_to_add:
log.info(
f" {Fore.GREEN}+{Style.RESET_ALL} {Fore.CYAN}{repo_name}{Style.RESET_ALL} "
f"({Fore.YELLOW}{repo_url}{Style.RESET_ALL})",
" %s+%s %s%s%s (%s%s%s)",
Fore.GREEN,
Style.RESET_ALL,
Fore.CYAN,
repo_name,
Style.RESET_ALL,
Fore.YELLOW,
repo_url,
Style.RESET_ALL,
)

if not yes:
confirm = input(
f"\n{Fore.CYAN}Add these repositories? [y/N]: {Style.RESET_ALL}",
).lower()
if confirm not in {"y", "yes"}:
log.info(f"{Fore.RED}✗{Style.RESET_ALL} Aborted by user.")
log.info("%s✗%s Aborted by user.", Fore.RED, Style.RESET_ALL)
return

changes_made = False
Expand All @@ -305,28 +347,40 @@ def add_from_filesystem(
if repo_name not in raw_config[determined_base_key]:
raw_config[determined_base_key][repo_name] = {"repo": repo_url}
log.info(
f"{Fore.GREEN}+{Style.RESET_ALL} Adding "
f"{Fore.CYAN}'{repo_name}'{Style.RESET_ALL} "
f"({Fore.YELLOW}{repo_url}{Style.RESET_ALL}) under "
f"'{Fore.MAGENTA}{determined_base_key}{Style.RESET_ALL}'.",
"%s+%s Adding %s'%s'%s (%s%s%s) under '%s%s%s'.",
Fore.GREEN,
Style.RESET_ALL,
Fore.CYAN,
repo_name,
Style.RESET_ALL,
Fore.YELLOW,
repo_url,
Style.RESET_ALL,
Fore.MAGENTA,
determined_base_key,
Style.RESET_ALL,
)
changes_made = True

if changes_made:
try:
save_config_yaml(config_file_path, raw_config)
log.info(
f"{Fore.GREEN}✓{Style.RESET_ALL} Successfully updated "
f"{Fore.BLUE}{config_file_path}{Style.RESET_ALL}.",
"%s✓%s Successfully updated %s%s%s.",
Fore.GREEN,
Style.RESET_ALL,
Fore.BLUE,
config_file_path,
Style.RESET_ALL,
)
except Exception:
log.exception("Error saving config to %s", config_file_path)
if log.isEnabledFor(logging.DEBUG):
import traceback

traceback.print_exc()
return
else:
log.info(
f"{Fore.GREEN}✓{Style.RESET_ALL} No changes made to the configuration.",
"%s✓%s No changes made to the configuration.",
Fore.GREEN,
Style.RESET_ALL,
)