Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1#!/usr/bin/env nix-shell
2#!nix-shell -I nixpkgs=./. -i python3 -p python3 curl common-updater-scripts nix coreutils
3
4"""
5Updater script for the roon-server package.
6"""
7
8import subprocess
9import urllib.request
10import re
11import sys
12import os
13
14
15def get_current_version():
16 """Get the current version of roon-server from the package.nix file."""
17 result = subprocess.run(
18 [
19 "nix-instantiate",
20 "--eval",
21 "-E",
22 "with import ./. {}; roon-server.version or (lib.getVersion roon-server)",
23 ],
24 capture_output=True,
25 text=True,
26 )
27 result.check_returncode()
28 return result.stdout.strip().strip('"')
29
30
31def get_latest_version_info():
32 """Get the latest version information from the Roon Labs API."""
33 url = "https://updates.roonlabs.net/update/?v=2&platform=linux&version=&product=RoonServer&branding=roon&branch=production&curbranch=production"
34 with urllib.request.urlopen(url) as response:
35 content = response.read().decode("utf-8")
36
37 # Parse the response
38 info = {}
39 for line in content.splitlines():
40 if "=" in line:
41 key, value = line.split("=", 1)
42 info[key] = value
43
44 return info
45
46
47def parse_version(display_version):
48 """Parse the display version string to get the version in the format used in the package.nix file."""
49 # Example: "2.47 (build 1510) production" -> "2.47.1510"
50 match = re.search(r"(\d+\.\d+)\s+\(build\s+(\d+)\)", display_version)
51 if match:
52 return f"{match.group(1)}.{match.group(2)}"
53 return None
54
55
56def get_hash(url):
57 """Calculate the hash of the package."""
58 result = subprocess.run(
59 ["nix-prefetch-url", "--type", "sha256", url], capture_output=True, text=True
60 )
61 result.check_returncode()
62 pkg_hash = result.stdout.strip()
63
64 result = subprocess.run(
65 ["nix", "hash", "to-sri", f"sha256:{pkg_hash}"], capture_output=True, text=True
66 )
67 result.check_returncode()
68 return result.stdout.strip()
69
70
71def update_package(new_version, hash_value):
72 """Update the package.nix file with the new version and hash."""
73 subprocess.run(
74 [
75 "update-source-version",
76 "roon-server",
77 new_version,
78 hash_value,
79 "--ignore-same-version",
80 ],
81 check=True,
82 )
83
84
85def main():
86 current_version = get_current_version()
87 print(f"Current roon-server version: {current_version}")
88
89 try:
90 latest_info = get_latest_version_info()
91
92 display_version = latest_info.get("displayversion", "")
93 download_url = latest_info.get("updateurl", "")
94
95 if not display_version or not download_url:
96 print("Error: Failed to get version information from Roon Labs API")
97 sys.exit(1)
98
99 print(f"Latest version from API: {display_version}")
100 print(f"Download URL: {download_url}")
101
102 new_version = parse_version(display_version)
103 if not new_version:
104 print(
105 f"Error: Failed to parse version from display version: {display_version}"
106 )
107 sys.exit(1)
108
109 print(f"Parsed version: {new_version}")
110
111 if new_version == current_version:
112 print("roon-server is already up to date!")
113 return
114
115 print(f"Calculating hash for new version {new_version}...")
116 hash_value = get_hash(download_url)
117
118 print(
119 f"Updating package.nix with new version {new_version} and hash {hash_value}"
120 )
121 update_package(new_version, hash_value)
122
123 print(f"Successfully updated roon-server to version {new_version}")
124
125 except Exception as e:
126 print(f"Error: {e}")
127 sys.exit(1)
128
129
130if __name__ == "__main__":
131 main()