From d2e8430c49a7a89f55c6eec4de6833dbb8ad2995 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Sun, 17 Sep 2023 12:05:13 -0500 Subject: [PATCH] Check if the runtime is up to date on dev install --- scripts/checksum.py | 78 +++++++++++++++++++++++++++++++++++++++++++ scripts/dev.py | 30 +++++++++++++++++ scripts/source.py | 80 ++------------------------------------------- 3 files changed, 110 insertions(+), 78 deletions(-) diff --git a/scripts/checksum.py b/scripts/checksum.py index 972ce9a..6702d4e 100644 --- a/scripts/checksum.py +++ b/scripts/checksum.py @@ -1,5 +1,6 @@ import hashlib import json +import os from .log import * @@ -28,3 +29,80 @@ def checkfile(filepath): def filesum(filepath): with open(filepath, "rb") as file: return hashlib.sha256(file.read()).hexdigest() + + +# ----------------------------------------------------------------------------- +# Directory-hashing implementation pulled from the checksumdir package on pypi. +# Licensed under the MIT license. +# ----------------------------------------------------------------------------- + +def dirsum( + dirname, + hash_func=hashlib.sha1, + excluded_files=None, + ignore_hidden=False, + followlinks=False, + excluded_extensions=None, + include_paths=False +): + if not excluded_files: + excluded_files = [] + + if not excluded_extensions: + excluded_extensions = [] + + if not os.path.isdir(dirname): + raise TypeError("{} is not a directory.".format(dirname)) + + hashvalues = [] + for root, dirs, files in os.walk(dirname, topdown=True, followlinks=followlinks): + if ignore_hidden and re.search(r"/\.", root): + continue + + dirs.sort() + files.sort() + + for fname in files: + if ignore_hidden and fname.startswith("."): + continue + + if fname.split(".")[-1:][0] in excluded_extensions: + continue + + if fname in excluded_files: + continue + + hashvalues.append(_filehash(os.path.join(root, fname), hash_func)) + + if include_paths: + hasher = hash_func() + # get the resulting relative path into array of elements + path_list = os.path.relpath(os.path.join(root, fname)).split(os.sep) + # compute the hash on joined list, removes all os specific separators + hasher.update(''.join(path_list).encode('utf-8')) + hashvalues.append(hasher.hexdigest()) + + return _reduce_hash(hashvalues, hash_func) + + +def _filehash(filepath, hashfunc): + hasher = hashfunc() + blocksize = 64 * 1024 + + if not os.path.exists(filepath): + return hasher.hexdigest() + + with open(filepath, "rb") as fp: + while True: + data = fp.read(blocksize) + if not data: + break + hasher.update(data) + return hasher.hexdigest() + + +def _reduce_hash(hashlist, hashfunc): + hasher = hashfunc() + for hashvalue in sorted(hashlist): + hasher.update(hashvalue.encode("utf-8")) + return hasher.hexdigest() diff --git a/scripts/dev.py b/scripts/dev.py index 74f22cc..c71c934 100644 --- a/scripts/dev.py +++ b/scripts/dev.py @@ -8,6 +8,7 @@ from zipfile import ZipFile from . import checksum from .bindgen import bindgen +from .checksum import dirsum from .gles_gen import gles_gen from .log import * from .utils import pushd, removeall, yeetdir, yeetfile @@ -65,6 +66,21 @@ def build_runtime(args): build_wasm3(args.release) build_orca(args.release) + with open("build/orcaruntime.sum", "w") as f: + f.write(runtime_checksum()) + + +def runtime_checksum_last(): + try: + with open("build/orcaruntime.sum", "r") as f: + return f.read() + except FileNotFoundError: + return None + + +def runtime_checksum(): + return dirsum("src") + def clean(args): yeetdir("build") @@ -504,6 +520,20 @@ def install_dir(): def install(args): + if runtime_checksum_last() is None: + print("You must build the Orca runtime before you can install it to your") + print("system. Please run the following command first:") + print() + print("orca dev build-runtime") + exit(1) + + if runtime_checksum() != runtime_checksum_last(): + print("Your build of the Orca runtime is out of date. We recommend that you") + print("rebuild the runtime first with `orca dev build-runtime`.") + if not prompt("Do you wish to install the runtime anyway?"): + return + print() + dest = install_dir() bin_dir = os.path.join(dest, "bin") src_dir = os.path.join(dest, "src") diff --git a/scripts/source.py b/scripts/source.py index c73786e..f4170a6 100644 --- a/scripts/source.py +++ b/scripts/source.py @@ -4,6 +4,7 @@ import os import re import shutil +from .checksum import dirsum from .log import * from .utils import yeetdir from .version import src_dir, orca_version @@ -54,7 +55,7 @@ def vendor_file_path(vendor_dir): def vendor_checksum(dir): - return dirhash(dir, excluded_extensions=["orcavendor"]) + return dirsum(dir, excluded_extensions=["orcavendor"]) def cflags(args): @@ -110,80 +111,3 @@ def cflags(args): print("If these paths look crazy to you, consider vendoring the source code into your") print("project using `orca source vendor`.") print() - - -# ----------------------------------------------------------------------------- -# Directory-hashing implementation pulled from the checksumdir package on pypi. -# Licensed under the MIT license. -# ----------------------------------------------------------------------------- - -def dirhash( - dirname, - hash_func=hashlib.sha1, - excluded_files=None, - ignore_hidden=False, - followlinks=False, - excluded_extensions=None, - include_paths=False -): - if not excluded_files: - excluded_files = [] - - if not excluded_extensions: - excluded_extensions = [] - - if not os.path.isdir(dirname): - raise TypeError("{} is not a directory.".format(dirname)) - - hashvalues = [] - for root, dirs, files in os.walk(dirname, topdown=True, followlinks=followlinks): - if ignore_hidden and re.search(r"/\.", root): - continue - - dirs.sort() - files.sort() - - for fname in files: - if ignore_hidden and fname.startswith("."): - continue - - if fname.split(".")[-1:][0] in excluded_extensions: - continue - - if fname in excluded_files: - continue - - hashvalues.append(_filehash(os.path.join(root, fname), hash_func)) - - if include_paths: - hasher = hash_func() - # get the resulting relative path into array of elements - path_list = os.path.relpath(os.path.join(root, fname)).split(os.sep) - # compute the hash on joined list, removes all os specific separators - hasher.update(''.join(path_list).encode('utf-8')) - hashvalues.append(hasher.hexdigest()) - - return _reduce_hash(hashvalues, hash_func) - - -def _filehash(filepath, hashfunc): - hasher = hashfunc() - blocksize = 64 * 1024 - - if not os.path.exists(filepath): - return hasher.hexdigest() - - with open(filepath, "rb") as fp: - while True: - data = fp.read(blocksize) - if not data: - break - hasher.update(data) - return hasher.hexdigest() - - -def _reduce_hash(hashlist, hashfunc): - hasher = hashfunc() - for hashvalue in sorted(hashlist): - hasher.update(hashvalue.encode("utf-8")) - return hasher.hexdigest()