Coverage for sel_tools/gitlab_api/create_commit.py: 86%
36 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-04 21:22 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-04 21:22 +0000
1"""Create Gitlab commit."""
3import json
4from functools import lru_cache
5from pathlib import Path
7import git
8import gitlab
9from gitlab.v4.objects.projects import Project
10from tqdm import tqdm
12from sel_tools.config import GIT_MAIN_BRANCH, GITLAB_SERVER_URL
13from sel_tools.utils.files import FileTree, FileVisitor
16def commit_changes(repo_paths: list[Path], message: str) -> None:
17 """Commit and push changes to all repos."""
18 for repo_path in tqdm(repo_paths, desc="Committing changes"):
19 repo = git.Repo(repo_path)
20 repo.git.add("--all")
21 repo.git.commit("-am", message)
22 repo.git.push()
25def upload_files(source_folder: Path, student_repos_file: Path, gitlab_token: str) -> None:
26 """Upload new files from source folder via commit to the repository.
28 For doing more than just adding new files refer to `commit_changes`
29 """
30 gitlab_instance = gitlab.Gitlab(GITLAB_SERVER_URL, private_token=gitlab_token)
31 student_repos = json.loads(student_repos_file.read_text())
32 for student_repo in tqdm(student_repos, desc="Uploading files"):
33 student_homework_project = gitlab_instance.projects.get(student_repo["id"])
34 create_commit(source_folder, f"Add {source_folder.name}", student_homework_project)
37def create_commit(source_folder: Path, message: str, gitlab_project: Project) -> None:
38 """Create commit in gitlab project from source folder with message."""
39 gitlab_project.commits.create(create_gitlab_commit_data_with_all_files_from(source_folder, message))
42@lru_cache
43def create_gitlab_commit_data_with_all_files_from(folder: Path, message: str) -> dict:
44 """Create gitlab commit with all files from folder.
46 Folder is assumed to be root of the repo committing to
47 """
48 file_tree = FileTree(folder)
49 initial_file_commit_actions_visitor = InitialFileCommitActionsVisitor(folder)
50 file_tree.accept(initial_file_commit_actions_visitor)
52 return (
53 {
54 "branch": GIT_MAIN_BRANCH,
55 "commit_message": message,
56 "actions": initial_file_commit_actions_visitor.actions,
57 }
58 if initial_file_commit_actions_visitor.actions
59 else {}
60 )
63class InitialFileCommitActionsVisitor(FileVisitor):
64 """Create gitlab commit action for new file."""
66 def __init__(self, root_folder: Path) -> None:
67 self.actions: list[dict] = []
68 self.__root_folder = root_folder
70 def visit_file(self, file: Path) -> None:
71 path_in_new_repo = file.relative_to(self.__root_folder)
72 self.actions.append(
73 {
74 "action": "create",
75 "file_path": str(path_in_new_repo),
76 "content": file.read_text(),
77 }
78 )