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

1"""Create Gitlab commit.""" 

2 

3import json 

4from functools import lru_cache 

5from pathlib import Path 

6 

7import git 

8import gitlab 

9from gitlab.v4.objects import Project 

10from tqdm import tqdm 

11 

12from sel_tools.config import GITLAB_SERVER_URL, get_branch_from_student_config 

13from sel_tools.utils.files import FileTree, FileVisitor 

14 

15 

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

23 

24 

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. 

27 

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 ) 

40 

41 

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

45 

46 

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. 

50 

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) 

56 

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 ) 

66 

67 

68class InitialFileCommitActionsVisitor(FileVisitor): 

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

70 

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

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

73 self.__root_folder = root_folder 

74 

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 )