Download code from a Git repository and extract to the specified path
(url: str, target_path: Path, proxy: str | None = None)
| 50 | |
| 51 | |
| 52 | def get_git_repo(url: str, target_path: Path, proxy: str | None = None) -> None: |
| 53 | """Download code from a Git repository and extract to the specified path""" |
| 54 | temp_dir = Path(tempfile.mkdtemp()) |
| 55 | try: |
| 56 | # Parse repository info |
| 57 | repo_namespace = url.split("/")[-2:] |
| 58 | author = repo_namespace[0] |
| 59 | repo = repo_namespace[1] |
| 60 | |
| 61 | # Try to get the latest release |
| 62 | release_url = f"https://api.github.com/repos/{author}/{repo}/releases" |
| 63 | try: |
| 64 | with httpx.Client( |
| 65 | proxy=proxy if proxy else None, |
| 66 | follow_redirects=True, |
| 67 | ) as client: |
| 68 | resp = client.get(release_url) |
| 69 | resp.raise_for_status() |
| 70 | releases = resp.json() |
| 71 | |
| 72 | if releases: |
| 73 | # Use the latest release |
| 74 | download_url = releases[0]["zipball_url"] |
| 75 | else: |
| 76 | # No release found, use default branch |
| 77 | click.echo(f"Downloading {author}/{repo} from default branch") |
| 78 | download_url = f"https://github.com/{author}/{repo}/archive/refs/heads/master.zip" |
| 79 | except Exception as e: |
| 80 | click.echo(f"Failed to get release info: {e}. Using provided URL directly") |
| 81 | download_url = url |
| 82 | |
| 83 | # Apply proxy |
| 84 | if proxy: |
| 85 | download_url = f"{proxy}/{download_url}" |
| 86 | |
| 87 | # Download and extract |
| 88 | with httpx.Client( |
| 89 | proxy=proxy if proxy else None, |
| 90 | follow_redirects=True, |
| 91 | ) as client: |
| 92 | resp = client.get(download_url) |
| 93 | if ( |
| 94 | resp.status_code == 404 |
| 95 | and "archive/refs/heads/master.zip" in download_url |
| 96 | ): |
| 97 | alt_url = download_url.replace("master.zip", "main.zip") |
| 98 | click.echo("Branch 'master' not found, trying 'main' branch") |
| 99 | resp = client.get(alt_url) |
| 100 | resp.raise_for_status() |
| 101 | else: |
| 102 | resp.raise_for_status() |
| 103 | zip_content = BytesIO(resp.content) |
| 104 | with ZipFile(zip_content) as z: |
| 105 | z.extractall(temp_dir) |
| 106 | namelist = z.namelist() |
| 107 | root_dir = Path(namelist[0]).parts[0] if namelist else "" |
| 108 | if target_path.exists(): |
| 109 | shutil.rmtree(target_path) |
no test coverage detected