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.
This commit is contained in:
sankalp committed 2025-12-13 21:19:18 +05:45
1 parent c50f8a4b89
commit a2f3657269
1 file changed
+42 -4
+42 -4
View File
@@ -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",