cakefoot/src/release.py
Cocktail Frank 67af1dd191 Add automatic web updates to arcade cabinet build
Add a Python script that checks a configured URL for the latest arcade
cabinet build available. Run the script during the game's construction.
If a new version is downloaded and installed successfully, quit the
game automatically before it runs so the newly installed version can be
launched.

Add update configuration parameters to the arcade cabinet config file.

Add a new target to the Makefile for the Linux arcade cabinet build.

Update the arcade cabinet daemon service file so that it registers when
the symlink changes target.
2025-02-27 03:08:35 -05:00

170 lines
6.4 KiB
Python

# /~@~@~@ C A K E F O O T <presented by> 💫dank.game💫
# |~)~)~)
# |\~*~*| Licensed under the zlib and CC-BY licenses. Source available for modding at
# |\\~*~|
# ,~|#\\~*|~, <https://open.shampoo.ooo/shampoo/cakefoot>
# : \\@\\~| :
# : \\#\\| : Created with SPACE🪐BOX engine for cross-platform, PC, web and mobile games
# : \\@\' :
# : \\/ : <https://open.shampoo.ooo/shampoo/spacebox>
# `~ ~ ~`~ */
#
# This script is used to add new releases to the distributions folder. The distributions folder is a separate
# folder from the builds folder where specific versions of builds are "frozen" to an arbitrary tag or release,
# like "Cakefoot-linux-1.0.4.zip".
#
# The builds in the given folder (default: build/) are copied to the distribution folder (default: dist/),
# with a given tag appended to the file (or folder) name.
#
# Currently, the build folder is expected to conform to a strict, undocumented structure :) that aligns with the
# build targets in the Makefile
import argparse
import subprocess
import pathlib
import os
import shutil
import glob
def force_link(target, link_path, target_is_directory=False):
"""
Make a symlink to the given target at the given path. If the path already exists, remove the link first, and then
create it (effectively forcing the link).
@param target path to link to
@param link_path link path on the filesystem which will link to target
@param target_is_directory True if the target is a directory, False otherwise
"""
try:
os.remove(link_path)
except:
pass
os.symlink(target, link_path, target_is_directory)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Copy current builds in the build directory into dist for release, with a given tag applied.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
"tag",
help="The tag to be appended to the file name, for example, '1.1.5'.")
parser.add_argument(
"--build",
type=pathlib.Path, default=pathlib.Path("build/"),
help="The location of per-platform builds")
parser.add_argument(
"--dist",
type=pathlib.Path,
default=pathlib.Path("dist/"),
help="The location where distributable builds are kept")
parser.add_argument(
"--project",
default="Cakefoot",
help="This project name will be prepended to the dist archive files")
parser.add_argument(
"--unprotected",
action="store_true",
help="Unless this flag is passed, non-WASM builds will be copied to a folder in dist named 'protected'")
arguments = parser.parse_args()
# WASM
wasm_build_dir = arguments.build / "wasm"
if wasm_build_dir.exists():
source_paths = glob.glob(str(wasm_build_dir / "Cakefoot.*"))
if source_paths:
wasm_dist_name = f"wasm-{arguments.tag}"
wasm_dist_dir = arguments.dist / wasm_dist_name
os.makedirs(wasm_dist_dir, mode=0o755, exist_ok=True)
for path in source_paths:
go_for_it = True
if (wasm_dist_dir / os.path.basename(path)).exists():
response = input(f"Replace existing file at {wasm_dist_dir / path}? [y/n]: ")
if response.lower() != "y":
go_for_it = False
if go_for_it:
shutil.copy(path, wasm_dist_dir)
print(f"Copied {path} to {wasm_dist_dir}")
wasm_link = arguments.dist / "wasm"
go_for_it = True
response = input(f"Replace existing link at {wasm_link}? [y/n]: ")
if response.lower() != "y":
go_for_it = False
if go_for_it:
force_link(wasm_dist_name, wasm_link, True)
print(f"Linked {wasm_link} to {wasm_dist_dir}")
else:
print(f"Error: no files to copy in {wasm_build_dir}")
else:
print(f"Error: no build directory found at {wasm_build_dir}")
# Downloadable
distributions = {
"ubuntu18": ["linux", "zip"],
"win32": ["win32", "zip"],
"win64": ["win64", "zip"],
"macos": ["", "dmg"]
}
for platform, name in distributions.items():
build_name = arguments.project
if name[0]:
build_name += f"-{name[0]}"
build_name += f".{name[1]}"
dist_dir = arguments.dist
if not arguments.unprotected:
dist_dir /= "protected"
dist_name = arguments.project
if name[0]:
dist_name += f"-{name[0]}"
link_name = dist_name
dist_name += f"-{arguments.tag}.{name[1]}"
link_name += f".{name[1]}"
source = arguments.build / platform / build_name
if source.exists():
destination = dist_dir / dist_name
go_for_it = True
if destination.exists():
response = input(f"Replace existing file at {destination}? [y/n]: ")
if response.lower() != "y":
go_for_it = False
if go_for_it:
shutil.copy(source, destination)
print(f"Copied {source} to {destination}")
link_path = dist_dir / link_name
go_for_it = True
if link_path.exists():
response = input(f"Replace existing link at {link_path}? [y/n]: ")
if response.lower() != "y":
go_for_it = False
if go_for_it:
force_link(dist_name, link_path)
print(f"Linked {link_path} to {destination}")
else:
print(f"Error: {platform} build {source} is missing.")
# WASM archives
for platform in ("coolmath", "itch"):
build_path = arguments.build / f"wasm_{platform}" / f"{arguments.project}_{platform}.zip"
if build_path.exists():
dist_path = arguments.dist / f"{arguments.project}_{platform}-{arguments.tag}.zip"
go_for_it = True
if dist_path.exists():
response = input(f"Replace existing file at {dist_path}? [y/n]: ")
if response.lower() != "y":
go_for_it = False
if go_for_it:
shutil.copy(build_path, dist_path)
print(f"Copied {build_path} to {dist_path}")
else:
print("Error: {platform} build file is missing at {build_path}")