165 lines
6.5 KiB
Python
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 ---
|