SXXXXXXX_GitUtility/remote_actions.py

165 lines
6.5 KiB
Python

# --- FILE: remote_actions.py ---
import os
import log_handler
from git_commands import GitCommands, GitCommandError
class RemoteActionHandler:
"""
Handles the execution logic for remote Git repository actions.
"""
def __init__(self, git_commands: GitCommands):
"""
Initializes the RemoteActionHandler.
Args:
git_commands (GitCommands): Instance for executing Git commands.
Raises:
TypeError: If git_commands argument is not a GitCommands instance.
"""
if not isinstance(git_commands, GitCommands):
raise TypeError("RemoteActionHandler requires a GitCommands instance.")
self.git_commands = git_commands
log_handler.log_debug("RemoteActionHandler initialized.", func_name="__init__")
def apply_remote_config(self, repo_path: str, remote_name: str, remote_url: str):
"""
Ensures the specified remote configuration exists in the local repository.
Adds the remote if it doesn't exist, or updates the URL if the name exists
but the URL is different.
Args:
repo_path (str): Path to the local repository.
remote_name (str): The desired name for the remote (e.g., 'origin').
remote_url (str): The URL of the remote repository.
Returns:
bool: True if the configuration was applied successfully or already existed,
False otherwise.
Raises:
ValueError: If input arguments are invalid.
GitCommandError: If Git commands fail.
"""
func_name = "apply_remote_config"
log_handler.log_info(
f"Applying remote config in '{repo_path}': Name='{remote_name}', URL='{remote_url}'",
func_name=func_name,
)
# --- Input Validation ---
if not repo_path or not os.path.isdir(repo_path):
raise ValueError(f"Invalid repository path: '{repo_path}'")
if not remote_name or remote_name.isspace():
raise ValueError("Remote name cannot be empty.")
if not remote_url or remote_url.isspace():
# Allow removing remote by setting empty URL? Maybe not here. Assume URL is required.
raise ValueError("Remote URL cannot be empty.")
if not os.path.exists(os.path.join(repo_path, ".git")):
raise ValueError(f"Directory '{repo_path}' is not a Git repository.")
try:
# Check existing remotes
existing_remotes = self.git_commands.get_remotes(
repo_path
) # Need to implement this in GitCommands
if remote_name in existing_remotes:
# Remote name exists, check if URL matches
current_url = existing_remotes[remote_name]
if current_url == remote_url:
log_handler.log_info(
f"Remote '{remote_name}' already configured correctly.",
func_name=func_name,
)
return True # Nothing to do
else:
# URL differs, update it
log_handler.log_info(
f"Updating URL for existing remote '{remote_name}'.",
func_name=func_name,
)
log_handler.log_debug(
f" Old URL: {current_url}", func_name=func_name
)
log_handler.log_debug(
f" New URL: {remote_url}", func_name=func_name
)
success = self.git_commands.set_remote_url(
repo_path, remote_name, remote_url
)
if success:
log_handler.log_info(
f"URL for remote '{remote_name}' updated successfully.",
func_name=func_name,
)
return True
else:
# set_remote_url should raise on error, but check anyway
log_handler.log_error(
f"Failed to update URL for remote '{remote_name}'.",
func_name=func_name,
)
return False
else:
# Remote name does not exist, add it
log_handler.log_info(
f"Adding new remote '{remote_name}' with URL '{remote_url}'.",
func_name=func_name,
)
success = self.git_commands.add_remote(
repo_path, remote_name, remote_url
)
if success:
log_handler.log_info(
f"Remote '{remote_name}' added successfully.",
func_name=func_name,
)
return True
else:
# add_remote should raise on error
log_handler.log_error(
f"Failed to add remote '{remote_name}'.", func_name=func_name
)
return False
except (GitCommandError, ValueError) as e:
log_handler.log_error(
f"Failed to apply remote config for '{remote_name}': {e}",
func_name=func_name,
)
raise # Re-raise the specific error for the caller (worker) to handle
except Exception as e:
log_handler.log_exception(
f"Unexpected error applying remote config for '{remote_name}': {e}",
func_name=func_name,
)
# Wrap unexpected errors in GitCommandError or a custom one if needed
raise GitCommandError(f"Unexpected error: {e}") from e
# --- Placeholder for future remote methods ---
def execute_remote_fetch(self, repo_path: str, remote_name: str):
# To be implemented: Calls git_commands.git_fetch
pass
def execute_remote_pull(self, repo_path: str, remote_name: str, branch_name: str):
# To be implemented: Calls git_commands.git_pull, handles conflicts
pass
def execute_remote_push(self, repo_path: str, remote_name: str, branch_name: str):
# To be implemented: Calls git_commands.git_push, handles upstream/errors
pass
def execute_push_tags(self, repo_path: str, remote_name: str):
# To be implemented: Calls git_commands.git_push_tags
pass
# --- END OF FILE remote_actions.py ---