Instead of recompiling all of lunch source for each game, we generate source files containing the `main` function and default configuration for every game instead.
138 lines
3.4 KiB
Python
138 lines
3.4 KiB
Python
import os
|
|
import shutil
|
|
import string
|
|
import subprocess
|
|
import configparser
|
|
|
|
pjoin = os.path.join
|
|
|
|
|
|
def read(filename: str) -> str:
|
|
with open(filename, "r") as file:
|
|
return file.read()
|
|
|
|
|
|
# Prepare `lunch` config template
|
|
config_template = string.Template(read("template.toml"))
|
|
|
|
# Prepare `lunch` config template
|
|
meson_template = string.Template(read("config/template.build"))
|
|
|
|
|
|
# Prepare games directory
|
|
if os.path.exists("games"):
|
|
shutil.rmtree("games")
|
|
os.mkdir("games")
|
|
with open("games/.gitignore", "w") as file:
|
|
file.write("*")
|
|
|
|
# Read config directory
|
|
games = []
|
|
for dirent in os.listdir("config"):
|
|
path = pjoin("config", dirent)
|
|
|
|
# If not a directory, skip
|
|
if not os.path.isdir(path):
|
|
continue
|
|
|
|
# Append game's name, and print it to the console
|
|
print(dirent)
|
|
games.append(dirent)
|
|
|
|
# Preprocess game config
|
|
config_source = ["[main]"] # Default section
|
|
for line in read(pjoin(path, "config.ini")).split("\n"):
|
|
line = line.strip()
|
|
|
|
# If line empty, skip
|
|
if len(line) == 0:
|
|
continue
|
|
|
|
# If key-value missing, set empty
|
|
if (line[0] != "[") and ("=" not in line):
|
|
line += "="
|
|
|
|
config_source.append(line)
|
|
config_source = "\n".join(config_source)
|
|
|
|
# Load game config
|
|
config = configparser.ConfigParser()
|
|
config.read_string(config_source)
|
|
|
|
# Prepare flat config
|
|
flat_config = {}
|
|
for key in config["main"].keys():
|
|
flat_config[key] = config["main"][key]
|
|
|
|
# Set defaults
|
|
def default(key, value):
|
|
if key not in flat_config:
|
|
flat_config[key] = value
|
|
|
|
default("name", dirent)
|
|
default("exec", dirent+".exe")
|
|
default("workdir", "")
|
|
|
|
# Replace slashes for paths
|
|
for key in ["exec", "workdir"]:
|
|
flat_config[key] = flat_config[key].replace("\\", "/")
|
|
|
|
# Add exclusions
|
|
if "exclude" in config:
|
|
flat_config["exclusions"] = list(config["exclude"].keys())
|
|
else:
|
|
flat_config["exclusions"] = []
|
|
|
|
# Prepare game directory
|
|
opath = pjoin("games", dirent)
|
|
os.mkdir(opath)
|
|
|
|
# Generate `lunch` config
|
|
with open(pjoin(opath, "config.toml"), "w") as file:
|
|
file.write(config_template.substitute(dict(flat_config)))
|
|
|
|
# Generate icon
|
|
icon_png = pjoin(path, "icon.png")
|
|
icon = pjoin(opath, "icon.ico")
|
|
subprocess.run([
|
|
"magick",
|
|
icon_png,
|
|
"-resize", "256x256",
|
|
"-define", "icon:auto-resize=256,128,96,64,48,32,16",
|
|
icon,
|
|
])
|
|
|
|
# Generate resource file
|
|
with open(pjoin(opath, "resource.rc"), "w") as file:
|
|
file.writelines([
|
|
"ICON\tICON\t\"icon.ico\""
|
|
])
|
|
|
|
# Generate source file
|
|
with open(pjoin(opath, "main.d"), "w") as file:
|
|
file.writelines([
|
|
"module main;\n",
|
|
"\n",
|
|
"import lunch.app;\n",
|
|
"\n",
|
|
"\n",
|
|
"void main()\n",
|
|
"{\n",
|
|
" app(import(\"config.toml\"));\n",
|
|
"}\n",
|
|
])
|
|
|
|
# Generate meson file
|
|
with open(pjoin(opath, "meson.build"), "w") as file:
|
|
file.write(meson_template.substitute(dict(flat_config)))
|
|
|
|
|
|
# Prepare meson configuration
|
|
mesontemplate = string.Template(read("config/meson.build"))
|
|
meson = {
|
|
"games": games
|
|
}
|
|
|
|
# Generate meson.build
|
|
with open("games/meson.build", "w") as file:
|
|
file.write(mesontemplate.substitute(meson)) |