Files
nixpkgs/pkgs/development/tools/electron/binary/update.py
T
2025-04-10 21:41:09 +02:00

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()