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

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.projects import Project 

10from tqdm import tqdm 

11 

12from sel_tools.config import GIT_MAIN_BRANCH, GITLAB_SERVER_URL 

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(source_folder, f"Add {source_folder.name}", student_homework_project) 

35 

36 

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

40 

41 

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. 

45 

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) 

51 

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 ) 

61 

62 

63class InitialFileCommitActionsVisitor(FileVisitor): 

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

65 

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

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

68 self.__root_folder = root_folder 

69 

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 )