some versions

This commit is contained in:
mjallen18
2026-01-15 09:29:16 -06:00
parent d47b092a8c
commit 8e7a0343c2
15 changed files with 289 additions and 492 deletions

View File

@@ -6,16 +6,19 @@
DEBUG ? "0",
TFA_FLAGS ? "",
}:
let
inherit (lib.trivial) importJSON;
versions = importJSON ./versions.json;
in
stdenv.mkDerivation rec {
pname = "arm-trusted-firmware";
version = "2.14";
version = versions.fw.rev;
src = fetchFromGitHub {
owner = "ARM-software";
repo = "arm-trusted-firmware";
tag = "v${version}";
hash = "sha256-7imeQocGMSyGXTEhNs4s0bcDxZpbLSSkOyI7c5UxqVs=";
hash = versions.fw.hash;
};
# Add required host tools if needed:

View File

@@ -0,0 +1,9 @@
{
"fw": {
"hash": "sha256-eh0b4q6od9ZWAFBQ+wRjpLQEEf8kox2L3l1iHwQtju8=",
"location": "github",
"owner": "ARM-software",
"repo": "arm-trusted-firmware",
"rev": "8fd4c786594239de20669f062e416fe1a37ca59e"
}
}

View File

@@ -41,14 +41,17 @@
jdk17 # for RuneLite/HDOS
, # for RS3
}:
let
inherit (lib.trivial) importJSON;
versions = importJSON ./versions.json;
in
stdenv.mkDerivation rec {
pname = "bolt-launcher";
version = "0.20.6";
version = versions.bolt.version;
src = fetchzip {
url = "https://codeberg.org/Adamcake/Bolt/releases/download/${version}/Bolt-Linux.zip";
sha256 = "sha256-kQwQixUwcbyC53q5lyNdcVbMh40Ay5vmWOj4ZVEVznY=";
sha256 = versions.bolt.hash;
stripRoot = false;
};

View File

@@ -0,0 +1,9 @@
{
"bolt": {
"hash": "sha256-s0hC822fXuYiHPRE3xcLNOsZs43xhLJ+vM1cuMc9zZQ=",
"location": "codeberg",
"owner": "Adamcake",
"repo": "Bolt",
"tag": "0.20.6"
}
}

View File

@@ -17,67 +17,37 @@
namespace,
}:
let
inherit (lib.trivial) importJSON;
pname = "edk2";
version = "stable202511";
versions = importJSON ./versions.json;
edk2Src = (
if MODEL == "5" then
fetchFromGitHub rec {
owner = "mjallen18";
repo = "edk2";
name = repo;
rev = "9765be56f1f816ef737153f5588b3294fcc69a63";
hash = "sha256-oqfJbNeOj2BVJqWE+snD6ri3lUO1aNcmPg+eJpjyr5E=";
fetchSubmodules = true;
}
else
fetchFromGitHub rec {
owner = "tianocore";
repo = "edk2";
name = repo;
tag = "edk2-${version}";
hash = "sha256-R/rgz8dWcDYVoiM67K2UGuq0xXbjjJYBPtJ1FmfGIaU=";
fetchSubmodules = true;
}
);
repoOwner = (if MODEL == "5" then "-mjallen" else "");
edk2NonOsiSrc = (
if MODEL == "5" then
fetchFromGitHub rec {
owner = "mjallen18";
repo = "edk2-non-osi";
name = repo;
rev = "09ee44f07ded544d976be8a03dec3715719f638e";
hash = "sha256-k7nUb3WaRUIr9IlXdam2WGKPOzKjLNVFLfuD5h4veMc=";
}
else
fetchFromGitHub rec {
owner = "tianocore";
repo = "edk2-non-osi";
name = repo;
rev = "94d048981116e2e3eda52dad1a89958ee404098d";
hash = "sha256-6yuvVvmGn4yaEksbbvGDX1ZcKpdWBKnwaNjLGvgAWyk=";
}
);
edk2Src = fetchFromGitHub rec {
owner = versions."edk2${repoOwner}".owner;
repo = "edk2";
name = repo;
rev = versions."edk2${repoOwner}".rev;
hash = versions."edk2${repoOwner}".hash;
};
edk2PlatformsSrc = (
if MODEL == "5" then
fetchFromGitHub rec {
owner = "mjallen18";
repo = "edk2-platforms";
name = repo;
rev = "fdf5a10cc60d1f01030e3ded3c6e69179819cd20";
hash = "sha256-kc5kMEZNLxWFUN8n5+NxXNphkXAtVyjvSAuFyljb8Cs=";
}
else
fetchFromGitHub rec {
owner = "tianocore";
repo = "edk2-platforms";
name = repo;
rev = "0991a0b643509d900e5d023a0116789827a696e5";
hash = "sha256-IdACr0NStqEpC0TFoKKgDwKT2mqyJwVXW/B7hlRXccI=";
}
);
edk2NonOsiSrc = fetchFromGitHub rec {
owner = versions."edk2-non-osi${repoOwner}".owner;
repo = "edk2-non-osi";
name = repo;
rev = versions."edk2-non-osi${repoOwner}".rev;
hash = versions."edk2-non-osi${repoOwner}".hash;
};
edk2PlatformsSrc = fetchFromGitHub rec {
owner = versions."edk2-platforms${repoOwner}".owner;
repo = "edk2-platforms";
name = repo;
rev = versions."edk2-platforms${repoOwner}".rev;
hash = versions."edk2-platforms${repoOwner}".hash;
};
baseTools = pkgs.${namespace}.edk2-basetools.override {
version = "stable202511";

View File

@@ -0,0 +1,44 @@
{
"edk2": {
"hash": "sha256-CS/jWY6B+/PIKDh6cL6n9pwAPhPcjZBZc75SnOJbHf8=",
"location": "github",
"owner": "tianocore",
"repo": "edk2",
"tag": "edk2-stable202511"
},
"edk2-non-osi": {
"hash": "sha256-6yuvVvmGn4yaEksbbvGDX1ZcKpdWBKnwaNjLGvgAWyk=",
"location": "github",
"owner": "tianocore",
"repo": "edk2-non-osi",
"rev": "94d048981116e2e3eda52dad1a89958ee404098d"
},
"edk2-platforms": {
"hash": "sha256-IdACr0NStqEpC0TFoKKgDwKT2mqyJwVXW/B7hlRXccI=",
"location": "github",
"owner": "tianocore",
"repo": "edk2-platforms",
"rev": "0991a0b643509d900e5d023a0116789827a696e5"
},
"edk2-mjallen": {
"hash": "sha256-oqfJbNeOj2BVJqWE+snD6ri3lUO1aNcmPg+eJpjyr5E=",
"location": "github",
"owner": "mjallen18",
"repo": "edk2",
"rev": "9765be56f1f816ef737153f5588b3294fcc69a63"
},
"edk2-non-osi-mjallen": {
"hash": "sha256-k7nUb3WaRUIr9IlXdam2WGKPOzKjLNVFLfuD5h4veMc=",
"location": "github",
"owner": "mjallen18",
"repo": "edk2-non-osi",
"rev": "09ee44f07ded544d976be8a03dec3715719f638e"
},
"edk2-platforms-mjallen": {
"hash": "sha256-kc5kMEZNLxWFUN8n5+NxXNphkXAtVyjvSAuFyljb8Cs=",
"location": "github",
"owner": "mjallen18",
"repo": "edk2-platforms",
"rev": "fdf5a10cc60d1f01030e3ded3c6e69179819cd20"
}
}

View File

@@ -15,7 +15,10 @@
fontconfig,
freetype,
}:
let
inherit (lib.trivial) importJSON;
versions = importJSON ./versions.json;
in
rustPlatform.buildRustPackage rec {
pname = "librepods";
version = "0.1.0";
@@ -23,8 +26,8 @@ rustPlatform.buildRustPackage rec {
src = fetchFromGitHub {
owner = "kavishdevar";
repo = "librepods";
rev = "c852b726deb5344ea3637332722a7c93f3858d60";
hash = "sha256-RoOkINI+ahepAbgwdkcl1iI9XGI/gYXWiH0J9Eb90pg=";
rev = versions.rev;
hash = versions.hash;
};
sourceRoot = "${src.name}/linux-rust";

View File

@@ -0,0 +1,5 @@
{
"repo": "https://github.com/kavishdevar/librepods",
"rev": "c852b726deb5344ea3637332722a7c93f3858d60",
"hash": "sha256-RoOkINI+ahepAbgwdkcl1iI9XGI/gYXWiH0J9Eb90pg="
}

View File

@@ -9,7 +9,10 @@
libpulseaudio,
fetchFromGitHub,
}:
let
inherit (lib.trivial) importJSON;
versions = importJSON ./versions.json;
in
stdenv.mkDerivation {
pname = "librepods";
version = "unstable";
@@ -17,8 +20,8 @@ stdenv.mkDerivation {
src = fetchFromGitHub {
owner = "kavishdevar";
repo = "librepods";
rev = "287163e116d092485d561ad571dae03a2f43cf2f";
hash = "sha256-PD5U87RVBRCLWwnN54x3AEey6wqoOeZlBvzyIESH1v8=";
rev = versions.rev;
hash = versions.hash;
};
sourceRoot = "source/linux";

View File

@@ -0,0 +1,6 @@
{
"repo": "https://github.com/kavishdevar/librepods",
"rev": "287163e116d092485d561ad571dae03a2f43cf2f",
"hash": "sha256-PD5U87RVBRCLWwnN54x3AEey6wqoOeZlBvzyIESH1v8="
}

View File

@@ -1,232 +0,0 @@
{
stdenv,
lib,
buildFHSEnv,
copyDesktopItems,
fetchurl,
gsettings-desktop-schemas,
makeDesktopItem,
makeWrapper,
opensc,
writeTextDir,
writeShellScript,
# New dependencies for aarch64 support
fex,
muvm,
configText ? "",
# Allow users to choose emulation method
useMusvm ? true, # Use muvm + FEX (better isolation) vs just FEX
}:
let
version = "2506";
isAarch64 = stdenv.hostPlatform.system == "aarch64-linux";
# Always extract x64 binaries (we'll emulate on aarch64)
sysArch = "x64";
# For USB support, ensure that /var/run/omnissa/<YOUR-UID>
# exists and is owned by you. Then run omnissa-usbarbitrator as root.
mainProgram = "horizon-client";
# This forces the default GTK theme (Adwaita) because Horizon is prone to
# UI usability issues when using non-default themes, such as Adwaita-dark.
wrapBinCommands = path: name: ''
makeWrapper "$out/${path}/${name}" "$out/bin/${name}_wrapper" \
--set GTK_THEME Adwaita \
--suffix XDG_DATA_DIRS : "${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}" \
--suffix LD_LIBRARY_PATH : "$out/lib/omnissa/horizon/crtbora:$out/lib/omnissa"
'';
omnissaHorizonClientFiles = stdenv.mkDerivation {
pname = "omnissa-horizon-files";
inherit version;
src = fetchurl {
url = "https://download3.omnissa.com/software/CART26FQ2_LIN_2506_TARBALL/Omnissa-Horizon-Client-Linux-2506-8.16.0-16536624989.tar.gz";
sha256 = "5515e79188e2605ced5a95c3a3829865b567be5d7a8de00a57455f7b5b2ae392";
};
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir ext
find ${sysArch} -type f -print0 | xargs -0n1 tar -Cext --strip-components=1 -xf
chmod -R u+w ext/usr/lib
mv ext/usr $out
cp -r ext/${sysArch}/include $out/
cp -r ext/${sysArch}/lib $out/
# Horizon includes a copy of libstdc++ which is loaded via $LD_LIBRARY_PATH
# when it cannot detect a new enough version already present on the system.
# The checks are distribution-specific and do not function correctly on NixOS.
# Deleting the bundled library is the simplest way to force it to use our version.
rm "$out/lib/omnissa/gcc/libstdc++.so.6"
# This opensc library is required to support smartcard authentication during the
# initial connection to Horizon.
mkdir $out/lib/omnissa/horizon/pkcs11
ln -s ${opensc}/lib/pkcs11/opensc-pkcs11.so $out/lib/omnissa/horizon/pkcs11/libopenscpkcs11.so
${wrapBinCommands "bin" "horizon-client"}
${wrapBinCommands "lib/omnissa/horizon/usb" "horizon-eucusbarbitrator"}
'';
};
# x86_64 FHS environment for native or emulated execution
omnissaFHSUserEnv =
pname:
buildFHSEnv {
inherit pname version;
# On aarch64, we need to invoke via FEX or muvm
runScript = "${omnissaHorizonClientFiles}/bin/${pname}_wrapper";
targetPkgs =
pkgs: with pkgs; [
at-spi2-atk
atk
cairo
dbus
file
fontconfig
freetype
gdk-pixbuf
glib
gtk2
gtk3-x11
harfbuzz
liberation_ttf
libjpeg
libpng
libpulseaudio
libtiff
libudev0-shim
libuuid
libv4l
pango
pcsclite
pixman
udev
omnissaHorizonClientFiles
xorg.libX11
xorg.libXau
xorg.libXcursor
xorg.libXext
xorg.libXi
xorg.libXinerama
xorg.libxkbfile
xorg.libXrandr
xorg.libXrender
xorg.libXScrnSaver
xorg.libXtst
zlib
libxml2_13
(writeTextDir "etc/omnissa/config" configText)
];
};
# Create wrapper scripts for aarch64 that use FEX or muvm
# Option 1: Direct FEX execution (simpler, less isolation)
fexWrapper =
pname:
writeShellScript "${pname}-fex-wrapper" ''
export FEXINTERPRETER="${fex}/bin/FEXInterpreter"
export FEX_ROOTFS="${fex}/share/fex-emu/RootFS"
# Set up FEX environment
export FEX_TSOENABLED=1
exec ${fex}/bin/FEXBash -c '${omnissaFHSUserEnv pname}/bin/${pname} "$@"' -- "$@"
'';
# Option 2: muvm + FEX (better isolation, handles kernel differences)
muvmWrapper =
pname:
writeShellScript "${pname}-muvm-wrapper" ''
# muvm creates a lightweight VM with x86_64 emulation via FEX
# This provides better isolation and compatibility
exec ${muvm}/bin/muvm \
--fex \
--share-display \
--share-sound \
-- ${omnissaFHSUserEnv pname}/bin/${pname} "$@"
'';
# Select the appropriate wrapper based on configuration
aarch64Wrapper = pname: if useMusvm then muvmWrapper pname else fexWrapper pname;
# Final wrapper that handles both architectures
desktopItem = makeDesktopItem {
name = "horizon-client";
desktopName = "Omnissa Horizon Client";
icon = "${omnissaHorizonClientFiles}/share/icons/horizon-client.png";
exec = "${
if isAarch64 then
aarch64Wrapper mainProgram
else
"${omnissaFHSUserEnv mainProgram}/bin/${mainProgram}"
} %u";
mimeTypes = [
"x-scheme-handler/horizon-client"
"x-scheme-handler/vmware-view"
];
};
in
stdenv.mkDerivation {
pname = "omnissa-horizon-client";
inherit version;
dontUnpack = true;
nativeBuildInputs = [ copyDesktopItems ];
desktopItems = [ desktopItem ];
installPhase = ''
runHook preInstall
mkdir -p $out/bin
${
if isAarch64 then
''
# On aarch64, create wrapper scripts that use FEX/muvm
cp ${aarch64Wrapper "horizon-client"} $out/bin/horizon-client
chmod +x $out/bin/horizon-client
cp ${aarch64Wrapper "omnissa-usbarbitrator"} $out/bin/omnissa-usbarbitrator
chmod +x $out/bin/omnissa-usbarbitrator
''
else
''
# On x86_64, use native FHS environment directly
ln -s ${omnissaFHSUserEnv "horizon-client"}/bin/horizon-client $out/bin/
ln -s ${omnissaFHSUserEnv "omnissa-usbarbitrator"}/bin/omnissa-usbarbitrator $out/bin/
''
}
runHook postInstall
'';
unwrapped = omnissaHorizonClientFiles;
passthru = {
updateScript = ./update.sh;
# Expose FHS env for debugging
fhsEnv = omnissaFHSUserEnv mainProgram;
};
meta = with lib; {
inherit mainProgram;
description = "Allows you to connect to your Omnissa Horizon virtual desktop";
homepage = "https://www.omnissa.com/products/horizon-8/";
license = licenses.unfree;
platforms = [
"x86_64-linux"
"aarch64-linux"
];
maintainers = with maintainers; [ mhutter ];
};
}

View File

@@ -1,43 +0,0 @@
{
lib,
stdenv,
fetchFromGitHub,
pciutils,
bash,
}:
stdenv.mkDerivation {
pname = "steamdeck-bios-manager";
version = "12b0139e3aabb21e559ab0a0c62a432523080bb9";
src = fetchFromGitHub {
owner = "ryanrudolfoba";
repo = "SteamDeck-BIOS-Manager";
rev = "12b0139e3aabb21e559ab0a0c62a432523080bb9";
sha256 = "sha256-Dw1r1UnmSVyrCMNRS79F99x8Vgb6KASN2gBegPbXnpk=";
};
# shell scripts — no compilation
dontBuild = true;
installPhase = ''
mkdir -p $out/bin
cp steamdeck-bios-manager.sh $out/bin/steamdeck-bios-manager
chmod +x $out/bin/steamdeck-bios-manager
'';
# runtime deps
nativeBuildInputs = [
pciutils
bash
];
meta = with lib; {
description = "Manage BIOS for the Steam Deck (unlock, flash, backup, block updates)";
homepage = "https://github.com/ryanrudolfoba/SteamDeck-BIOS-Manager";
license = licenses.agpl3Only;
platforms = platforms.linux;
maintainers = [ ];
sourceProvenance = with sourceTypes; [ ];
};
}

View File

@@ -1,149 +0,0 @@
{
lib,
glib,
stdenv,
dbus,
freetype,
fontconfig,
zlib,
libsForQt5,
libxinerama,
libxcb,
libsm,
libxi,
libglvnd,
libxext,
libxrandr,
mailspring,
libx11,
libice,
libxrender,
autoPatchelfHook,
makeWrapper,
xkeyboard_config,
fetchurl,
buildFHSEnv,
openal,
makeDesktopItem,
}:
let
pname = "unigine-superposition";
version = "1.1";
superposition = stdenv.mkDerivation rec {
inherit pname version;
src = fetchurl {
url = "https://assets.unigine.com/d/Unigine_Superposition-${version}.run";
sha256 = "sha256-dJThxzv1nvIWFRPV1cudm/+9hHmSnUl2rFO2lV3lgPg=";
};
nativeBuildInputs = [
autoPatchelfHook
makeWrapper
];
buildInputs = [
glib
stdenv.cc.cc
dbus
freetype
fontconfig
zlib
libsForQt5.qt5.qtquickcontrols2
libxinerama
libxcb
libsm
libxi
libglvnd
libxext
libxrandr
mailspring
libx11
libice
libxrender
];
installPhase = ''
bash $src --target $name --noexec
mkdir -p $out/bin $out/lib/unigine/superposition/
cp -r $name/* $out/lib/unigine/superposition/
echo "exec $out/lib/unigine/superposition/Superposition" >> $out/bin/superposition
chmod +x $out/bin/superposition
wrapProgram $out/lib/unigine/superposition/Superposition \
--set QT_XKB_CONFIG_ROOT ${xkeyboard_config} \
--run "cd $out/lib/unigine/superposition/"
'';
dontUnpack = true;
dontWrapQtApps = true;
postPatchMkspecs = ''
cp -f $name/bin/superposition $out/lib/unigine/superposition/bin/superposition
'';
};
desktopItem = makeDesktopItem {
name = "Superposition";
exec = "unigine-superposition";
genericName = "A GPU Stress test tool from the UNIGINE";
icon = "Superposition";
desktopName = "Superposition Benchmark";
};
in
# We can patch the "/bin/superposition", but "/bin/launcher" checks it for changes.
# For that we need use a buildFHSEnv.
buildFHSEnv {
inherit pname version;
targetPkgs = _pkgs: [
superposition
glib
stdenv.cc.cc
dbus
freetype
fontconfig
zlib
libsForQt5.qt5.qtquickcontrols2
libxinerama
libxcb
libsm
libxi
libglvnd
libxext
libxrandr
mailspring
libx11
libice
libxrender
openal
];
runScript = "superposition";
extraInstallCommands = ''
# create directories
mkdir -p $out/share/icons/hicolor $out/share/applications
# create .desktop file
ln -s ${desktopItem}/share/applications/* $out/share/applications
# install Superposition.desktop and icon
cp ${superposition}/lib/unigine/superposition/Superposition.png $out/share/icons/
for RES in 16 24 32 48 64 128 256; do
mkdir -p $out/share/icons/hicolor/"$RES"x"$RES"/apps
cp ${superposition}/lib/unigine/superposition/icons/superposition_icon_$RES.png $out/share/icons/hicolor/"$RES"x"$RES"/apps/Superposition.png
done
'';
meta = {
description = "Unigine Superposition GPU benchmarking tool";
homepage = "https://benchmark.unigine.com/superposition";
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
license = lib.licenses.unfree;
maintainers = [ ];
platforms = [ "x86_64-linux" ];
mainProgram = "unigine-superposition";
};
}

View File

@@ -0,0 +1,5 @@
{
"repo": "https://ftp.denx.de/pub/u-boot/u-boot-${defaultVersion}.tar.bz2",
"tag": "2025.07",
"hash": "sha256-D5M/bFpCaJW/MG6T5qxTxghw5LVM2lbZUhG+yZ5jvsc="
}

161
update.py Executable file
View File

@@ -0,0 +1,161 @@
#!/usr/bin/env python3
import json
import re
import subprocess
import sys
from pathlib import Path
from urllib.request import Request, urlopen
from urllib.error import HTTPError
GITHUB_API = "https://api.github.com"
CODEBERG_API = "https://codeberg.org/api/v1"
def run(cmd):
p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if p.returncode != 0:
raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{p.stderr.strip()}")
return p.stdout.strip()
def http_get_json(url, token=None):
headers = {"Accept": "application/json"}
if token:
headers["Authorization"] = f"token {token}"
req = Request(url, headers=headers)
with urlopen(req) as resp:
return json.load(resp)
def github_latest_release(owner, repo, token=None):
url = f"{GITHUB_API}/repos/{owner}/{repo}/releases/latest"
return http_get_json(url, token=token)
def github_latest_commit(owner, repo, token=None):
url = f"{GITHUB_API}/repos/{owner}/{repo}/commits?per_page=1"
data = http_get_json(url, token=token)
return data[0]["sha"]
def codeberg_latest_release(owner, repo, token=None):
url = f"{CODEBERG_API}/repos/{owner}/{repo}/releases/latest"
return http_get_json(url, token=token)
def codeberg_latest_commit(owner, repo, token=None):
url = f"{CODEBERG_API}/repos/{owner}/{repo}/commits?limit=1"
data = http_get_json(url, token=token)
return data[0]["sha"]
def nix_hash_to_sri(hash_str):
# Convert nix-base32 to SRI
return run(["nix", "hash", "to-sri", "--type", "sha256", hash_str])
def prefetch_git(url, rev):
out = run(["nix-prefetch-git", "--url", url, "--rev", rev, "--fetch-submodules"])
data = json.loads(out)
return nix_hash_to_sri(data["sha256"])
def prefetch_url(url, unpack=False):
cmd = ["nix-prefetch-url", url]
if unpack:
cmd.insert(1, "--unpack")
hash_str = run(cmd)
return nix_hash_to_sri(hash_str)
def is_archive_url(url):
return bool(re.search(r"\.(tar\.gz|tar\.xz|tar\.bz2|zip)$", url))
def build_repo_url(location, owner, repo):
if location == "github":
return f"https://github.com/{owner}/{repo}.git"
if location == "codeberg":
return f"https://codeberg.org/{owner}/{repo}.git"
raise ValueError(f"Unknown repo location: {location}")
def build_release_tarball_url(location, owner, repo, tag):
if location == "github":
return f"https://github.com/{owner}/{repo}/archive/refs/tags/{tag}.tar.gz"
if location == "codeberg":
return f"https://codeberg.org/{owner}/{repo}/archive/{tag}.tar.gz"
raise ValueError(f"Unknown repo location: {location}")
def update_entry(name, entry, gh_token=None, cb_token=None):
location = entry.get("location")
owner = entry.get("owner")
repo = entry.get("repo")
url = entry.get("url")
if url and (location == "url" or location == "archive"):
# Direct URL source
unpack = is_archive_url(url)
new_hash = prefetch_url(url, unpack=unpack)
entry["hash"] = new_hash
return True
if location in ("github", "codeberg"):
if entry.get("tag"):
# Use latest release tag
if location == "github":
rel = github_latest_release(owner, repo, token=gh_token)
tag = rel["tag_name"]
else:
rel = codeberg_latest_release(owner, repo, token=cb_token)
tag = rel["tag_name"]
if tag != entry["tag"]:
entry["tag"] = tag
tar_url = build_release_tarball_url(location, owner, repo, tag)
entry["hash"] = prefetch_url(tar_url, unpack=True)
return True
if entry.get("rev"):
# Use latest commit
if location == "github":
sha = github_latest_commit(owner, repo, token=gh_token)
else:
sha = codeberg_latest_commit(owner, repo, token=cb_token)
if sha != entry["rev"]:
entry["rev"] = sha
repo_url = build_repo_url(location, owner, repo)
entry["hash"] = prefetch_git(repo_url, sha)
return True
return False
def process_file(path, gh_token=None, cb_token=None):
data = json.loads(path.read_text())
changed = False
for name, entry in data.items():
try:
changed = update_entry(name, entry, gh_token=gh_token, cb_token=cb_token)
except HTTPError as e:
print(f"[WARN] {path}: {name}: HTTP error {e.code}", file=sys.stderr)
except Exception as e:
print(f"[WARN] {path}: {name}: {e}", file=sys.stderr)
if changed:
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n")
return changed
def main(root):
gh_token = None
cb_token = None
# Optional tokens from environment
# import os
# gh_token = os.environ.get("GITHUB_TOKEN")
# cb_token = os.environ.get("CODEBERG_TOKEN")
root = Path(root)
files = list(root.rglob("version*.json"))
if not files:
print("No version*.json files found")
return 1
updated = 0
for f in files:
if process_file(f, gh_token=gh_token, cb_token=cb_token):
print(f"Updated: {f}")
updated += 1
print(f"Done. Updated {updated} file(s).")
return 0
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <root-folder>")
sys.exit(2)
sys.exit(main(sys.argv[1]))