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

1"""Create Gitlab commit.""" 

2 

3from functools import lru_cache 

4from pathlib import Path 

5 

6import git 

7import gitlab 

8from gitlab.v4.objects import Project 

9from tqdm import tqdm 

10 

11from sel_tools.utils.files import FileTree, FileVisitor 

12from sel_tools.utils.student_config import get_branch_from_student_config 

13 

14 

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() 

22 

23 

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. 

26 

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 ) 

37 

38 

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)) 

42 

43 

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. 

47 

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) 

53 

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 ) 

63 

64 

65class InitialFileCommitActionsVisitor(FileVisitor): 

66 """Create gitlab commit action for new file.""" 

67 

68 def __init__(self, root_folder: Path) -> None: 

69 self.actions: list[dict] = [] 

70 self.__root_folder = root_folder 

71 

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 )