From a2f36572696e0d6a959bfa6494beaa155393d171 Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sat, 13 Dec 2025 21:19:18 +0545 Subject: [PATCH] feat(git): Introduce a robust utility for running git commands This commit introduces a new `run_git_command` utility function within `devgen.utils` to centralize and standardize the execution of Git commands. This improves code reusability and error handling for Git-related operations. * **New Features** * Add `run_git_command` to `devgen/utils.py` to provide a standardized, robust way to execute Git commands, capture output, and handle errors. * Expose `run_git_command` in `__all__` for public use. * **Enhancements & Refinements** * Refactor `get_git_staged_files` to utilize the new `run_git_command` utility, reducing code duplication and improving consistency. --- devgen/utils.py | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/devgen/utils.py b/devgen/utils.py index 2791945..5ebc8a4 100644 --- a/devgen/utils.py +++ b/devgen/utils.py @@ -104,15 +104,52 @@ def configure_logger( return logger -def get_git_staged_files() -> list[str]: +def run_git_command( + args: list[str], + check: bool = True, + cwd: Optional[Path] = None, + encoding: str = "utf-8", + errors: str = "replace", +) -> str: + """ + Executes a git command and returns the output. + + Args: + args: List of command arguments (e.g., ["git", "status"]). + check: Whether to raise an exception on non-zero exit code. + cwd: Current working directory for the command. + encoding: Output encoding. + errors: Error handling strategy for encoding. + + Returns: + The standard output of the command, stripped of leading/trailing whitespace. + + Raises: + subprocess.CalledProcessError: If the command fails and check is True. + """ try: res = subprocess.run( - ["git", "diff", "--name-only", "--cached"], + args, capture_output=True, text=True, - check=True, + encoding=encoding, + errors=errors, + check=check, + cwd=cwd, ) - return [f for f in res.stdout.splitlines() if f.strip()] + return res.stdout.strip() + except subprocess.CalledProcessError as e: + # Log the error if a logger is configured, but re-raise + # We don't have access to a specific logger here easily without passing it in, + # so we rely on the caller to handle logging if needed, or we could log to a default one. + # For now, just re-raise as the caller expects. + raise e + + +def get_git_staged_files() -> list[str]: + try: + output = run_git_command(["git", "diff", "--name-only", "--cached"]) + return [f for f in output.splitlines() if f.strip()] except subprocess.CalledProcessError: return [] @@ -171,6 +208,7 @@ __all__ = [ "sanitize_ai_commit_message", "extract_commit_messages", "configure_logger", + "run_git_command", "get_git_staged_files", "read_file_content", "delete_file",