Coverage for tools/sel_tools/code_evaluation/jobs/common.py: 91%

45 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-02 05:55 +0000

1"""Common evaluation job interface and utilities.""" 

2 

3import itertools 

4import subprocess 

5from abc import ABCMeta, abstractmethod 

6from pathlib import Path 

7 

8from sel_tools.code_evaluation.report import EvaluationResult 

9 

10 

11class EvaluationJob: 

12 """Interface for evaluation job. 

13 

14 Children implement _run 

15 """ 

16 

17 __metaclass__ = ABCMeta 

18 

19 def __init__(self, weight: int = 1) -> None: 

20 self.__weight: int = weight 

21 self._comment: str = "" 

22 

23 def run(self, repo_path: Path) -> list[EvaluationResult]: 

24 deps_results = [job.run(repo_path) for job in self.dependencies] 

25 print(f"\nRunning {self.name} on {repo_path}") 

26 job_result_score = min(self._run(repo_path), self.max_run_score) 

27 return [ 

28 *list(itertools.chain(*deps_results)), 

29 EvaluationResult( 

30 self.name, self.__weight * job_result_score, self.max_run_score * self.__weight, self.comment 

31 ), 

32 ] 

33 

34 @property 

35 @abstractmethod 

36 def name(self) -> str: 

37 msg = "Don't call me, I'm abstract." 

38 raise NotImplementedError(msg) 

39 

40 @property 

41 def max_run_score(self) -> int: 

42 return 1 

43 

44 @property 

45 def comment(self) -> str: 

46 return f"{self.name}: {self._comment}" if self._comment else "" 

47 

48 @property 

49 def dependencies(self) -> list["EvaluationJob"]: 

50 return [] 

51 

52 @abstractmethod 

53 def _run(self, repo_path: Path) -> int: 

54 msg = "Don't call me, I'm abstract." 

55 raise NotImplementedError(msg) 

56 

57 

58def run_shell_command(command: str, cwd: Path) -> int: 

59 """Run shell command.""" 

60 try: 

61 subprocess.check_call(command, shell=True, cwd=cwd) 

62 except subprocess.CalledProcessError: 

63 return 0 

64 return 1 

65 

66 

67def run_shell_command_with_output(command: str, cwd: Path) -> tuple[int, str]: 

68 """Run shell command and get the output.""" 

69 try: 

70 data = subprocess.check_output(command, shell=True, cwd=cwd) 

71 except subprocess.CalledProcessError as ex: 

72 return 0, ex.output.decode("utf-8") 

73 return 1, data.decode("utf-8")