diff options
Diffstat (limited to 'pkgs/os-specific/linux/kernel/update-mainline.py')
-rwxr-xr-x | pkgs/os-specific/linux/kernel/update-mainline.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/kernel/update-mainline.py b/pkgs/os-specific/linux/kernel/update-mainline.py new file mode 100755 index 00000000000..e7c37e9ab99 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/update-mainline.py @@ -0,0 +1,104 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i python3 -p "python3.withPackages (ps: [ ps.beautifulsoup4 ps.lxml ])" +from enum import Enum +from bs4 import BeautifulSoup, NavigableString, Tag +from dataclasses import dataclass +import json +import pathlib +import re +import subprocess +import urllib.request +import sys + + +HERE = pathlib.Path(__file__).parent +ROOT = HERE.parent.parent.parent.parent +VERSIONS_FILE = HERE / "kernels-org.json" + +class KernelNature(Enum): + MAINLINE = 1 + STABLE = 2 + LONGTERM = 3 + +@dataclass +class KernelRelease: + nature: KernelNature + version: str + date: str + link: str + eol: bool = False + +def parse_release(release: Tag) -> KernelRelease | None: + columns: list[Tag] = list(release.find_all('td')) + try: + nature = KernelNature[columns[0].get_text().rstrip(':').upper()] + except KeyError: + return None + + version = columns[1].get_text().rstrip(' [EOL]') + date = columns[2].get_text() + link = columns[3].find('a') + if link is not None and isinstance(link, Tag): + link = link.attrs.get('href') + assert link is not None, f'link for kernel {version} is non-existent' + eol = bool(release.find(class_='eolkernel')) + + return KernelRelease(nature=nature, version=version, date=date, link=link, eol=eol) + +def get_branch(version: str): + # This is a testing kernel. + if 'rc' in version: + return 'testing' + else: + major, minor, *_ = version.split(".") + return f"{major}.{minor}" + + +def get_hash(url: str): + return subprocess.check_output(["nix-prefetch-url", url]).decode().strip() + + +def commit(message): + return subprocess.check_call(["git", "commit", "-m", message, VERSIONS_FILE]) + + +def main(): + kernel_org = urllib.request.urlopen("https://kernel.org/") + soup = BeautifulSoup(kernel_org.read().decode(), "lxml") + release_table = soup.find(id='releases') + if not release_table or isinstance(release_table, NavigableString): + print(release_table) + print('Failed to find the release table on https://kernel.org') + sys.exit(1) + + releases = release_table.find_all('tr') + parsed_releases = filter(None, [parse_release(release) for release in releases]) + all_kernels = json.load(VERSIONS_FILE.open()) + + for kernel in parsed_releases: + branch = get_branch(kernel.version) + nixpkgs_branch = branch.replace('.', '_') + + old_version = all_kernels.get(branch, {}).get("version") + if old_version == kernel.version: + print(f"linux_{nixpkgs_branch}: {kernel.version} is latest, skipping...") + continue + + if old_version is None: + message = f"linux_{nixpkgs_branch}: init at {kernel.version}" + else: + message = f"linux_{nixpkgs_branch}: {old_version} -> {kernel.version}" + + print(message) + + all_kernels[branch] = {"version": kernel.version, "hash": get_hash(kernel.link)} + + with VERSIONS_FILE.open("w") as fd: + json.dump(all_kernels, fd, indent=4) + fd.write("\n") # makes editorconfig happy + + commit(message) + + +if __name__ == "__main__": + main() |