diff --git a/packager.py b/packager.py deleted file mode 100644 index 6a944a1..0000000 --- a/packager.py +++ /dev/null @@ -1,254 +0,0 @@ -import subprocess -import sys -import os -import platform -import hashlib -import click -import shutil -import toml -import hashlib -import glob -import urllib.request -from dataclasses import dataclass - -PACKAGER_TARGET_DIR = "target/packager" - -@dataclass -class PackageInfo: - name: str - version: str - description: str - publisher: str - url: str - modulo_version: str - -@click.group() -def cli(): - pass - -@cli.command() -@click.option('--skipcargo', default=False, is_flag=True, help="Skip cargo release build") -def build(skipcargo): - """Build espanso distribution""" - # Check operating system - TARGET_OS = "macos" - if platform.system() == "Windows": - TARGET_OS = "windows" - elif platform.system() == "Linux": - TARGET_OS = "linux" - - print("Detected OS:", TARGET_OS) - - print("Loading info from Cargo.toml") - cargo_info = toml.load("Cargo.toml") - package_info = PackageInfo(cargo_info["package"]["name"], - cargo_info["package"]["version"], - cargo_info["package"]["description"], - cargo_info["package"]["authors"][0], - cargo_info["package"]["homepage"], - cargo_info["modulo"]["version"]) - print(package_info) - - if not skipcargo: - print("Building release version...") - subprocess.run(["cargo", "build", "--release"]) - else: - print("Skipping build") - - if TARGET_OS == "windows": - build_windows(package_info) - elif TARGET_OS == "macos": - build_mac(package_info) - -def calculate_sha256(file): - with open(file, "rb") as f: - b = f.read() # read entire file as bytes - readable_hash = hashlib.sha256(b).hexdigest() - return readable_hash - -def build_windows(package_info): - print("Starting packaging process for Windows...") - - # Check Inno Setup - try: - subprocess.run(["iscc"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - except FileNotFoundError: - raise Exception("Could not find Inno Setup compiler. Please install it from here: http://www.jrsoftware.org/isdl.php") - - print("Clearing target dirs") - - # Clearing previous build directory - if os.path.isdir(PACKAGER_TARGET_DIR): - print("Cleaning packager temp directory...") - shutil.rmtree(PACKAGER_TARGET_DIR) - - TARGET_DIR = os.path.join(PACKAGER_TARGET_DIR, "win") - os.makedirs(TARGET_DIR, exist_ok=True) - - modulo_url = "https://github.com/federico-terzi/modulo/releases/download/v{0}/modulo-win.exe".format(package_info.modulo_version) - modulo_sha_url = "https://github.com/federico-terzi/modulo/releases/download/v{0}/modulo-win.exe.sha256.txt".format(package_info.modulo_version) - print("Pulling modulo depencency from:", modulo_url) - modulo_target_file = os.path.join(TARGET_DIR, "modulo.exe") - urllib.request.urlretrieve(modulo_url, modulo_target_file) - print("Pulling SHA signature from:", modulo_sha_url) - modulo_sha_file = os.path.join(TARGET_DIR, "modulo.sha256") - urllib.request.urlretrieve(modulo_sha_url, modulo_sha_file) - print("Checking signatures...") - expected_sha = None - with open(modulo_sha_file, "r") as sha_f: - expected_sha = sha_f.read() - actual_sha = calculate_sha256(modulo_target_file) - if actual_sha != expected_sha: - raise Exception("Modulo SHA256 is not matching") - - print("Gathering CRT DLLs...") - msvc_dirs = glob.glob("C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\*\\VC\\Redist\\MSVC\\*") - print("Found Redists: ", msvc_dirs) - - print("Determining best redist...") - - if len(msvc_dirs) == 0: - raise Exception("Cannot find redistributable dlls") - - msvc_dir = None - - for curr_dir in msvc_dirs: - dll_files = glob.glob(curr_dir + "\\x64\\*CRT\\*.dll") - print("Found dlls", dll_files, "in", curr_dir) - if any("vcruntime140_1.dll" in x.lower() for x in dll_files): - msvc_dir = curr_dir - break - - if msvc_dir is None: - raise Exception("Cannot find redist with VCRUNTIME140_1.dll") - - print("Using: ", msvc_dir) - - dll_files = glob.glob(msvc_dir + "\\x64\\*CRT\\*.dll") - - print("Found DLLs:") - include_list = [] - for dll in dll_files: - print("Including: "+dll) - include_list.append("Source: \""+dll+"\"; DestDir: \"{app}\"; Flags: ignoreversion") - - print("Including modulo") - include_list.append("Source: \""+os.path.abspath(modulo_target_file)+"\"; DestDir: \"{app}\"; Flags: ignoreversion") - - include = "\r\n".join(include_list) - - INSTALLER_NAME = f"espanso-win-installer" - - # Inno setup - shutil.copy("packager/win/modpath.iss", os.path.join(TARGET_DIR, "modpath.iss")) - - print("Processing inno setup template") - with open("packager/win/setupscript.iss", "r") as iss_script: - content = iss_script.read() - - # Replace variables - content = content.replace("{{{app_name}}}", package_info.name) - content = content.replace("{{{app_version}}}", package_info.version) - content = content.replace("{{{app_publisher}}}", package_info.publisher) - content = content.replace("{{{app_url}}}", package_info.url) - content = content.replace("{{{app_license}}}", os.path.abspath("LICENSE")) - content = content.replace("{{{app_icon}}}", os.path.abspath("packager/win/icon.ico")) - content = content.replace("{{{executable_path}}}", os.path.abspath("target/release/espanso.exe")) - content = content.replace("{{{output_dir}}}", os.path.abspath(TARGET_DIR)) - content = content.replace("{{{output_name}}}", INSTALLER_NAME) - content = content.replace("{{{dll_include}}}", include) - - with open(os.path.join(TARGET_DIR, "setupscript.iss"), "w") as output_script: - output_script.write(content) - - print("Compiling installer with Inno setup") - subprocess.run(["iscc", os.path.abspath(os.path.join(TARGET_DIR, "setupscript.iss"))]) - - print("Calculating the SHA256") - sha256_hash = hashlib.sha256() - with open(os.path.abspath(os.path.join(TARGET_DIR, INSTALLER_NAME+".exe")),"rb") as f: - # Read and update hash string value in blocks of 4K - for byte_block in iter(lambda: f.read(4096),b""): - sha256_hash.update(byte_block) - - hash_file = os.path.abspath(os.path.join(TARGET_DIR, "espanso-win-installer-sha256.txt")) - with open(hash_file, "w") as hf: - hf.write(sha256_hash.hexdigest()) - - -def build_mac(package_info): - print("Starting packaging process for MacOS...") - - print("Clearing target dirs") - - # Clearing previous build directory - if os.path.isdir(PACKAGER_TARGET_DIR): - print("Cleaning packager temp directory...") - shutil.rmtree(PACKAGER_TARGET_DIR) - - TARGET_DIR = os.path.join(PACKAGER_TARGET_DIR, "mac") - os.makedirs(TARGET_DIR, exist_ok=True) - - print("Compressing release to archive...") - target_name = f"espanso-mac.tar.gz" - archive_target = os.path.abspath(os.path.join(TARGET_DIR, target_name)) - subprocess.run(["tar", - "-C", os.path.abspath("target/release"), - "-cvf", - archive_target, - "espanso", - ]) - print(f"Created archive: {archive_target}") - - print("Calculating the SHA256") - sha256_hash = hashlib.sha256() - with open(archive_target,"rb") as f: - # Read and update hash string value in blocks of 4K - for byte_block in iter(lambda: f.read(4096),b""): - sha256_hash.update(byte_block) - - hash_file = os.path.abspath(os.path.join(TARGET_DIR, "espanso-mac-sha256.txt")) - with open(hash_file, "w") as hf: - hf.write(sha256_hash.hexdigest()) - - modulo_sha_url = "https://github.com/federico-terzi/modulo/releases/download/v{0}/modulo-mac.sha256.txt".format(package_info.modulo_version) - print("Pulling SHA signature from:", modulo_sha_url) - modulo_sha_file = os.path.join(TARGET_DIR, "modulo.sha256") - urllib.request.urlretrieve(modulo_sha_url, modulo_sha_file) - modulo_sha = None - with open(modulo_sha_file, "r") as sha_f: - modulo_sha = sha_f.read() - if modulo_sha is None: - raise Exception("Cannot determine modulo SHA") - - print("Processing Homebrew formula template") - with open("packager/mac/espanso.rb", "r") as formula_template: - content = formula_template.read() - - # Replace variables - content = content.replace("{{{app_desc}}}", package_info.description) - content = content.replace("{{{app_url}}}", package_info.url) - content = content.replace("{{{app_version}}}", package_info.version) - content = content.replace("{{{modulo_version}}}", package_info.modulo_version) - content = content.replace("{{{modulo_sha}}}", modulo_sha) - - # Calculate hash - with open(archive_target, "rb") as f: - bytes = f.read() - readable_hash = hashlib.sha256(bytes).hexdigest() - content = content.replace("{{{release_hash}}}", readable_hash) - - with open(os.path.join(TARGET_DIR, "espanso.rb"), "w") as output_script: - output_script.write(content) - - print("Done!") - - -if __name__ == '__main__': - print("[[ espanso packager ]]") - - # Check python version 3 - if sys.version_info[0] < 3: - raise Exception("Must be using Python 3") - - cli() \ No newline at end of file