Clone a Git repository to a temporary directory.
(self, url: str)
| 191 | return host |
| 192 | |
| 193 | def _clone_git(self, url: str) -> Path: |
| 194 | """Clone a Git repository to a temporary directory.""" |
| 195 | self._validate_url_host(url, ALLOWED_GIT_HOSTS) |
| 196 | temp_dir = self._get_temp_dir() |
| 197 | clone_dir = temp_dir / "repo" |
| 198 | try: |
| 199 | subprocess.run( |
| 200 | ["git", "clone", "--depth", "1", url, str(clone_dir)], |
| 201 | check=True, |
| 202 | capture_output=True, |
| 203 | timeout=60, |
| 204 | shell=False, |
| 205 | ) |
| 206 | except subprocess.CalledProcessError as e: |
| 207 | logger.warning("Git clone failed for %s: %s", url, e) |
| 208 | raise ValueError(f"Failed to clone repository: {e.stderr.decode()}") from e |
| 209 | except subprocess.TimeoutExpired: |
| 210 | logger.warning("Git clone timed out for %s", url) |
| 211 | raise ValueError("Git clone timed out after 60 seconds") from None |
| 212 | except FileNotFoundError: |
| 213 | logger.warning("Git not found when cloning %s", url) |
| 214 | raise ValueError( |
| 215 | "Git is not installed. Please install git to scan repositories." |
| 216 | ) from None |
| 217 | return clone_dir |
| 218 | |
| 219 | def _download_file(self, url: str) -> Path: |
| 220 | """Download a file from URL to a temporary directory.""" |