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
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 18:55 +0000
1"""Homework code evaluation module."""
3import copy
4import itertools
5from datetime import date
7import git
8from tqdm import tqdm
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
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 ]
30class CodeEvaluator:
31 """Code evaluator class."""
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)
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 )
50 def __clean_repo(self) -> None:
51 self.__repo.git.restore(".")
52 self.__repo.git.clean("-xdf")
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()