Coverage for repo_ctx / gitlab_client.py: 0%
36 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-25 17:42 +0100
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-25 17:42 +0100
1"""GitLab API client."""
2import gitlab
3import base64
4from typing import Optional
5import json
8class GitLabClient:
9 def __init__(self, url: str, token: str):
10 self.gl = gitlab.Gitlab(url, private_token=token)
12 def get_project(self, group: str, project: str):
13 """Get project by group/project path."""
14 return self.gl.projects.get(f"{group}/{project}")
16 def get_group(self, group_path: str):
17 """Get group by path."""
18 return self.gl.groups.get(group_path)
20 def list_group_projects(self, group_path: str, include_subgroups: bool = True) -> list[dict]:
21 """List all projects in a group."""
22 group = self.get_group(group_path)
23 projects = group.projects.list(all=True, include_subgroups=include_subgroups)
24 return [{"path": p.path_with_namespace} for p in projects]
26 def get_file_tree(self, project, ref: str = "main") -> list[dict]:
27 """Get repository file tree."""
28 try:
29 return project.repository_tree(ref=ref, recursive=True, all=True)
30 except gitlab.exceptions.GitlabGetError:
31 # Try master if main doesn't exist
32 return project.repository_tree(ref="master", recursive=True, all=True)
34 def read_file(self, project, path: str, ref: str) -> str:
35 """Read file content."""
36 file_data = project.files.get(file_path=path, ref=ref)
37 content = file_data.content
38 if file_data.encoding == 'base64':
39 content = base64.b64decode(content).decode('utf-8')
40 return content
42 def get_tags(self, project) -> list[str]:
43 """Get repository tags."""
44 return [tag.name for tag in project.tags.list(all=True)]
46 def get_default_branch(self, project) -> str:
47 """Get default branch."""
48 return project.default_branch
50 def read_config(self, project, ref: str) -> Optional[dict]:
51 """Read git_context.json if exists."""
52 try:
53 content = self.read_file(project, "git_context.json", ref)
54 return json.loads(content)
55 except:
56 return None