3
3
from util import *
4
4
from validate import InputValidator , AnswerValidator , OutputValidator
5
5
6
+ import secrets
6
7
import shutil
7
8
from typing import Any
8
9
@@ -28,6 +29,34 @@ def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
28
29
bar .log (f"renaming '{ old_name } ' to '{ new_name } '" )
29
30
old_path .rename (new_path )
30
31
32
+ def rename_testcase (old_base : Path , new_dir : Path ) -> None :
33
+ new_dir .mkdir (parents = True , exist_ok = True )
34
+ new_base = new_dir / old_base .name
35
+ for ext in config .KNOWN_TEXT_DATA_EXTENSIONS :
36
+ old_path = old_base .with_suffix (ext )
37
+ new_path = new_base .with_suffix (ext )
38
+ if old_path .is_file ():
39
+ old_rel_path , new_rel_path = [
40
+ p .relative_to (problem_path ) for p in (old_path , new_path )
41
+ ]
42
+ if new_path .exists ():
43
+ bar .error (
44
+ f"can't rename '{ old_rel_path } ', '{ new_rel_path } ' already exists" ,
45
+ resume = True ,
46
+ )
47
+ continue
48
+ bar .log (f"renaming '{ old_rel_path } ' to '{ new_rel_path } '" )
49
+ old_path .rename (new_path )
50
+
51
+ bad_dir = problem_path / "data" / "bad"
52
+ for file in bad_dir .glob ("*.in" ):
53
+ if file .with_suffix (".ans" ).is_file ():
54
+ rename_testcase (file , problem_path / "data" / "invalid_answer" )
55
+ else :
56
+ rename_testcase (file , problem_path / "data" / "invalid_input" )
57
+ if bad_dir .is_dir () and not any (bad_dir .iterdir ()):
58
+ bad_dir .rmdir ()
59
+
31
60
32
61
def upgrade_testdata_yaml (problem_path : Path , bar : ProgressBar ) -> None :
33
62
rename = [
@@ -62,14 +91,16 @@ def upgrade_generators_yaml(problem_path: Path, bar: ProgressBar) -> None:
62
91
63
92
changed = False
64
93
65
- rename = [
66
- ("invalid_inputs" , "invalid_input" ),
67
- ("invalid_answers" , "invalid_answer" ),
68
- ("invalid_outputs" , "invalid_output" ),
69
- ("valid_outputs" , "valid_output" ),
70
- ]
71
94
if "data" in yaml_data and isinstance (yaml_data ["data" ], dict ):
72
95
data = yaml_data ["data" ]
96
+ assert isinstance (data , CommentedMap )
97
+
98
+ rename = [
99
+ ("invalid_inputs" , "invalid_input" ),
100
+ ("invalid_answers" , "invalid_answer" ),
101
+ ("invalid_outputs" , "invalid_output" ),
102
+ ("valid_outputs" , "valid_output" ),
103
+ ]
73
104
for old_name , new_name in rename :
74
105
if old_name in data :
75
106
if new_name in data :
@@ -82,6 +113,40 @@ def upgrade_generators_yaml(problem_path: Path, bar: ProgressBar) -> None:
82
113
ryaml_replace (data , old_name , new_name )
83
114
changed = True
84
115
116
+ # this breaks comments... but that is fine
117
+ if "bad" in data :
118
+
119
+ def move_testcase (name : str , value : Any , new_parent : str ) -> None :
120
+ parent = ryaml_get_or_add (data , new_parent )
121
+ if "data" not in parent :
122
+ parent [data ] = CommentedSeq
123
+ parent = parent ["data" ]
124
+ new_name = name
125
+ if isinstance (parent , list ):
126
+ parent .append (CommentedMap ())
127
+ parent [- 1 ][new_name ] = value
128
+ else :
129
+ if new_name in parent :
130
+ new_name = f"bad_{ new_name } "
131
+ if new_name in parent :
132
+ new_name = f"{ new_name } _{ secrets .token_hex (6 )} "
133
+ assert new_name not in parent
134
+ parent [new_name ] = value
135
+ bar .log (f"renaming 'bad.{ name } ' to '{ new_parent } .{ new_name } ' in generators.yaml" )
136
+
137
+ bad = data ["bad" ]
138
+ if "data" in bad and bad ["data" ]:
139
+ children = bad ["data" ] if isinstance (bad ["data" ], list ) else [bad ["data" ]]
140
+ for dictionary in children :
141
+ for child_name , child_data in sorted (dictionary .items ()):
142
+ if "ans" in child_data :
143
+ move_testcase (child_name , child_data , "invalid_answer" )
144
+ else :
145
+ move_testcase (child_name , child_data , "invalid_input" )
146
+
147
+ ryaml_filter (data , "bad" )
148
+ changed = True
149
+
85
150
def upgrade_generated_testdata_yaml (data : dict [str , Any ], path : str ) -> bool :
86
151
changed = False
87
152
if "testdata.yaml" in data :
@@ -374,7 +439,7 @@ def add_args(new_data: dict[str, Any]) -> bool:
374
439
data ["limits" ] = CommentedMap ()
375
440
if "time_limit" in data ["limits" ]:
376
441
bar .error (
377
- "can't change '.timelimit ' file, 'limits.time_limit' already exists in problem.yaml" ,
442
+ "can't change 'domjudge-problem.ini ' file, 'limits.time_limit' already exists in problem.yaml" ,
378
443
resume = True ,
379
444
)
380
445
else :
0 commit comments