Skip to content

Commit

Permalink
Allow generating only ins/outs in gen command (#157)
Browse files Browse the repository at this point in the history
* Add --ins and --outs flags

* Add tests

* Fix tests

* Longer flag names

* Bump version for release
  • Loading branch information
MasloMaslane authored Oct 29, 2023
1 parent a4bda02 commit 15a01c0
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/sinol_make/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from sinol_make import util, oiejq


__version__ = "1.5.13"
__version__ = "1.5.14"


def configure_parsers():
Expand Down
57 changes: 36 additions & 21 deletions src/sinol_make/commands/gen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def configure_subparser(self, subparser):

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

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

return md5_sums, outputs_to_generate

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

self.args = args
self.ins = args.only_inputs
self.outs = args.only_outputs
# If no arguments are specified, generate both input and output files.
if not self.ins and not self.outs:
self.ins = True
self.outs = True

self.task_id = package_util.get_task_id()
package_util.validate_test_names(self.task_id)
self.ingen = gen_util.get_ingen(self.task_id, args.ingen_path)
print(util.info(f'Using ingen file {os.path.basename(self.ingen)}'))
util.change_stack_size_to_unlimited()
if self.ins:
self.ingen = gen_util.get_ingen(self.task_id, args.ingen_path)
print(util.info(f'Using ingen file {os.path.basename(self.ingen)}'))
self.ingen_exe = gen_util.compile_ingen(self.ingen, self.args, self.args.weak_compilation_flags)

if gen_util.run_ingen(self.ingen_exe):
print(util.info('Successfully generated input files.'))
else:
util.exit_with_error('Failed to generate input files.')

self.correct_solution = gen_util.get_correct_solution(self.task_id)
self.ingen_exe = gen_util.compile_ingen(self.ingen, self.args, self.args.weak_compilation_flags)
if self.outs:
self.correct_solution = gen_util.get_correct_solution(self.task_id)

util.change_stack_size_to_unlimited()
if gen_util.run_ingen(self.ingen_exe):
print(util.info('Successfully generated input files.'))
else:
util.exit_with_error('Failed to generate input files.')
md5_sums, outputs_to_generate = self.calculate_md5_sums()
if len(outputs_to_generate) == 0:
print(util.info('All output files are up to date.'))
else:
self.correct_solution_exe = gen_util.compile_correct_solution(self.correct_solution, self.args,
self.args.weak_compilation_flags)
self.generate_outputs(outputs_to_generate)

with open(os.path.join(os.getcwd(), 'in', '.md5sums'), 'w') as f:
yaml.dump(md5_sums, f)
md5_sums, outputs_to_generate = self.calculate_md5_sums()
if len(outputs_to_generate) == 0:
print(util.info('All output files are up to date.'))
else:
self.correct_solution_exe = gen_util.compile_correct_solution(self.correct_solution, self.args,
self.args.weak_compilation_flags)
self.generate_outputs(outputs_to_generate)
with open(os.path.join(os.getcwd(), 'in', '.md5sums'), 'w') as f:
yaml.dump(md5_sums, f)
63 changes: 60 additions & 3 deletions tests/commands/gen/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
from sinol_make import configure_parsers
from sinol_make.commands.gen import Command
from sinol_make.commands.gen import gen_util
from sinol_make.helpers import package_util
from sinol_make.helpers import package_util, paths
from tests.fixtures import *
from tests import util


def simple_run():
def simple_run(arguments=None):
if arguments is None:
arguments = []
parser = configure_parsers()
args = parser.parse_args(["gen"])
args = parser.parse_args(["gen"] + arguments)
command = Command()
command.run(args)

Expand Down Expand Up @@ -95,3 +97,58 @@ def test_shell_ingen_unchanged(create_package):
edited_time = os.path.getmtime(shell_ingen_path)
simple_run()
assert edited_time == os.path.getmtime(shell_ingen_path)


@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
indirect=True)
def test_only_inputs_flag(create_package):
"""
Test if `--only-inputs` flag works.
"""
simple_run(["--only-inputs"])
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
assert len(ins) > 0
assert len(outs) == 0
assert not os.path.exists(os.path.join(create_package, "in", ".md5sums"))

@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
indirect=True)
def test_only_outputs_flag(create_package):
"""
Test if `--only-outputs` flag works.
"""
simple_run(['--only-inputs'])
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
in1 = ins[0]
for file in ins[1:]:
os.unlink(file)
assert len(outs) == 0
def in_to_out(file):
return os.path.join(create_package, "out", os.path.basename(file).replace(".in", ".out"))

simple_run(["--only-outputs"])
ins = glob.glob(os.path.join(create_package, "in", "*.in"))
outs = glob.glob(os.path.join(create_package, "out", "*.out"))
assert len(ins) == 1
assert os.path.exists(in_to_out(in1))
assert len(outs) == 1


@pytest.mark.parametrize("create_package", [util.get_shell_ingen_pack_path(), util.get_simple_package_path()],
indirect=True)
def test_missing_output_files(create_package):
"""
Test if `ingen` command generates missing output files.
"""
package_path = create_package
for args in [[], ["--only-outputs"]]:
simple_run()
outs = glob.glob(os.path.join(package_path, "out", "*.out"))
os.unlink(outs[0])
assert not os.path.exists(outs[0])
simple_run(args)
assert os.path.exists(outs[0])
shutil.rmtree(paths.get_cache_path())
os.unlink(os.path.join(package_path, "in", ".md5sums"))

0 comments on commit 15a01c0

Please sign in to comment.