Retrieves the content of a file from a GitLab repository (cloud or self-hosted). Args: repo_url (str): The GitLab repo URL (e.g., "https://gitlab.com/username/repo" or "http://localhost/group/project") file_path (str): File path within the repository (e.g., "src/main.py")
(repo_url: str, file_path: str, access_token: str = None)
| 535 | raise ValueError(f"Failed to get file content: {str(e)}") |
| 536 | |
| 537 | def get_gitlab_file_content(repo_url: str, file_path: str, access_token: str = None) -> str: |
| 538 | """ |
| 539 | Retrieves the content of a file from a GitLab repository (cloud or self-hosted). |
| 540 | |
| 541 | Args: |
| 542 | repo_url (str): The GitLab repo URL (e.g., "https://gitlab.com/username/repo" or "http://localhost/group/project") |
| 543 | file_path (str): File path within the repository (e.g., "src/main.py") |
| 544 | access_token (str, optional): GitLab personal access token |
| 545 | |
| 546 | Returns: |
| 547 | str: File content |
| 548 | |
| 549 | Raises: |
| 550 | ValueError: If anything fails |
| 551 | """ |
| 552 | try: |
| 553 | # Parse and validate the URL |
| 554 | parsed_url = urlparse(repo_url) |
| 555 | if not parsed_url.scheme or not parsed_url.netloc: |
| 556 | raise ValueError("Not a valid GitLab repository URL") |
| 557 | |
| 558 | gitlab_domain = f"{parsed_url.scheme}://{parsed_url.netloc}" |
| 559 | if parsed_url.port not in (None, 80, 443): |
| 560 | gitlab_domain += f":{parsed_url.port}" |
| 561 | path_parts = parsed_url.path.strip("/").split("/") |
| 562 | if len(path_parts) < 2: |
| 563 | raise ValueError("Invalid GitLab URL format — expected something like https://gitlab.domain.com/group/project") |
| 564 | |
| 565 | # Build project path and encode for API |
| 566 | project_path = "/".join(path_parts).replace(".git", "") |
| 567 | encoded_project_path = quote(project_path, safe='') |
| 568 | |
| 569 | # Encode file path |
| 570 | encoded_file_path = quote(file_path, safe='') |
| 571 | |
| 572 | # Try to get the default branch from the project info |
| 573 | default_branch = None |
| 574 | try: |
| 575 | project_info_url = f"{gitlab_domain}/api/v4/projects/{encoded_project_path}" |
| 576 | project_headers = {} |
| 577 | if access_token: |
| 578 | project_headers["PRIVATE-TOKEN"] = access_token |
| 579 | |
| 580 | project_response = requests.get(project_info_url, headers=project_headers) |
| 581 | if project_response.status_code == 200: |
| 582 | project_data = project_response.json() |
| 583 | default_branch = project_data.get('default_branch', 'main') |
| 584 | logger.info(f"Found default branch: {default_branch}") |
| 585 | else: |
| 586 | logger.warning(f"Could not fetch project info, using 'main' as default branch") |
| 587 | default_branch = 'main' |
| 588 | except Exception as e: |
| 589 | logger.warning(f"Error fetching project info: {e}, using 'main' as default branch") |
| 590 | default_branch = 'main' |
| 591 | |
| 592 | api_url = f"{gitlab_domain}/api/v4/projects/{encoded_project_path}/repository/files/{encoded_file_path}/raw?ref={default_branch}" |
| 593 | # Fetch file content from GitLab API |
| 594 | headers = {} |