Generate rules instead of dependencies.

This allows the testrunner script to be eliminated, and on one of my
lower-spec machines this makes a significant difference because Python
startup can be slow, and it's now not necessary to invoke it for every
run.
This commit is contained in:
Simon Howard 2024-09-04 18:38:02 -04:00
parent 6744277d9b
commit 56b45289b9
6 changed files with 94 additions and 113 deletions

2
.gitignore vendored
View file

@ -1 +1 @@
.depends .rules

View file

@ -28,8 +28,8 @@ output/%.txt: demos/%.lmp $(SOURCE_PORT)
@mkdir -p $(dir $@) @mkdir -p $(dir $@)
@./testrunner $< $@ @./testrunner $< $@
.depends: makedepends .rules: makerules
./makedepends $@ ./makerules $@
extract/%: extract/%:
unzip $(UNZIPOPTS) -d extract $< $(notdir $@) unzip $(UNZIPOPTS) -d extract $< $(notdir $@)
@ -45,6 +45,6 @@ extract/class_ep.wad: pwads/class_ep.zip
clean: clean:
rm -f extract/*.wad rm -f extract/*.wad
rm -rf output/* rm -rf output/*
rm -f .depends rm -f .rules
include .depends include .rules

View file

@ -1,27 +0,0 @@
#
# Copyright (C) 2024 Simon Howard
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. This program is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
from os.path import dirname, join, exists
import yaml
def read_config(path):
if path == '':
return {}
# Config deeper in the hierarchy can override config files from
# higher up in the hierarchy:
result = read_config(dirname(path))
config_file = join(path, ".democonfig")
if exists(config_file):
with open(config_file) as f:
result.update(yaml.safe_load(f))
return result

View file

@ -1,41 +0,0 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 Simon Howard
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. This program is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
from glob import glob
import os
from os.path import exists, join
import sys
from common import *
depends_file = sys.argv[1]
dependencies = {}
for filename in glob("expected/**/*.txt", recursive=True):
lmp_file = filename.replace("expected/", "demos/").replace(".txt", ".lmp")
cfg = read_config(lmp_file)
depends = [join("iwads", cfg["iwad"])]
pwad = cfg.get("pwad")
if pwad is not None:
depends.append(os.path.join("extract", pwad))
out_file = filename.replace("expected/", "output/")
dependencies[out_file] = depends
with open(depends_file, "w") as f:
for out_file, depends in sorted(dependencies.items()):
out_file = out_file.replace("#", "\\#")
f.write("%s: %s\n" % (
out_file, " ".join(depends),
))

89
makerules Executable file
View file

@ -0,0 +1,89 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 Simon Howard
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. This program is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
from glob import glob
import os
from os.path import dirname, basename, exists, join
import shlex
import sys
import yaml
def escape_filename(filename):
return filename.replace("#", "\\#")
def read_config(path):
if path == '':
return {}
# Config deeper in the hierarchy can override config files from
# higher up in the hierarchy:
result = read_config(dirname(path))
config_file = join(path, ".democonfig")
if exists(config_file):
with open(config_file) as f:
result.update(yaml.safe_load(f))
return result
class Rule:
def __init__(self, expect_file):
self.out_file = expect_file.replace("expected/", "output/")
self.lmp_file = (
expect_file.replace("expected/", "demos/")
.replace(".txt", ".lmp"))
self.cfg = read_config(self.lmp_file)
def dependencies(self):
yield self.lmp_file
yield "$(SOURCE_PORT)"
yield join("iwads", self.cfg["iwad"])
pwad = self.cfg.get("pwad")
if pwad is not None:
yield join("extract", pwad)
def game_arguments(self):
result = [
"$(DOOMOPTS)",
"-statdump", "$@",
"-iwad", join("iwads", self.cfg["iwad"]),
"-timedemo", "$<"
]
if "gameversion" in self.cfg:
result.extend(("-gameversion", self.cfg["gameversion"]))
if "pwad" in self.cfg:
result.extend(("-file", join("extract", self.cfg["pwad"])))
return result
def command(self):
args = self.game_arguments()
return "$(SOURCE_PORT) " + " ".join(args) + " >/dev/null 2>&1"
def rule_output(self):
result = "%s: %s\n" % (
escape_filename(self.out_file), " ".join(
escape_filename(f) for f in self.dependencies()),
)
result += "\t@mkdir -p %s\n" % (shlex.quote(dirname(self.out_file)))
result += "\t%s || true\n\n" % self.command()
return result
depends_file = sys.argv[1]
rules = []
with open(depends_file, "w") as f:
for filename in sorted(glob("expected/**/*.txt", recursive=True)):
r = Rule(filename)
f.write(r.rule_output())

View file

@ -1,40 +0,0 @@
#!/usr/bin/env python3
#
# Copyright (C) 2024 Simon Howard
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. This program is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
import os
from os.path import join
import shlex
import sys
from common import *
source_port = os.getenv("SOURCE_PORT")
assert source_port != "", "SOURCE_PORT environment variable not set."
lmp_file, out_file = sys.argv[1:]
cfg = read_config(lmp_file)
args = [
source_port,
"-iwad", join("iwads", cfg["iwad"]),
"-statdump", out_file,
"-timedemo", lmp_file,
] + shlex.split(os.getenv("DOOMOPTS", ""))
if "gameversion" in cfg:
args.extend(("-gameversion", cfg["gameversion"]))
if "pwad" in cfg:
args.extend(("-file", join("extract", cfg["pwad"])))
command = shlex.join(args) + " >/dev/null 2>&1"
print(command)
os.system(command)