at 25.11-pre 6.8 kB view raw
1#! /usr/bin/env nix-shell 2#! nix-shell -i python -p python3.pkgs.click python3.pkgs.click-log nix 3""" 4electron updater 5 6A script for updating binary hashes. 7 8It supports the following modes: 9 10| Mode | Description | 11|------------- | ----------------------------------------------- | 12| `update` | for updating a specific Electron release | 13| `update-all` | for updating all electron releases at once | 14 15The `update` command requires a `--version` flag 16to specify the major release to be update. 17The `update-all` command updates all non-eol major releases. 18 19The `update` and `update-all` commands accept an optional `--commit` 20flag to automatically commit the changes for you. 21""" 22import logging 23import os 24import subprocess 25import sys 26import click 27import click_log 28 29from typing import Tuple 30os.chdir(os.path.dirname(__file__)) 31sys.path.append("..") 32from update_util import * 33 34 35# Relatice path to the electron-bin info.json 36BINARY_INFO_JSON = "info.json" 37 38# Relative path the the electron-chromedriver info.json 39CHROMEDRIVER_INFO_JSON = "../chromedriver/info.json" 40 41logger = logging.getLogger(__name__) 42click_log.basic_config(logger) 43 44 45systems = { 46 "i686-linux": "linux-ia32", 47 "x86_64-linux": "linux-x64", 48 "armv7l-linux": "linux-armv7l", 49 "aarch64-linux": "linux-arm64", 50 "x86_64-darwin": "darwin-x64", 51 "aarch64-darwin": "darwin-arm64", 52} 53 54def get_shasums256(version: str) -> list: 55 """Returns the contents of SHASUMS256.txt""" 56 try: 57 called_process: subprocess.CompletedProcess = subprocess.run( 58 [ 59 "nix-prefetch-url", 60 "--print-path", 61 f"https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt", 62 ], 63 capture_output=True, 64 check=True, 65 text=True, 66 ) 67 68 hash_file_path = called_process.stdout.split("\n")[1] 69 70 with open(hash_file_path, "r") as f: 71 return f.read().split("\n") 72 73 except subprocess.CalledProcessError as err: 74 print(err.stderr) 75 sys.exit(1) 76 77 78def get_headers(version: str) -> str: 79 """Returns the hash of the release headers tarball""" 80 try: 81 called_process: subprocess.CompletedProcess = subprocess.run( 82 [ 83 "nix-prefetch-url", 84 "--unpack", 85 f"https://artifacts.electronjs.org/headers/dist/v{version}/node-v{version}-headers.tar.gz", 86 ], 87 capture_output=True, 88 check=True, 89 text=True, 90 ) 91 return called_process.stdout.split("\n")[0] 92 except subprocess.CalledProcessError as err: 93 print(err.stderr) 94 sys.exit(1) 95 96 97def get_electron_hashes(major_version: str) -> dict: 98 """Returns a dictionary of hashes for a given major version""" 99 m, _ = get_latest_version(major_version) 100 version: str = m["version"] 101 102 out = {} 103 out[major_version] = { 104 "hashes": {}, 105 "version": version, 106 } 107 108 hashes: list = get_shasums256(version) 109 110 for nix_system, electron_system in systems.items(): 111 filename = f"*electron-v{version}-{electron_system}.zip" 112 if any([x.endswith(filename) for x in hashes]): 113 out[major_version]["hashes"][nix_system] = [ 114 x.split(" ")[0] for x in hashes if x.endswith(filename) 115 ][0] 116 out[major_version]["hashes"]["headers"] = get_headers(version) 117 118 return out 119 120 121def get_chromedriver_hashes(major_version: str) -> dict: 122 """Returns a dictionary of hashes for a given major version""" 123 m, _ = get_latest_version(major_version) 124 version: str = m["version"] 125 126 out = {} 127 out[major_version] = { 128 "hashes": {}, 129 "version": version, 130 } 131 132 hashes: list = get_shasums256(version) 133 134 for nix_system, electron_system in systems.items(): 135 filename = f"*chromedriver-v{version}-{electron_system}.zip" 136 if any([x.endswith(filename) for x in hashes]): 137 out[major_version]["hashes"][nix_system] = [ 138 x.split(" ")[0] for x in hashes if x.endswith(filename) 139 ][0] 140 out[major_version]["hashes"]["headers"] = get_headers(version) 141 142 return out 143 144 145def update_binary(major_version: str, commit: bool, chromedriver: bool) -> None: 146 """Update a given electron-bin or chromedriver release 147 148 Args: 149 major_version: The major version number, e.g. '27' 150 commit: Whether the updater should commit the result 151 """ 152 if chromedriver: 153 json_path=CHROMEDRIVER_INFO_JSON 154 package_name = f"electron-chromedriver_{major_version}" 155 update_fn=get_chromedriver_hashes 156 else: 157 json_path=BINARY_INFO_JSON 158 package_name = f"electron_{major_version}-bin" 159 update_fn = get_electron_hashes 160 print(f"Updating {package_name}") 161 162 old_info = load_info_json(json_path) 163 new_info = update_fn(major_version) 164 165 out = old_info | new_info 166 167 save_info_json(json_path, out) 168 169 old_version = ( 170 old_info[major_version]["version"] if major_version in old_info else None 171 ) 172 new_version = new_info[major_version]["version"] 173 if old_version == new_version: 174 print(f"{package_name} is up-to-date") 175 elif commit: 176 commit_result(package_name, old_version, new_version, json_path) 177 178 179@click.group() 180def cli() -> None: 181 """A script for updating electron-bin and chromedriver hashes""" 182 pass 183 184 185@cli.command("update-chromedriver", help="Update a single major release") 186@click.option("-v", "--version", help="The major version, e.g. '23'") 187@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result") 188def update_chromedriver(version: str, commit: bool) -> None: 189 update_binary(version, commit, True) 190 191 192@cli.command("update", help="Update a single major release") 193@click.option("-v", "--version", required=True, type=str, help="The major version, e.g. '23'") 194@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result") 195def update(version: str, commit: bool) -> None: 196 update_binary(version, commit, False) 197 update_binary(version, commit, True) 198 199 200@cli.command("update-all", help="Update all releases at once") 201@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result") 202def update_all(commit: bool) -> None: 203 # Filter out releases that have reached end-of-life 204 filtered_bin_info = dict( 205 filter( 206 lambda entry: int(entry[0]) in supported_version_range(), 207 load_info_json(BINARY_INFO_JSON).items(), 208 ) 209 ) 210 211 for major_version, _ in filtered_bin_info.items(): 212 update_binary(str(major_version), commit, False) 213 update_binary(str(major_version), commit, True) 214 215 216if __name__ == "__main__": 217 cli()