Coverage for tools / sel_tools / gitlab_api / create_commit.py: 85%
33 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 18:55 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 18:55 +0000
1"""Create Gitlab commit."""
3from functools import lru_cache
4from pathlib import Path
6import git
7import gitlab
8from gitlab.v4.objects import Project
9from tqdm import tqdm
11from sel_tools.utils.files import FileTree, FileVisitor
12from sel_tools.utils.student_config import get_branch_from_student_config
15def commit_changes(repo_paths: list[Path], message: str) -> None:
16 """Commit and push changes to all repos."""
17 for repo_path in tqdm(repo_paths, desc="Committing changes"):
18 repo = git.Repo(repo_path)
19 repo.git.add("--all")
20 repo.git.commit("-am", message)
21 repo.git.push()
24def upload_files(source_folder: Path, student_repos: list[dict], gitlab_instance: gitlab.Gitlab) -> None:
25 """Upload new files from source folder via commit to the repository.
27 For doing more than just adding new files refer to `commit_changes`
28 """
29 for student_repo in tqdm(student_repos, desc="Uploading files"):
30 student_homework_project = gitlab_instance.projects.get(student_repo["id"])
31 create_commit(
32 source_folder,
33 f"Add {source_folder.name}",
34 get_branch_from_student_config(student_repo),
35 student_homework_project,
36 )
39def create_commit(source_folder: Path, message: str, branch: str, gitlab_project: Project) -> None:
40 """Create commit in gitlab project from source folder with message."""
41 gitlab_project.commits.create(create_gitlab_commit_data_with_all_files_from(source_folder, message, branch))
44@lru_cache
45def create_gitlab_commit_data_with_all_files_from(folder: Path, message: str, branch: str) -> dict:
46 """Create gitlab commit with all files from folder.
48 Folder is assumed to be root of the repo committing to
49 """
50 file_tree = FileTree(folder)
51 initial_file_commit_actions_visitor = InitialFileCommitActionsVisitor(folder)
52 file_tree.accept(initial_file_commit_actions_visitor)
54 return (
55 {
56 "branch": branch,
57 "commit_message": message,
58 "actions": initial_file_commit_actions_visitor.actions,
59 }
60 if initial_file_commit_actions_visitor.actions
61 else {}
62 )
65class InitialFileCommitActionsVisitor(FileVisitor):
66 """Create gitlab commit action for new file."""
68 def __init__(self, root_folder: Path) -> None:
69 self.actions: list[dict] = []
70 self.__root_folder = root_folder
72 def visit_file(self, file: Path) -> None:
73 path_in_new_repo = file.relative_to(self.__root_folder)
74 self.actions.append(
75 {
76 "action": "create",
77 "file_path": str(path_in_new_repo),
78 "content": file.read_text(),
79 }
80 )