Skip to content

Commit 15a01c0

Browse files
authored
Allow generating only ins/outs in gen command (#157)
* Add --ins and --outs flags * Add tests * Fix tests * Longer flag names * Bump version for release
1 parent a4bda02 commit 15a01c0

File tree

3 files changed

+97
-25
lines changed

3 files changed

+97
-25
lines changed

src/sinol_make/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sinol_make import util, oiejq
1010

1111

12-
__version__ = "1.5.13"
12+
__version__ = "1.5.14"
1313

1414

1515
def configure_parsers():

src/sinol_make/commands/gen/__init__.py

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ def configure_subparser(self, subparser):
3434

3535
parser.add_argument('ingen_path', type=str, nargs='?',
3636
help='path to ingen source file, for example prog/abcingen.cpp')
37+
parser.add_argument('-i', '--only-inputs', action='store_true', help='generate input files only')
38+
parser.add_argument('-o', '--only-outputs', action='store_true', help='generate output files only')
3739
parser.add_argument('-c', '--cpus', type=int,
3840
help=f'number of cpus to use to generate output files '
3941
f'(default: {util.default_cpu_count()})',
@@ -80,38 +82,51 @@ def calculate_md5_sums(self):
8082
outputs_to_generate = []
8183
for file in glob.glob(os.path.join(os.getcwd(), 'in', '*.in')):
8284
basename = os.path.basename(file)
85+
output_basename = os.path.splitext(os.path.basename(basename))[0] + '.out'
86+
output_path = os.path.join(os.getcwd(), 'out', output_basename)
8387
md5_sums[basename] = util.get_file_md5(file)
8488

8589
if old_md5_sums is None or old_md5_sums.get(basename, '') != md5_sums[basename]:
86-
output_basename = os.path.splitext(os.path.basename(basename))[0] + '.out'
87-
outputs_to_generate.append(os.path.join(os.getcwd(), "out", output_basename))
90+
outputs_to_generate.append(output_path)
91+
elif not os.path.exists(output_path):
92+
# If output file does not exist, generate it.
93+
outputs_to_generate.append(output_path)
8894

8995
return md5_sums, outputs_to_generate
9096

9197
def run(self, args: argparse.Namespace):
9298
util.exit_if_not_package()
9399

94100
self.args = args
101+
self.ins = args.only_inputs
102+
self.outs = args.only_outputs
103+
# If no arguments are specified, generate both input and output files.
104+
if not self.ins and not self.outs:
105+
self.ins = True
106+
self.outs = True
107+
95108
self.task_id = package_util.get_task_id()
96109
package_util.validate_test_names(self.task_id)
97-
self.ingen = gen_util.get_ingen(self.task_id, args.ingen_path)
98-
print(util.info(f'Using ingen file {os.path.basename(self.ingen)}'))
110+
util.change_stack_size_to_unlimited()
111+
if self.ins:
112+
self.ingen = gen_util.get_ingen(self.task_id, args.ingen_path)
113+
print(util.info(f'Using ingen file {os.path.basename(self.ingen)}'))
114+
self.ingen_exe = gen_util.compile_ingen(self.ingen, self.args, self.args.weak_compilation_flags)
115+
116+
if gen_util.run_ingen(self.ingen_exe):
117+
print(util.info('Successfully generated input files.'))
118+
else:
119+
util.exit_with_error('Failed to generate input files.')
99120

100-
self.correct_solution = gen_util.get_correct_solution(self.task_id)
101-
self.ingen_exe = gen_util.compile_ingen(self.ingen, self.args, self.args.weak_compilation_flags)
121+
if self.outs:
122+
self.correct_solution = gen_util.get_correct_solution(self.task_id)
102123

103-
util.change_stack_size_to_unlimited()
104-
if gen_util.run_ingen(self.ingen_exe):
105-
print(util.info('Successfully generated input files.'))
106-
else:
107-
util.exit_with_error('Failed to generate input files.')
108-
md5_sums, outputs_to_generate = self.calculate_md5_sums()
109-
if len(outputs_to_generate) == 0:
110-
print(util.info('All output files are up to date.'))
111-
else:
112-
self.correct_solution_exe = gen_util.compile_correct_solution(self.correct_solution, self.args,
113-
self.args.weak_compilation_flags)
114-
self.generate_outputs(outputs_to_generate)
115-
116-
with open(os.path.join(os.getcwd(), 'in', '.md5sums'), 'w') as f:
117-
yaml.dump(md5_sums, f)
124+
md5_sums, outputs_to_generate = self.calculate_md5_sums()
125+
if len(outputs_to_generate) == 0:
126+
print(util.info('All output files are up to date.'))
127+
else:
128+
self.correct_solution_exe = gen_util.compile_correct_solution(self.correct_solution, self.args,
129+
self.args.weak_compilation_flags)
130+
self.generate_outputs(outputs_to_generate)
131+
with open(os.path.join(os.getcwd(), 'in', '.md5sums'), 'w') as f:
132+
yaml.dump(md5_sums, f)

tests/commands/gen/test_integration.py

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
from sinol_make import configure_parsers
77
from sinol_make.commands.gen import Command
88
from sinol_make.commands.gen import gen_util
9-
from sinol_make.helpers import package_util
9+
from sinol_make.helpers import package_util, paths
1010
from tests.fixtures import *
1111
from tests import util
1212

1313

14-
def simple_run():
14+
def simple_run(arguments=None):
15+
if arguments is None:
16+
arguments = []
1517
parser = configure_parsers()
16-
args = parser.parse_args(["gen"])
18+
args = parser.parse_args(["gen"] + arguments)
1719
command = Command()
1820
command.run(args)
1921

@@ -95,3 +97,58 @@ def test_shell_ingen_unchanged(create_package):
9597
edited_time = os.path.getmtime(shell_ingen_path)
9698
simple_run()
9799
assert edited_time == os.path.getmtime(shell_ingen_path)
100+
101+
102+
@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
103+
indirect=True)
104+
def test_only_inputs_flag(create_package):
105+
"""
106+
Test if `--only-inputs` flag works.
107+
"""
108+
simple_run(["--only-inputs"])
109+
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
110+
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
111+
assert len(ins) > 0
112+
assert len(outs) == 0
113+
assert not os.path.exists(os.path.join(create_package, "in", ".md5sums"))
114+
115+
@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
116+
indirect=True)
117+
def test_only_outputs_flag(create_package):
118+
"""
119+
Test if `--only-outputs` flag works.
120+
"""
121+
simple_run(['--only-inputs'])
122+
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
123+
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
124+
in1 = ins[0]
125+
for file in ins[1:]:
126+
os.unlink(file)
127+
assert len(outs) == 0
128+
def in_to_out(file):
129+
return os.path.join(create_package, "out", os.path.basename(file).replace(".in", ".out"))
130+
131+
simple_run(["--only-outputs"])
132+
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
133+
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
134+
assert len(ins) == 1
135+
assert os.path.exists(in_to_out(in1))
136+
assert len(outs) == 1
137+
138+
139+
@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
140+
indirect=True)
141+
def test_missing_output_files(create_package):
142+
"""
143+
Test if `ingen` command generates missing output files.
144+
"""
145+
package_path = create_package
146+
for args in [[], ["--only-outputs"]]:
147+
simple_run()
148+
outs = glob.glob(os.path.join(package_path, "out", "*.out"))
149+
os.unlink(outs[0])
150+
assert not os.path.exists(outs[0])
151+
simple_run(args)
152+
assert os.path.exists(outs[0])
153+
shutil.rmtree(paths.get_cache_path())
154+
os.unlink(os.path.join(package_path, "in", ".md5sums"))

0 commit comments

Comments
 (0)