diff --git a/src/sinol_make/commands/run/__init__.py b/src/sinol_make/commands/run/__init__.py index 0994bb89..6a01152c 100644 --- a/src/sinol_make/commands/run/__init__.py +++ b/src/sinol_make/commands/run/__init__.py @@ -340,17 +340,17 @@ def get_groups(self, tests): return sorted(list(set([self.get_group(test) for test in tests]))) - def compile_solutions(self, solutions): + def compile_solutions(self, solutions, is_checker=False): os.makedirs(paths.get_compilation_log_path(), exist_ok=True) os.makedirs(paths.get_executables_path(), exist_ok=True) print("Compiling %d solutions..." % len(solutions)) - args = [(solution, True) for solution in solutions] + args = [(solution, True, is_checker) for solution in solutions] with mp.Pool(self.cpus) as pool: compilation_results = pool.starmap(self.compile, args) return compilation_results - def compile(self, solution, use_extras = False): + def compile(self, solution, use_extras = False, is_checker = False): compile_log_file = paths.get_compilation_log_path("%s.compile_log" % package_util.get_file_name(solution)) source_file = os.path.join(os.getcwd(), "prog", self.get_solution_from_exe(solution)) output = paths.get_executables_path(package_util.get_executable(solution)) @@ -371,7 +371,7 @@ def compile(self, solution, use_extras = False): try: with open(compile_log_file, "w") as compile_log: compile.compile(source_file, output, self.compilers, compile_log, self.args.weak_compilation_flags, - extra_compilation_args, extra_compilation_files) + extra_compilation_args, extra_compilation_files, is_checker=is_checker) print(util.info("Compilation of file %s was successful." % package_util.get_file_name(solution))) return True @@ -1185,6 +1185,14 @@ def check_errors(self, results: Dict[str, Dict[str, Dict[str, ExecutionResult]]] if error_msg != "": util.exit_with_error(error_msg) + def compile_checker(self): + checker_basename = os.path.basename(self.checker) + self.checker_executable = paths.get_executables_path(checker_basename + ".e") + + checker_compilation = self.compile_solutions([self.checker], is_checker=True) + if not checker_compilation[0]: + util.exit_with_error('Checker compilation failed.') + def run(self, args): util.exit_if_not_package() @@ -1215,12 +1223,7 @@ def run(self, args): if len(checker) != 0: print(util.info("Checker found: %s" % os.path.basename(checker[0]))) self.checker = checker[0] - checker_basename = os.path.basename(self.checker) - self.checker_executable = paths.get_executables_path(checker_basename + ".e") - - checker_compilation = self.compile_solutions([self.checker]) - if not checker_compilation[0]: - util.exit_with_error('Checker compilation failed.') + self.compile_checker() else: self.checker = None diff --git a/src/sinol_make/helpers/cache.py b/src/sinol_make/helpers/cache.py index 961c6987..6fc5c2c0 100644 --- a/src/sinol_make/helpers/cache.py +++ b/src/sinol_make/helpers/cache.py @@ -1,12 +1,13 @@ import os import yaml +from typing import Union from sinol_make import util from sinol_make.structs.cache_structs import CacheFile from sinol_make.helpers import paths -def get_cache_file(solution_path: str): +def get_cache_file(solution_path: str) -> CacheFile: """ Returns content of cache file for given solution :param solution_path: Path to solution @@ -21,7 +22,7 @@ def get_cache_file(solution_path: str): return CacheFile() -def check_compiled(file_path: str): +def check_compiled(file_path: str) -> Union[str, None]: """ Check if a file is compiled :param file_path: Path to the file @@ -39,14 +40,22 @@ def check_compiled(file_path: str): return None -def save_compiled(file_path: str, exe_path: str): +def save_compiled(file_path: str, exe_path: str, is_checker: bool = False): """ Save the compiled executable path to cache in `.cache/md5sums/`, which contains the md5sum of the file and the path to the executable. :param file_path: Path to the file :param exe_path: Path to the compiled executable + :param is_checker: Whether the compiled file is a checker. If True, all cached tests are removed. """ info = get_cache_file(file_path) info.executable_path = exe_path info.md5sum = util.get_file_md5(file_path) info.save(file_path) + + if is_checker: + for solution in os.listdir(paths.get_cache_path('md5sums')): + info = get_cache_file(solution) + print(info) + info.tests = {} + info.save(solution) diff --git a/src/sinol_make/helpers/compile.py b/src/sinol_make/helpers/compile.py index 035a20c4..4baea5bf 100644 --- a/src/sinol_make/helpers/compile.py +++ b/src/sinol_make/helpers/compile.py @@ -14,7 +14,7 @@ def compile(program, output, compilers: Compilers = None, compile_log = None, weak_compilation_flags = False, - extra_compilation_args = None, extra_compilation_files = None): + extra_compilation_args = None, extra_compilation_files = None, is_checker = False): """ Compile a program. :param program: Path to the program to compile @@ -24,6 +24,7 @@ def compile(program, output, compilers: Compilers = None, compile_log = None, we :param weak_compilation_flags: If True, disable all warnings :param extra_compilation_args: Extra compilation arguments :param extra_compilation_files: Extra compilation files + :param is_checker: Set to True if compiling a checker. This will remove all cached test results. """ if extra_compilation_args is None: extra_compilation_args = [] @@ -92,7 +93,7 @@ def compile(program, output, compilers: Compilers = None, compile_log = None, we if process.returncode != 0: raise CompilationError('Compilation failed') else: - save_compiled(program, output) + save_compiled(program, output, is_checker) return True diff --git a/src/sinol_make/structs/cache_structs.py b/src/sinol_make/structs/cache_structs.py index 034a230c..5d1f3933 100644 --- a/src/sinol_make/structs/cache_structs.py +++ b/src/sinol_make/structs/cache_structs.py @@ -28,7 +28,7 @@ def __init__(self, time_limit=0, memory_limit=0, time_tool="", result=None): self.time_tool = time_tool self.result = result - def to_dict(self): + def to_dict(self) -> Dict: return { "time_limit": self.time_limit, "memory_limit": self.memory_limit, @@ -53,7 +53,7 @@ def __init__(self, md5sum="", executable_path="", tests=None): self.executable_path = executable_path self.tests = tests - def to_dict(self): + def to_dict(self) -> Dict: return { "md5sum": self.md5sum, "executable_path": self.executable_path, @@ -61,7 +61,7 @@ def to_dict(self): } @staticmethod - def from_dict(dict): + def from_dict(dict) -> 'CacheFile': return CacheFile( md5sum=dict.get("md5sum", ""), executable_path=dict.get("executable_path", ""),