From df706f9ae85d6b00197c9088381aa01d42b1e153 Mon Sep 17 00:00:00 2001 From: "r.jaepel" Date: Tue, 11 Feb 2025 14:07:26 +0100 Subject: [PATCH] Add fallback to pull that also tries the HTTP URL --- cadetrdm/initialize_repo.py | 4 +--- cadetrdm/repositories.py | 27 +++++++++++++++++++++------ tests/test_git_adapter.py | 3 +++ tests/test_gitlab_api.py | 9 +++++---- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/cadetrdm/initialize_repo.py b/cadetrdm/initialize_repo.py index 9974477..a3fe07e 100644 --- a/cadetrdm/initialize_repo.py +++ b/cadetrdm/initialize_repo.py @@ -242,10 +242,8 @@ def clone(project_url, path_to_repo: str = None, multi_options: List[str] = None path_to_repo = project_url.split("/")[-1] path_to_repo = path_to_repo.replace(".git", "") print(f"Cloning {project_url} into {path_to_repo}") - git.Repo.clone_from(project_url, path_to_repo, multi_options=multi_options) - # During class instantiation, the output repo is cloned. - repo = ProjectRepo(path_to_repo) + repo = ProjectRepo.clone_from(to_path=path_to_repo, url=project_url, multi_options=multi_options) repo.fill_data_from_cadet_rdm_json() diff --git a/cadetrdm/repositories.py b/cadetrdm/repositories.py index 8532a95..3296392 100644 --- a/cadetrdm/repositories.py +++ b/cadetrdm/repositories.py @@ -10,7 +10,7 @@ from datetime import datetime from pathlib import Path from stat import S_IREAD, S_IWRITE -from typing import List +from typing import List, Optional from urllib.request import urlretrieve import cadetrdm @@ -34,7 +34,6 @@ def validate_is_output_repo(path_to_repo): if rdm_data["is_project_repo"]: raise ValueError("Please use the URL to the output repository.") - class BaseRepo: def __init__(self, repository_path=None, search_parent_directories=True, *args, **kwargs): """ @@ -185,6 +184,21 @@ def update(self): traceback.print_exc() print(f"Git command error in {self.path}: {e}") + @classmethod + def clone_from(cls, url, to_path, multi_options: Optional[List[str]] = None, **kwargs): + try: + git.Repo.clone_from(url, to_path, multi_options=multi_options, **kwargs) + except git.exc.GitCommandError as e: + if "Permission denied (publickey)" in e: + try: + git.Repo.clone_from(ssh_url_to_http_url(url), to_path, multi_options=multi_options, **kwargs) + except Exception as e_inner: + raise e_inner + else: + raise e + instance = cls(to_path) + return instance + def add_remote(self, remote_url, remote_name=None): """ Add a remote to the repository. @@ -261,9 +275,10 @@ def import_remote_repo(self, source_repo_location, source_repo_branch, target_re print(f"Cloning from {source_repo_location} into {target_repo_location}") multi_options = ["--filter=blob:none", "--branch", source_repo_branch, "--single-branch"] - repo = git.Repo.clone_from(source_repo_location, target_repo_location, multi_options=multi_options) - repo.git.clear_cache() - repo.close() + repo = self.clone_from(url=source_repo_location, to_path=target_repo_location, + multi_options=multi_options) + repo._git.clear_cache() + repo._git_repo.close() self.update_cadet_rdm_cache_json(source_repo_branch=source_repo_branch, target_repo_location=target_repo_location, @@ -750,7 +765,7 @@ def _clone_output_repo(self, multi_options: List[str] = None): for output_remote in ssh_remotes + http_remotes: try: print(f"Attempting to clone {output_remote} into {output_path}") - git.Repo.clone_from(output_remote, output_path, multi_options=multi_options) + _ = self.clone_from(output_remote, output_path, multi_options=multi_options) except Exception as e: print(e) else: diff --git a/tests/test_git_adapter.py b/tests/test_git_adapter.py index 54c502d..1289f71 100644 --- a/tests/test_git_adapter.py +++ b/tests/test_git_adapter.py @@ -159,6 +159,9 @@ def try_initialize_from_remote(): "test_repo_from_remote") assert try_init_gitpython_repo("test_repo_from_remote") + repo = ProjectRepo("test_repo_from_remote") + assert hasattr(repo, "") + def test_init_over_existing_repo(monkeypatch): path_to_repo = Path("test_repo_2") diff --git a/tests/test_gitlab_api.py b/tests/test_gitlab_api.py index 1a8cdd5..1707dce 100644 --- a/tests/test_gitlab_api.py +++ b/tests/test_gitlab_api.py @@ -6,6 +6,7 @@ from cadetrdm import initialize_repo, ProjectRepo from cadetrdm.io_utils import delete_path from cadetrdm.remote_integration import GitHubRemote, GitLabRemote +from cadetrdm.repositories import BaseRepo @pytest.mark.server_api @@ -26,7 +27,7 @@ def test_gitlab_create(): response = remote.create_remote(url=url, namespace=namespace, name=name, username="r.jaepel") - git.Repo.clone_from(response.ssh_url_to_repo, "test_repo_remote") + BaseRepo.clone_from(response.ssh_url_to_repo, "test_repo_remote") delete_path("test_repo_remote") remote.delete_remote(url=url, namespace=namespace, name=name, username="r.jaepel") @@ -34,7 +35,7 @@ def test_gitlab_create(): sleep(3) with pytest.raises(git.exc.GitCommandError): - git.Repo.clone_from(response.ssh_url_to_repo, "test_repo_remote") + BaseRepo.clone_from(response.ssh_url_to_repo, "test_repo_remote") @pytest.mark.server_api @@ -60,13 +61,13 @@ def test_github_create(): sleep(3) - git.Repo.clone_from(response.html_url, "test_repo_remote") + BaseRepo.clone_from(response.html_url, "test_repo_remote") delete_path("test_repo_remote") remote.delete_remote(namespace=namespace, name=name, username="r.jaepel") with pytest.raises(git.exc.GitCommandError): - git.Repo.clone_from(response.ssh_url, "test_repo_remote") + BaseRepo.clone_from(response.ssh_url, "test_repo_remote") @pytest.mark.server_api