mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-17 02:45:05 +00:00
99 lines
3.6 KiB
Python
Executable File
99 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# License: Apache License v2
|
|
"""Downloads the installed platforms of the selected SDK again when the CDN has a newer build of it. Run it as "tt update-sdk"."""
|
|
|
|
import io
|
|
import json
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import urllib.request
|
|
import zipfile
|
|
|
|
CDN_URL = os.environ.get("TT_CDN", "https://cdn.tactilityproject.org")
|
|
|
|
|
|
def fail(message):
|
|
print(f"tt update-sdk: {message}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def fetch(url):
|
|
request = urllib.request.Request(url, headers={"User-Agent": "tt update-sdk"})
|
|
try:
|
|
with urllib.request.urlopen(request, timeout=30) as response:
|
|
return response.read()
|
|
except OSError as error:
|
|
fail(f"failed to download {url}: {error}")
|
|
|
|
|
|
def read_commit(platform_directory):
|
|
try:
|
|
with open(os.path.join(platform_directory, "commit")) as file:
|
|
return file.read().strip()
|
|
except OSError:
|
|
return None
|
|
|
|
|
|
def installed_platforms(version_directory):
|
|
prefix = "platform-"
|
|
return sorted(
|
|
name[len(prefix):] for name in os.listdir(version_directory)
|
|
if name.startswith(prefix) and os.path.isdir(os.path.join(version_directory, name, "TactilitySDK"))
|
|
)
|
|
|
|
|
|
def install_platform(platform_directory, archive_data, commit):
|
|
"""Extracts next to the installed SDK and then replaces it, refusing entries outside of it"""
|
|
staging_directory = os.path.join(platform_directory, "TactilitySDK.new")
|
|
shutil.rmtree(staging_directory, ignore_errors=True)
|
|
os.makedirs(staging_directory)
|
|
root = os.path.realpath(staging_directory)
|
|
try:
|
|
with zipfile.ZipFile(io.BytesIO(archive_data)) as archive:
|
|
for member in archive.infolist():
|
|
destination = os.path.realpath(os.path.join(root, member.filename))
|
|
if not destination.startswith(root + os.sep):
|
|
fail(f"invalid entry in the SDK archive: {member.filename}")
|
|
archive.extractall(root)
|
|
except zipfile.BadZipFile:
|
|
shutil.rmtree(staging_directory, ignore_errors=True)
|
|
fail("the downloaded SDK archive is invalid")
|
|
sdk_directory = os.path.join(platform_directory, "TactilitySDK")
|
|
shutil.rmtree(sdk_directory, ignore_errors=True)
|
|
os.replace(staging_directory, sdk_directory)
|
|
with open(os.path.join(platform_directory, "commit"), "w") as file:
|
|
file.write(commit)
|
|
|
|
|
|
def main():
|
|
version = os.environ.get("TACTILITY_SDK_VERSION")
|
|
sdk_path = os.environ.get("TACTILITY_SDK_PATH")
|
|
if version is None or sdk_path is None:
|
|
fail("run this tool as 'tt update-sdk'")
|
|
version_directory = os.path.join(sdk_path, "sdk", version)
|
|
if os.environ.get("TT_LOCAL") == "1":
|
|
fail("a local SDK can't be updated")
|
|
index_data = fetch(f"{CDN_URL}/sdk/{version}/index.json")
|
|
try:
|
|
index = json.loads(index_data)
|
|
except ValueError:
|
|
fail("the downloaded index.json is invalid")
|
|
commit = index.get("gitCommit", "")
|
|
available = index.get("platforms", {})
|
|
updated = False
|
|
for platform in installed_platforms(version_directory):
|
|
platform_directory = os.path.join(version_directory, f"platform-{platform}")
|
|
if read_commit(platform_directory) == commit or platform not in available:
|
|
continue
|
|
print(f"Updating SDK {version} for {platform}")
|
|
install_platform(platform_directory, fetch(f"{CDN_URL}/sdk/{version}/{available[platform]}"), commit)
|
|
updated = True
|
|
with open(os.path.join(version_directory, "index.json"), "wb") as file:
|
|
file.write(index_data)
|
|
print(f"SDK {version} was updated" if updated else f"SDK {version} is up to date")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|