218 lines
6.7 KiB
Python
Executable File
218 lines
6.7 KiB
Python
Executable File
#! /usr/bin/env nix-shell
|
|
#! nix-shell -i python -p python3.pkgs.click python3.pkgs.click-log nix
|
|
"""
|
|
electron updater
|
|
|
|
A script for updating binary hashes.
|
|
|
|
It supports the following modes:
|
|
|
|
| Mode | Description |
|
|
|------------- | ----------------------------------------------- |
|
|
| `update` | for updating a specific Electron release |
|
|
| `update-all` | for updating all electron releases at once |
|
|
|
|
The `update` command requires a `--version` flag
|
|
to specify the major release to be update.
|
|
The `update-all` command updates all non-eol major releases.
|
|
|
|
The `update` and `update-all` commands accept an optional `--commit`
|
|
flag to automatically commit the changes for you.
|
|
"""
|
|
import logging
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import click
|
|
import click_log
|
|
|
|
from typing import Tuple
|
|
os.chdir(os.path.dirname(__file__))
|
|
sys.path.append("..")
|
|
from update_util import *
|
|
|
|
|
|
# Relatice path to the electron-bin info.json
|
|
BINARY_INFO_JSON = "info.json"
|
|
|
|
# Relative path the the electron-chromedriver info.json
|
|
CHROMEDRIVER_INFO_JSON = "../chromedriver/info.json"
|
|
|
|
logger = logging.getLogger(__name__)
|
|
click_log.basic_config(logger)
|
|
|
|
|
|
systems = {
|
|
"i686-linux": "linux-ia32",
|
|
"x86_64-linux": "linux-x64",
|
|
"armv7l-linux": "linux-armv7l",
|
|
"aarch64-linux": "linux-arm64",
|
|
"x86_64-darwin": "darwin-x64",
|
|
"aarch64-darwin": "darwin-arm64",
|
|
}
|
|
|
|
def get_shasums256(version: str) -> list:
|
|
"""Returns the contents of SHASUMS256.txt"""
|
|
try:
|
|
called_process: subprocess.CompletedProcess = subprocess.run(
|
|
[
|
|
"nix-prefetch-url",
|
|
"--print-path",
|
|
f"https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt",
|
|
],
|
|
capture_output=True,
|
|
check=True,
|
|
text=True,
|
|
)
|
|
|
|
hash_file_path = called_process.stdout.split("\n")[1]
|
|
|
|
with open(hash_file_path, "r") as f:
|
|
return f.read().split("\n")
|
|
|
|
except subprocess.CalledProcessError as err:
|
|
print(err.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def get_headers(version: str) -> str:
|
|
"""Returns the hash of the release headers tarball"""
|
|
try:
|
|
called_process: subprocess.CompletedProcess = subprocess.run(
|
|
[
|
|
"nix-prefetch-url",
|
|
"--unpack",
|
|
f"https://artifacts.electronjs.org/headers/dist/v{version}/node-v{version}-headers.tar.gz",
|
|
],
|
|
capture_output=True,
|
|
check=True,
|
|
text=True,
|
|
)
|
|
return called_process.stdout.split("\n")[0]
|
|
except subprocess.CalledProcessError as err:
|
|
print(err.stderr)
|
|
sys.exit(1)
|
|
|
|
|
|
def get_electron_hashes(major_version: str) -> dict:
|
|
"""Returns a dictionary of hashes for a given major version"""
|
|
m, _ = get_latest_version(major_version)
|
|
version: str = m["version"]
|
|
|
|
out = {}
|
|
out[major_version] = {
|
|
"hashes": {},
|
|
"version": version,
|
|
}
|
|
|
|
hashes: list = get_shasums256(version)
|
|
|
|
for nix_system, electron_system in systems.items():
|
|
filename = f"*electron-v{version}-{electron_system}.zip"
|
|
if any([x.endswith(filename) for x in hashes]):
|
|
out[major_version]["hashes"][nix_system] = [
|
|
x.split(" ")[0] for x in hashes if x.endswith(filename)
|
|
][0]
|
|
out[major_version]["hashes"]["headers"] = get_headers(version)
|
|
|
|
return out
|
|
|
|
|
|
def get_chromedriver_hashes(major_version: str) -> dict:
|
|
"""Returns a dictionary of hashes for a given major version"""
|
|
m, _ = get_latest_version(major_version)
|
|
version: str = m["version"]
|
|
|
|
out = {}
|
|
out[major_version] = {
|
|
"hashes": {},
|
|
"version": version,
|
|
}
|
|
|
|
hashes: list = get_shasums256(version)
|
|
|
|
for nix_system, electron_system in systems.items():
|
|
filename = f"*chromedriver-v{version}-{electron_system}.zip"
|
|
if any([x.endswith(filename) for x in hashes]):
|
|
out[major_version]["hashes"][nix_system] = [
|
|
x.split(" ")[0] for x in hashes if x.endswith(filename)
|
|
][0]
|
|
out[major_version]["hashes"]["headers"] = get_headers(version)
|
|
|
|
return out
|
|
|
|
|
|
def update_binary(major_version: str, commit: bool, chromedriver: bool) -> None:
|
|
"""Update a given electron-bin or chromedriver release
|
|
|
|
Args:
|
|
major_version: The major version number, e.g. '27'
|
|
commit: Whether the updater should commit the result
|
|
"""
|
|
if chromedriver:
|
|
json_path=CHROMEDRIVER_INFO_JSON
|
|
package_name = f"electron-chromedriver_{major_version}"
|
|
update_fn=get_chromedriver_hashes
|
|
else:
|
|
json_path=BINARY_INFO_JSON
|
|
package_name = f"electron_{major_version}-bin"
|
|
update_fn = get_electron_hashes
|
|
print(f"Updating {package_name}")
|
|
|
|
old_info = load_info_json(json_path)
|
|
new_info = update_fn(major_version)
|
|
|
|
out = old_info | new_info
|
|
|
|
save_info_json(json_path, out)
|
|
|
|
old_version = (
|
|
old_info[major_version]["version"] if major_version in old_info else None
|
|
)
|
|
new_version = new_info[major_version]["version"]
|
|
if old_version == new_version:
|
|
print(f"{package_name} is up-to-date")
|
|
elif commit:
|
|
commit_result(package_name, old_version, new_version, json_path)
|
|
|
|
|
|
@click.group()
|
|
def cli() -> None:
|
|
"""A script for updating electron-bin and chromedriver hashes"""
|
|
pass
|
|
|
|
|
|
@cli.command("update-chromedriver", help="Update a single major release")
|
|
@click.option("-v", "--version", help="The major version, e.g. '23'")
|
|
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
|
|
def update_chromedriver(version: str, commit: bool) -> None:
|
|
update_binary(version, commit, True)
|
|
|
|
|
|
@cli.command("update", help="Update a single major release")
|
|
@click.option("-v", "--version", required=True, type=str, help="The major version, e.g. '23'")
|
|
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
|
|
def update(version: str, commit: bool) -> None:
|
|
update_binary(version, commit, False)
|
|
update_binary(version, commit, True)
|
|
|
|
|
|
@cli.command("update-all", help="Update all releases at once")
|
|
@click.option("-c", "--commit", is_flag=True, default=False, help="Commit the result")
|
|
def update_all(commit: bool) -> None:
|
|
# Filter out releases that have reached end-of-life
|
|
filtered_bin_info = dict(
|
|
filter(
|
|
lambda entry: int(entry[0]) in supported_version_range(),
|
|
load_info_json(BINARY_INFO_JSON).items(),
|
|
)
|
|
)
|
|
|
|
for major_version, _ in filtered_bin_info.items():
|
|
update_binary(str(major_version), commit, False)
|
|
update_binary(str(major_version), commit, True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
cli()
|