Files
renpy/distribute.py

317 lines
8.3 KiB
Python
Executable File

#!/home/tom/ab/renpy/lib/py3-linux-x86_64/python
# Builds a distribution of Ren'Py.
from __future__ import division, absolute_import, with_statement, print_function, unicode_literals
import future.standard_library
import future.utils
PY2 = future.utils.PY2
import sys
import os
import compileall
import shutil
import subprocess
import argparse
import time
import collections
try:
from importlib import reload
except ImportError:
pass
ROOT = os.path.dirname(os.path.abspath(__file__))
def zip_rapt_symbols(destination):
"""
Zips up the rapt symbols.
"""
import zipfile
if PY2:
zf = zipfile.ZipFile(destination + "/android-native-symbols.zip", "w", zipfile.ZIP_DEFLATED)
else:
zf = zipfile.ZipFile(destination + "/android-native-symbols.zip", "w", zipfile.ZIP_DEFLATED, compresslevel=3)
for dn, dirs, files in os.walk("rapt/symbols"):
for fn in dirs + files:
fn = os.path.join(dn, fn)
arcname = os.path.relpath(fn, "rapt/symbols")
zf.write(fn, arcname)
zf.close()
def copy_tutorial_file(src, dest):
"""
Copies a file from src to dst. Lines between "# tutorial-only" and
"# end-tutorial-only" comments are omitted from the copy.
"""
# True if we want to copy the line.
copy = True
with open(src, "r") as sf, open(dest, "w") as df:
for l in sf:
if "# tutorial-only" in l:
copy = False
elif "# end-tutorial-only" in l:
copy = True
else:
if copy:
df.write(l)
def link_directory(dirname):
dn = os.path.join(ROOT, dirname)
if os.path.exists(dn):
os.unlink(dn)
if PY2:
source = dn + "2"
else:
source = dn + "3"
if os.path.exists(source):
os.symlink(source, dn)
def main():
start = time.time()
ap = argparse.ArgumentParser()
ap.add_argument("version", nargs="?")
ap.add_argument("--fast", action="store_true")
ap.add_argument("--pygame", action="store", default=None)
ap.add_argument("--no-rapt", action="store_true")
ap.add_argument("--variant", action="store")
ap.add_argument("--sign", action="store_true", default=True)
ap.add_argument("--nosign", action="store_false", dest="sign")
ap.add_argument("--notarized", action="store_true", dest="notarized")
ap.add_argument("--vc-version-only", action="store_true")
ap.add_argument("--link-directories", action="store_true")
ap.add_argument("--append-version", action="store_true")
ap.add_argument("--nightly", action="store_true")
ap.add_argument("--print-version", action="store_true")
args = ap.parse_args()
link_directory("rapt")
link_directory("renios")
link_directory("web")
import renpy.versions
renpy.versions.generate_vc_version(nightly=args.nightly)
if args.link_directories or args.vc_version_only:
return
if not os.path.abspath(sys.executable).startswith(ROOT + "/lib"):
raise Exception("Distribute must be run with the python in lib/.")
if args.sign:
os.environ["RENPY_MAC_IDENTITY"] = "Developer ID Application: Tom Rothamel (XHTE5H7Z79)"
if PY2 and not sys.flags.optimize:
raise Exception("Not running with python optimization.")
try:
vc_version_base = os.path.splitext(renpy.vc_version.__file__)[0]
# Delete the .pyc and .pyo files, as reload can choose one of them instead
# of the new .py file.
for fn in [ vc_version_base + ".pyc", vc_version_base + ".pyo" ]:
if os.path.exists(fn):
os.unlink(fn)
reload(renpy.vc_version)
except Exception:
import renpy.vc_version
# A normal reload is fine, as renpy/__init__.py won't change.
reload(renpy)
if args.print_version:
print(renpy.version_only)
return
if args.version is None:
if args.nightly:
args.version = renpy.version_only
else:
args.version = ".".join(str(i) for i in renpy.version_tuple[:-1])
if args.append_version:
args.version += "-" + renpy.version_only
# Check that the versions match.
full_version = renpy.version_only # @UndefinedVariable
if "-" not in args.version \
and not full_version.startswith(args.version):
raise Exception("The command-line and Ren'Py versions do not match.")
os.environ['RENPY_BUILD_VERSION'] = args.version
# The destination directory.
destination = os.path.join("dl", args.version)
if args.variant:
destination += "-" + args.variant
if os.path.exists(os.path.join(destination, "checksums.txt")):
raise Exception("The checksums.txt file exists.")
print("Version {} ({})".format(args.version, full_version))
if sys.version_info[0] >= 3:
renpy_sh = "./renpy3.sh"
else:
renpy_sh = "./renpy2.sh"
# Compile all the python files.
compileall.compile_dir("renpy/", ddir="renpy/", force=True, quiet=1)
# Compile the various games.
if not args.fast:
for i in [ 'tutorial', 'launcher', 'the_question' ]:
print("Compiling", i)
subprocess.check_call([renpy_sh, i, "compile" ])
# Kick off the rapt build.
if not args.fast:
print("Cleaning RAPT.")
sys.path.insert(0, os.path.join(ROOT, "rapt", "buildlib"))
import rapt.interface # type: ignore
import rapt.build # type: ignore
interface = rapt.interface.Interface()
rapt.build.distclean(interface)
print("Compiling RAPT and renios.")
compileall.compile_dir("rapt/buildlib/", ddir="rapt/buildlib/", quiet=1)
compileall.compile_dir("renios/buildlib/", ddir="renios/buildlib/", quiet=1)
if not os.path.exists(destination):
os.makedirs(destination)
zip_rapt_symbols(destination)
if args.fast:
cmd = [
renpy_sh,
"launcher",
"distribute",
"launcher",
"--package",
"sdk",
"--destination",
destination,
"--no-update",
]
else:
cmd = [
renpy_sh,
"launcher",
"distribute",
"launcher",
"--destination",
destination,
]
if args.notarized:
cmd.extend([
"--macapp",
"notarized/out",
])
print()
subprocess.check_call(cmd)
# Sign the update.
if not args.fast:
subprocess.check_call([
"scripts/sign_update.py",
"/home/tom/ab/keys/renpy_private.pem",
os.path.join(destination, "updates.json"),
])
# Package pygame_sdl2.
if not args.fast:
subprocess.check_call([
"pygame_sdl2/setup.py",
"-q",
"egg_info",
"--tag-build",
"+renpy" + args.version.replace("+", "-"),
"sdist",
"-d",
os.path.abspath(destination)
])
# Write 7z.exe.
sdk = "renpy-{}-sdk".format(args.version)
if not args.fast:
# shutil.copy("renpy-ppc.zip", os.path.join(destination, "renpy-ppc.zip"))
with open("7z.sfx", "rb") as f:
sfx = f.read()
os.chdir(destination)
if os.path.exists(sdk):
shutil.rmtree(sdk)
subprocess.check_call([ "unzip", "-q", sdk + ".zip" ])
if os.path.exists(sdk + ".7z"):
os.unlink(sdk + ".7z")
sys.stdout.write("Creating -sdk.7z")
p = subprocess.Popen([ "7z", "a", sdk + ".7z", sdk], stdout=subprocess.PIPE)
for i, _l in enumerate(p.stdout): # type: ignore
if i % 10 != 0:
continue
sys.stdout.write(".")
sys.stdout.flush()
if p.wait() != 0:
raise Exception("7z failed")
with open(sdk + ".7z", "rb") as f:
data = f.read()
with open(sdk + ".7z.exe", "wb") as f:
f.write(sfx)
f.write(data)
os.unlink(sdk + ".7z")
shutil.rmtree(sdk)
else:
os.chdir(destination)
if os.path.exists(sdk + ".7z.exe"):
os.unlink(sdk + ".7z.exe")
print()
print("Distribute took {:.0f} seconds.".format(time.time() - start))
if __name__ == "__main__":
main()