Coverage for sel_tools/gitlab_api/create_commit.py: 86%
36 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-03 19:37 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-03 19:37 +0000
1"""Create Gitlab commit."""
3import json
4from functools import lru_cache
5from pathlib import Path
7import git
8import gitlab
9from gitlab.v4.objects import Project
10from tqdm import tqdm
12from sel_tools.config import GITLAB_SERVER_URL, get_branch_from_student_config
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(
35 source_folder,
36 f"Add {source_folder.name}",
37 get_branch_from_student_config(student_repo),
38 student_homework_project,
39 )
42def create_commit(source_folder: Path, message: str, branch: str, gitlab_project: Project) -> None:
43 """Create commit in gitlab project from source folder with message."""
44 gitlab_project.commits.create(create_gitlab_commit_data_with_all_files_from(source_folder, message, branch))
47@lru_cache
48def create_gitlab_commit_data_with_all_files_from(folder: Path, message: str, branch: str) -> dict:
49 """Create gitlab commit with all files from folder.
51 Folder is assumed to be root of the repo committing to
52 """
53 file_tree = FileTree(folder)
54 initial_file_commit_actions_visitor = InitialFileCommitActionsVisitor(folder)
55 file_tree.accept(initial_file_commit_actions_visitor)
57 return (
58 {
59 "branch": branch,
60 "commit_message": message,
61 "actions": initial_file_commit_actions_visitor.actions,
62 }
63 if initial_file_commit_actions_visitor.actions
64 else {}
65 )
68class InitialFileCommitActionsVisitor(FileVisitor):
69 """Create gitlab commit action for new file."""
71 def __init__(self, root_folder: Path) -> None:
72 self.actions: list[dict] = []
73 self.__root_folder = root_folder
75 def visit_file(self, file: Path) -> None:
76 path_in_new_repo = file.relative_to(self.__root_folder)
77 self.actions.append(
78 {
79 "action": "create",
80 "file_path": str(path_in_new_repo),
81 "content": file.read_text(),
82 }
83 )