diff --git a/src/sinol_make/commands/export/__init__.py b/src/sinol_make/commands/export/__init__.py index 83d3e08f..2ff67203 100644 --- a/src/sinol_make/commands/export/__init__.py +++ b/src/sinol_make/commands/export/__init__.py @@ -230,8 +230,7 @@ def run(self, args: argparse.Namespace): self.task_id = package_util.get_task_id() package_util.validate_test_names(self.task_id) - with open(os.path.join(os.getcwd(), 'config.yml'), 'r') as config_file: - config = yaml.load(config_file, Loader=yaml.FullLoader) + config = package_util.get_config() export_package_path = paths.get_cache_path('export', self.task_id) if os.path.exists(export_package_path): diff --git a/src/sinol_make/commands/run/__init__.py b/src/sinol_make/commands/run/__init__.py index 0bf5c623..0796f6d7 100644 --- a/src/sinol_make/commands/run/__init__.py +++ b/src/sinol_make/commands/run/__init__.py @@ -1148,12 +1148,7 @@ def run(self, args): self.set_constants() package_util.validate_test_names(self.ID) self.args = args - with open(os.path.join(os.getcwd(), "config.yml"), 'r') as config: - try: - self.config = yaml.load(config, Loader=yaml.FullLoader) - except AttributeError: - self.config = yaml.load(config) - + self.config = package_util.get_config() try: self.contest = contest_types.get_contest_type() except UnknownContestType as e: diff --git a/src/sinol_make/contest_types/__init__.py b/src/sinol_make/contest_types/__init__.py index 309198df..98887606 100644 --- a/src/sinol_make/contest_types/__init__.py +++ b/src/sinol_make/contest_types/__init__.py @@ -1,16 +1,13 @@ -import os -import yaml - from sinol_make.contest_types.default import DefaultContest from sinol_make.contest_types.icpc import ICPCContest from sinol_make.contest_types.oi import OIContest +from sinol_make.helpers.package_util import get_config from sinol_make.interfaces.Errors import UnknownContestType def get_contest_type(): - with open(os.path.join(os.getcwd(), "config.yml"), "r") as config_file: - config = yaml.load(config_file, Loader=yaml.FullLoader) - contest_type = config.get("sinol_contest_type", "default").lower() + config = get_config() + contest_type = config.get("sinol_contest_type", "default").lower() if contest_type == "default": return DefaultContest() diff --git a/src/sinol_make/helpers/compile.py b/src/sinol_make/helpers/compile.py index b4435b8f..5c1c9375 100644 --- a/src/sinol_make/helpers/compile.py +++ b/src/sinol_make/helpers/compile.py @@ -9,7 +9,7 @@ import sinol_make.helpers.compiler as compiler from sinol_make import util from sinol_make.helpers import paths -from sinol_make.helpers.cache import check_compiled, save_compiled +from sinol_make.helpers.cache import check_compiled, save_compiled, package_util from sinol_make.interfaces.Errors import CompilationError from sinol_make.structs.compiler_structs import Compilers @@ -120,8 +120,7 @@ def compile_file(file_path: str, name: str, compilers: Compilers, weak_compilati os.makedirs(paths.get_executables_path(), exist_ok=True) os.makedirs(paths.get_compilation_log_path(), exist_ok=True) - with open(os.path.join(os.getcwd(), "config.yml"), "r") as config_file: - config = yaml.load(config_file, Loader=yaml.FullLoader) + config = package_util.get_config() extra_compilation_files = [os.path.join(os.getcwd(), "prog", file) for file in config.get("extra_compilation_files", [])] @@ -148,8 +147,11 @@ def print_compile_log(compile_log_path: str): Print the first 500 lines of compilation log :param compile_log_path: path to the compilation log """ + lines_to_print = 500 with open(compile_log_path, 'r') as compile_log: lines = compile_log.readlines() - for line in lines[:500]: + for line in lines[:lines_to_print]: print(line, end='') + if len(lines) > lines_to_print: + print(util.error(f"Compilation log too long. Whole log file at: {compile_log_path}")) diff --git a/src/sinol_make/helpers/package_util.py b/src/sinol_make/helpers/package_util.py index 86cdc53b..2a69d52d 100644 --- a/src/sinol_make/helpers/package_util.py +++ b/src/sinol_make/helpers/package_util.py @@ -11,8 +11,7 @@ def get_task_id() -> str: - with open(os.path.join(os.getcwd(), "config.yml")) as config_file: - config = yaml.load(config_file, Loader=yaml.FullLoader) + config = get_config() if "sinol_task_id" in config: return config["sinol_task_id"] else: @@ -38,7 +37,7 @@ def extract_test_id(test_path, task_id): def get_group(test_path, task_id): if extract_test_id(test_path, task_id).endswith("ocen"): return 0 - return int("".join(re.search(r'\d+',extract_test_id(test_path, task_id)).group())) + return int("".join(re.search(r'\d+', extract_test_id(test_path, task_id)).group())) def get_groups(tests, task_id): @@ -49,12 +48,23 @@ def get_test_key(test, task_id): return get_group(test, task_id), test +def get_config(): + try: + with open(os.path.join(os.getcwd(), "config.yml"), "r") as config_file: + return yaml.load(config_file, Loader=yaml.FullLoader) + except FileNotFoundError: + # Potentially redundant with util:exit_if_not_package + util.exit_with_error("You are not in a package directory (couldn't find config.yml in current directory).") + except yaml.YAMLError as e: + util.exit_with_error("config.yml is not a valid YAML. Fix it before continuing:\n" + str(e)) + + def get_solutions_re(task_id: str) -> re.Pattern: """ Returns regex pattern matching all solutions for given task. :param task_id: Task id. """ - return re.compile(r"^%s[bs]?[0-9]*(_.*)?\.(cpp|cc|java|py|pas)$" % task_id) + return re.compile(r"^%s[bs]?[0-9]*(_.*)?\.(c|cpp|cc|py)$" % task_id) def get_executable_key(executable, task_id): @@ -202,7 +212,8 @@ def _get_limit_from_dict(dict: Dict[str, Any], limit_type: LimitTypes, test_id: if allow_test_limit: return dict[plural_limit_name][test_id] else: - util.exit_with_error(f'{os.path.basename(test_path)}: Specifying limit for a single test is not allowed in sinol-make.') + util.exit_with_error( + f'{os.path.basename(test_path)}: Specifying limit for a single test is not allowed in sinol-make.') elif test_group in dict[plural_limit_name]: return dict[plural_limit_name][test_group] if limit_name in dict: @@ -226,9 +237,11 @@ def _get_limit(limit_type: LimitTypes, test_path: str, config: Dict[str, Any], l return global_limit else: if limit_type == LimitTypes.TIME_LIMIT: - util.exit_with_error(f'Time limit was not defined for test {os.path.basename(test_path)} in config.yml.') + util.exit_with_error( + f'Time limit was not defined for test {os.path.basename(test_path)} in config.yml.') elif limit_type == LimitTypes.MEMORY_LIMIT: - util.exit_with_error(f'Memory limit was not defined for test {os.path.basename(test_path)} in config.yml.') + util.exit_with_error( + f'Memory limit was not defined for test {os.path.basename(test_path)} in config.yml.') def get_time_limit(test_path, config, lang, task_id, args=None): @@ -257,6 +270,7 @@ def validate_test_names(task_id): """ Checks if all files in the package have valid names. """ + def get_invalid_files(path, pattern): invalid_files = [] for file in glob.glob(os.path.join(os.getcwd(), path)): diff --git a/tests/commands/export/test_integration.py b/tests/commands/export/test_integration.py index ba2dfd56..b59b8dc5 100644 --- a/tests/commands/export/test_integration.py +++ b/tests/commands/export/test_integration.py @@ -53,7 +53,7 @@ def test_simple(create_package, capsys): """ package_path = create_package parser = configure_parsers() - args = parser.parse_args(["export"]) + args = parser.parse_args(["export", "--no-statement"]) command = Command() command.run(args) @@ -95,7 +95,7 @@ def test_correct_permissions(create_package, capsys): os.chmod(shell_ingen, st.st_mode & ~stat.S_IEXEC) parser = configure_parsers() - args = parser.parse_args(["export"]) + args = parser.parse_args(["export", "--no-statement"]) command = Command() command.run(args) task_id = package_util.get_task_id() @@ -116,7 +116,7 @@ def test_handwritten_tests(create_package): Test if handwritten tests are correctly copied. """ parser = configure_parsers() - args = parser.parse_args(["export"]) + args = parser.parse_args(["export", "--no-statement"]) command = Command() command.run(args) task_id = package_util.get_task_id() @@ -136,7 +136,7 @@ def test_ocen_archive(create_package): Test creation of ocen archive. """ parser = configure_parsers() - args = parser.parse_args(["export"]) + args = parser.parse_args(["export", "--no-statement"]) command = Command() command.run(args) task_id = package_util.get_task_id()