cakefoot/src/release.py

185 lines
7.3 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 a given 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 sub-folders in the build folder are 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'")
parser.add_argument(
"--exclude",
nargs="*",
help="Platforms to exclude, one or more of 'wasm', 'linux', 'win64', 'win32', 'macos', 'ubuntu18', 'coolmath',"
" 'itch'")
arguments = parser.parse_args()
# WASM
if "wasm" not in arguments.exclude:
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}")
else:
print("Excluding WASM build based on configuration")
# Downloadable
distributions = {
"ubuntu18": ["linux", "zip"],
"win32": ["win32", "zip"],
"win64": ["win64", "zip"],
"macos": ["", "dmg"]
}
for platform, name in distributions.items():
if platform not in arguments.exclude:
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.")
else:
print(f"Excluding {platform} release based on configuration")
# WASM archives
for platform in ("coolmath", "itch"):
if platform not in arguments.exclude:
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}")
else:
print(f"Excluding {platform} release based on configuration")