Skip to content

Commit 80c5e11

Browse files
authored
Sinol-make (#33)
1 parent 9ffcef8 commit 80c5e11

File tree

9 files changed

+57
-22
lines changed

9 files changed

+57
-22
lines changed

src/sio3pack/files/local_file.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ def __init__(self, path: str, exists=True):
4141
super().__init__(path)
4242
self.filename = os.path.basename(path)
4343

44+
def __repr__(self):
45+
return f"<LocalFile {self.path}>"
46+
4447
def read(self) -> str:
4548
with open(self.path, "r") as f:
4649
return f.read()

src/sio3pack/packages/package/model.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,20 @@ def __getattr__(self, name: str) -> Any:
164164
except AttributeError:
165165
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
166166

167+
def reload_config(self):
168+
pass
169+
167170
@wrap_exceptions
168171
def get_title(self, lang: str | None = None) -> str:
169172
raise NotImplementedError("This method should be implemented in subclasses.")
170173

171174
@wrap_exceptions
172175
def get_statement(self, lang: str | None = None) -> File | None:
173176
raise NotImplementedError("This method should be implemented in subclasses.")
177+
pass
178+
179+
def reload_tests(self):
180+
pass
174181

175182
@wrap_exceptions
176183
def get_test(self, test_id: str) -> Test:

src/sio3pack/packages/sinolpack/model.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ def _from_file(self, file: LocalFile, configuration: SIO3PackConfig = None):
113113
archive.extract(to_path=self.tmpdir.name)
114114
self.rootdir = os.path.join(self.tmpdir.name, self.short_name)
115115
else:
116-
# FIXME: Won't work in sinol-make.
117116
self.short_name = os.path.basename(os.path.abspath(file.path))
118117
self.rootdir = os.path.abspath(file.path)
119118

@@ -164,7 +163,7 @@ def get_prog_dir(self) -> str:
164163
"""
165164
return os.path.join(self.rootdir, "prog")
166165

167-
def get_in_prog_dir(self, filename: str) -> File:
166+
def get_in_prog_dir(self, filename: str) -> LocalFile:
168167
"""
169168
Returns the path to the input file in the program directory.
170169
"""
@@ -193,9 +192,16 @@ def _process_config_yml(self):
193192
try:
194193
config = self.get_in_root("config.yml")
195194
self.config = yaml.safe_load(config.read())
195+
self.short_name = self.config.get("sinol_task_id", self.short_name)
196196
except FileNotFoundError:
197197
self.config = {}
198198

199+
def reload_config(self):
200+
"""
201+
Process the config.yml file again in case it was modified.
202+
"""
203+
self._process_config_yml()
204+
199205
def _detect_full_name(self):
200206
"""
201207
Sets the problem's full name from the ``config.yml`` (key ``title``)
@@ -300,6 +306,12 @@ def special_file_types(self) -> list[str]:
300306
"""
301307
return ["ingen", "inwer", "soc", "chk"]
302308

309+
def _get_all_files_from_list(self, filenames: list[str]) -> list[LocalFile]:
310+
files = []
311+
for filename in filenames:
312+
files.append(self.get_in_prog_dir(filename))
313+
return files
314+
303315
def _process_prog_files(self):
304316
"""
305317
Process all files in the problem's program directory that are used.
@@ -313,13 +325,17 @@ def _process_prog_files(self):
313325
self.model_solutions = self.sort_model_solutions(self._get_model_solutions())
314326

315327
self.additional_files = []
316-
for file in self.config.get("extra_compilation_files", []) + self.config.get("extra_execution_files", []):
328+
extra_files = []
329+
extra_files.extend(self.config.get("extra_compilation_files", []))
330+
for lang_extra_files in self.config.get("extra_execution_files", {}).values():
331+
extra_files.extend(lang_extra_files)
332+
for file in extra_files:
317333
try:
318334
lf = LocalFile(os.path.join(self.get_prog_dir(), file))
319335
self.additional_files.append(lf)
320336
except FileNotFoundError:
321337
pass
322-
extensions = self.get_submittable_extensions()
338+
extensions = self.get_submittable_extensions() + ["sh"]
323339
self.special_files: dict[str, File | None] = {}
324340
for file in self.special_file_types():
325341
try:
@@ -478,6 +494,12 @@ def _process_existing_tests(self):
478494
out_file = None
479495
self.tests.append(Test(test_name, test_id, in_file, out_file, group))
480496

497+
def reload_tests(self):
498+
"""
499+
Updates `self.tests` variable with existing tests.
500+
"""
501+
self._process_existing_tests()
502+
481503
def get_input_tests(self) -> list[Test]:
482504
"""
483505
Returns the list of tests with input files.
@@ -493,11 +515,11 @@ def get_test(self, test_id: str) -> Test:
493515
return test
494516
raise ValueError(f"Test with ID {test_id} not found.")
495517

496-
def get_tests_with_inputs(self) -> list[Test]:
518+
def get_tests_with_inputs(self, tests: list[Test] = None) -> list[Test]:
497519
"""
498520
Returns the list of input tests.
499521
"""
500-
return [test for test in self.tests if test.in_file is not None]
522+
return [test for test in tests or self.tests if test.in_file is not None]
501523

502524
def get_corresponding_out_filename(self, in_test: str) -> str:
503525
"""
@@ -617,8 +639,8 @@ def get(conf) -> int:
617639
if f"{type}_limits" in conf:
618640
if test.test_id in conf[f"{type}_limits"]:
619641
return conf[f"{type}_limits"][test.test_id]
620-
if test.group in conf[f"{type}_limits"]:
621-
return conf[f"{type}_limits"][test.group]
642+
if int(test.group) in conf[f"{type}_limits"]:
643+
return conf[f"{type}_limits"][int(test.group)]
622644
if f"{type}_limit" in conf:
623645
return conf[f"{type}_limit"]
624646
return None

src/sio3pack/test/test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ def __init__(self, test_name: str, test_id: str, in_file: File, out_file: File,
1818
self.in_file = in_file
1919
self.out_file = out_file
2020
self.group = group
21+
22+
def __repr__(self):
23+
return f"<Test {self.test_name}>"

src/sio3pack/workflow/workflow.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from sio3pack.files.file import File
12
from sio3pack.workflow.object import Object, ObjectList, ObjectsManager
23
from sio3pack.workflow.tasks import ExecutionTask, ScriptTask, Task
34

@@ -160,7 +161,7 @@ def add_task(self, task: Task):
160161
"""
161162
self.tasks.append(task)
162163

163-
def get_prog_files(self) -> list[str]:
164+
def get_prog_files(self) -> list[File]:
164165
"""
165166
Get all program files in the workflow.
166167

src/sio3pack/workflow/workflow_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def get_default(self, name: str) -> Workflow:
8787
return self._get_compile_python_workflow()
8888
return None
8989

90-
def get_prog_files(self) -> list[str]:
90+
def get_prog_files(self) -> list[File]:
9191
"""
9292
Get all program files used in all graphs.
9393
"""

tests/packages/sinolpack/test_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,23 @@ def test_get_limits(get_package):
6262
"time_limit": 1000,
6363
"memory_limit": 1024,
6464
"time_limits": {
65-
"1": 2000,
65+
1: 2000,
6666
"1a": 3000,
6767
},
6868
"memory_limits": {
69-
"1": 2048,
69+
1: 2048,
7070
"1a": 3072,
7171
},
7272
"override_limits": {
7373
"py": {
7474
"time_limit": 5000,
7575
"memory_limit": 4096,
7676
"time_limits": {
77-
"2": 6000,
77+
2: 6000,
7878
"2a": 7000,
7979
},
8080
"memory_limits": {
81-
"2": 4096,
81+
2: 4096,
8282
"2a": 5120,
8383
},
8484
}

tests/packages/sinolpack/test_workflows.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ def test_extra_files(get_package):
306306
workflow = workflows[0]
307307

308308
print(workflow.external_objects)
309-
assert len(workflow.external_objects) == 5
309+
assert len(workflow.external_objects) == 4
310310
extlib_h = None
311311
extlib_py = None
312312
for obj in workflow.external_objects:
@@ -315,7 +315,7 @@ def test_extra_files(get_package):
315315
elif obj.handle.endswith("extlib.py"):
316316
extlib_py = obj
317317
assert extlib_h is not None, "Should have extlib.h as external object"
318-
assert extlib_py is not None, "Should have extlib.py as external object"
318+
assert extlib_py is None, "Should not have extlib.py as external object"
319319

320320
for task in workflow.tasks:
321321
if isinstance(task, ExecutionTask):
@@ -333,14 +333,11 @@ def test_extra_files(get_package):
333333
proc = task.processes[0]
334334
assert "extlib.h" in proc.arguments, "Should have extlib.h in arguments"
335335
elif task.name.startswith("Run solution for test"):
336-
assert task.filesystem_manager.len() == 2
337-
ext_fs = task.filesystem_manager.get_by_id(1)
338-
assert isinstance(ext_fs, ObjectFilesystem), "Should have object filesystem with external file"
339-
assert ext_fs.object.handle == extlib_py.handle, "Should have extlib.py as external file"
336+
assert task.filesystem_manager.len() == 1
340337

341338
assert task.mountnamespace_manager.len() == 1, "Should have one mount namespace"
342339
assert (
343-
len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 2
340+
len(task.mountnamespace_manager.get_by_id(0).mountpoints) == 1
344341
), "Should have two mount points"
345342

346343
# Check that python compilation doesnt have extlib.h in compilation args.

tests/test_packages/extra_files/config.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ extra_compilation_files: ['extlib.h']
33
extra_compilation_args:
44
cpp:
55
- 'extlib.h'
6-
extra_execution_files: ['extlib.py']
6+
extra_execution_files:
7+
py:
8+
- 'extlib.py'
79
extra_files: ['dir/some_file.txt']

0 commit comments

Comments
 (0)