diff --git a/scripts/prebuild.py b/scripts/prebuild.py new file mode 100644 index 0000000..239cfbb --- /dev/null +++ b/scripts/prebuild.py @@ -0,0 +1,81 @@ +import os +import requests +import subprocess +import tarfile + +from pathlib import Path +from urllib.parse import unquote + +BUILD = "3.13.9" +DATE = "20251014" +CPYTHON_BUILD = f"cpython-{BUILD}" + +root = Path(__file__).resolve().parents[1] +build_dir = root.joinpath("build") +cpython_dir = build_dir.joinpath(CPYTHON_BUILD) + + +def fetch(url: str, destination: str) -> None: + print(f"Fetching URL '{url}'") + res = requests.get(url) + code = res.status_code + if code != 200: + raise Exception(f"URL '{url}' returned status code {code}") + with open(build_dir.joinpath(destination), "wb") as f: + f.write(res.content) + + +def get_cpython() -> None: + source = f"https://github.com/astral-sh/python-build-standalone/releases/download/{DATE}/" + build = f"{CPYTHON_BUILD}%2B{DATE}-x86_64_v3-unknown-linux-gnu-install_only_stripped.tar.gz" + url = f"{source}{build}" + outfile = unquote(build) + fetch(url, outfile) + version = build.split("%")[0] + untar(outfile, "python", version) + + +def get_pyapp() -> None: + url = "https://github.com/ofek/pyapp/releases/latest/download/source.tar.gz" + outfile = "pyapp-latest.tar.gz" + fetch(url, outfile) + untar(outfile, "pyapp-*", "pyapp-latest") + + +def untar(file: str, glob: str, renamed: str) -> None: + full_path = build_dir.joinpath(file) + with tarfile.open(full_path, "r:gz") as tar: + tar.extractall(path=build_dir) + full_path.unlink() + for _dir in build_dir.glob(glob): + os.rename(_dir, build_dir.joinpath(renamed)) + + +def install_deps() -> None: + pip = build_dir.joinpath(f"{CPYTHON_BUILD}/bin/pip") + subprocess.run([pip, "install", root]) + + +def repackage() -> None: + print("Preparing tar archive...") + outfile = build_dir.joinpath("airgapped.tar.gz") + with tarfile.open(outfile, "w:gz") as tar: + tar.add(build_dir.joinpath(CPYTHON_BUILD), arcname="python") + + +def rebuild_cpython() -> None: + if cpython_dir.is_dir() is False: + get_cpython() + install_deps() + repackage() + return get_packaged_version() + + +def get_packaged_version() -> str: + proc = subprocess.run( + [cpython_dir.joinpath("bin/dzgui"), "-v"], + capture_output=True, + text=True, + check=True, + ) + return proc.stdout.rstrip() diff --git a/scripts/release.py b/scripts/release.py index ae34d65..c80315e 100644 --- a/scripts/release.py +++ b/scripts/release.py @@ -5,11 +5,12 @@ import tarfile from pathlib import Path +from prebuild import get_pyapp, rebuild_cpython + + root = Path(__file__).resolve().parents[1] output = root.joinpath("dist") - -pyapp_dir = root.joinpath("pyapp-latest") -cpython = root.joinpath("build/cpython/airgapped.tar.gz") +build_dir = root.joinpath("build") builder = build.ProjectBuilder(root) wheel = builder.build("wheel", output_directory=output) @@ -20,8 +21,15 @@ metadata = stem.split("-") appname = metadata[0] version = metadata[1] -entrypoint = "dzgui.main:main" +pyapp_dir = build_dir.joinpath("pyapp-latest") +if pyapp_dir.is_dir() is False: + get_pyapp() +packaged_version = rebuild_cpython() +assert packaged_version == version +cpython = build_dir.joinpath("airgapped.tar.gz") + +entrypoint = "dzgui.main:main" env = os.environ env["PYAPP_PROJECT_VERSION"] = version env["PYAPP_PROJECT_NAME"] = appname @@ -38,7 +46,7 @@ env["PYAPP_DISTRIBUTION_PYTHON_PATH"] = "python/bin/python3" proc = subprocess.run(["cargo", "build", "--release"], env=env, cwd=pyapp_dir) if proc.returncode == 0: - output_exe = root.joinpath("pyapp-latest/target/release/pyapp") + output_exe = build_dir.joinpath("pyapp-latest/target/release/pyapp") release_exe = output.joinpath(appname) output_exe.rename(release_exe) tarpath = output.joinpath(tarname)