Coverage for tools / sel_tools / code_evaluation / evaluate_code.py: 94%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-02 18:55 +0000

1"""Homework code evaluation module.""" 

2 

3import copy 

4import itertools 

5from datetime import date 

6 

7import git 

8from tqdm import tqdm 

9 

10from sel_tools.code_evaluation.jobs.common import EvaluationJob 

11from sel_tools.code_evaluation.jobs.factory import EvaluationJobFactory 

12from sel_tools.code_evaluation.report import EvaluationReport 

13from sel_tools.utils.repo import GitlabProject 

14 

15 

16def evaluate_code( 

17 eval_job_factory: type[EvaluationJobFactory], 

18 gitlab_projects: list[GitlabProject], 

19 homework_number: int, 

20 evaluation_date: date | None, 

21) -> list[EvaluationReport]: 

22 """Evaluate code for given repositories and homework number.""" 

23 evaluation_jobs = eval_job_factory.create(gitlab_projects, homework_number) 

24 return [ 

25 CodeEvaluator(evaluation_jobs, gitlab_project, homework_number).evaluate(evaluation_date) 

26 for gitlab_project in tqdm(gitlab_projects, desc=f"Evaluating Homework {homework_number}") 

27 ] 

28 

29 

30class CodeEvaluator: 

31 """Code evaluator class.""" 

32 

33 def __init__(self, jobs: list[EvaluationJob], gitlab_project: GitlabProject, homework_number: int) -> None: 

34 # Perform a deepcopy to avoid artifact of old job runs 

35 self.__jobs = copy.deepcopy(jobs) 

36 self.__gitlab_project = gitlab_project 

37 self.__homework_number = homework_number 

38 self.__repo = git.Repo(gitlab_project.local_path) 

39 

40 def evaluate(self, evaluation_date: date | None) -> EvaluationReport: 

41 self.__clean_repo() 

42 if evaluation_date is not None: 

43 self.__checkout_last_commit_before_eval_date(evaluation_date) 

44 return EvaluationReport( 

45 self.__gitlab_project, 

46 self.__homework_number, 

47 list(itertools.chain(*[job.run(self.__gitlab_project.local_path) for job in self.__jobs])), 

48 ) 

49 

50 def __clean_repo(self) -> None: 

51 self.__repo.git.restore(".") 

52 self.__repo.git.clean("-xdf") 

53 

54 def __checkout_last_commit_before_eval_date(self, evaluation_date: date) -> None: 

55 commits_before_eval_date = list(self.__repo.iter_commits(before=evaluation_date)) 

56 if commits_before_eval_date: 

57 self.__repo.git.checkout(commits_before_eval_date[0]) 

58 self.__clean_repo()