Clone a repository to a local path based on the provided configuration. This function handles the process of cloning a Git repository to the local file system. It can clone a specific branch, tag, or commit if provided, and it raises exceptions if any errors occur during the cloning pro
(config: CloneConfig, *, token: str | None = None)
| 29 | |
| 30 | @async_timeout(DEFAULT_TIMEOUT) |
| 31 | async def clone_repo(config: CloneConfig, *, token: str | None = None) -> None: |
| 32 | """Clone a repository to a local path based on the provided configuration. |
| 33 | |
| 34 | This function handles the process of cloning a Git repository to the local file system. |
| 35 | It can clone a specific branch, tag, or commit if provided, and it raises exceptions if |
| 36 | any errors occur during the cloning process. |
| 37 | |
| 38 | Parameters |
| 39 | ---------- |
| 40 | config : CloneConfig |
| 41 | The configuration for cloning the repository. |
| 42 | token : str | None |
| 43 | GitHub personal access token (PAT) for accessing private repositories. |
| 44 | |
| 45 | Raises |
| 46 | ------ |
| 47 | ValueError |
| 48 | If the repository is not found, if the provided URL is invalid, or if the token format is invalid. |
| 49 | |
| 50 | """ |
| 51 | # Extract and validate query parameters |
| 52 | url: str = config.url |
| 53 | local_path: str = config.local_path |
| 54 | partial_clone: bool = config.subpath != "/" |
| 55 | |
| 56 | logger.info( |
| 57 | "Starting git clone operation", |
| 58 | extra={ |
| 59 | "url": url, |
| 60 | "local_path": local_path, |
| 61 | "partial_clone": partial_clone, |
| 62 | "subpath": config.subpath, |
| 63 | "branch": config.branch, |
| 64 | "tag": config.tag, |
| 65 | "commit": config.commit, |
| 66 | "include_submodules": config.include_submodules, |
| 67 | }, |
| 68 | ) |
| 69 | |
| 70 | logger.debug("Ensuring git is installed") |
| 71 | await ensure_git_installed() |
| 72 | |
| 73 | logger.debug("Creating local directory", extra={"parent_path": str(Path(local_path).parent)}) |
| 74 | await ensure_directory_exists_or_create(Path(local_path).parent) |
| 75 | |
| 76 | logger.debug("Checking if repository exists", extra={"url": url}) |
| 77 | if not await check_repo_exists(url, token=token): |
| 78 | logger.error("Repository not found", extra={"url": url}) |
| 79 | msg = "Repository not found. Make sure it is public or that you have provided a valid token." |
| 80 | raise ValueError(msg) |
| 81 | |
| 82 | logger.debug("Resolving commit reference") |
| 83 | commit = await resolve_commit(config, token=token) |
| 84 | logger.debug("Resolved commit", extra={"commit": commit}) |
| 85 | |
| 86 | clone_cmd = ["git"] |
| 87 | if token and is_github_host(url): |
| 88 | clone_cmd += ["-c", create_git_auth_header(token, url=url)] |