Merge pull request #329823 from ExpidusOS/fix/pkgsllvm/elfutils
[NixPkgs.git] / pkgs / by-name / so / sonarr / update.py
blob195a2d5d05ac0842efc34f3e4fa35571acf950b8
1 import json
2 import os
3 import pathlib
4 import requests
5 import shutil
6 import subprocess
7 import sys
8 import tempfile
11 def replace_in_file(file_path, replacements):
12 file_contents = pathlib.Path(file_path).read_text()
13 for old, new in replacements.items():
14 if old == new:
15 continue
16 updated_file_contents = file_contents.replace(old, new)
17 # A dumb way to check that we’ve actually replaced the string.
18 if file_contents == updated_file_contents:
19 print(f"no string to replace: {old} {new}", file=sys.stderr)
20 sys.exit(1)
21 file_contents = updated_file_contents
22 with tempfile.NamedTemporaryFile(mode="w") as t:
23 t.write(file_contents)
24 t.flush()
25 shutil.copyfile(t.name, file_path)
28 def nix_hash_to_sri(hash):
29 return subprocess.run(
31 "nix",
32 "--extra-experimental-features", "nix-command",
33 "hash",
34 "to-sri",
35 "--type", "sha256",
36 "--",
37 hash,
39 stdout=subprocess.PIPE,
40 text=True,
41 check=True,
42 ).stdout.rstrip()
45 nixpkgs_path = "."
46 attr_path = os.getenv("UPDATE_NIX_ATTR_PATH", "sonarr")
48 package_attrs = json.loads(subprocess.run(
50 "nix",
51 "--extra-experimental-features", "nix-command",
52 "eval",
53 "--json",
54 "--file", nixpkgs_path,
55 "--apply", """p: {
56 dir = builtins.dirOf p.meta.position;
57 version = p.version;
58 sourceHash = p.src.outputHash;
59 yarnHash = p.yarnOfflineCache.outputHash;
60 }""",
61 "--",
62 attr_path,
64 stdout=subprocess.PIPE,
65 text=True,
66 check=True,
67 ).stdout)
69 old_version = package_attrs["version"]
70 new_version = old_version
72 # Note that we use Sonarr API instead of GitHub to fetch latest stable release.
73 # This corresponds to the Updates tab in the web UI. See also
74 # https://github.com/Sonarr/Sonarr/blob/070919a7e6a96ca7e26524996417c6f8d1b5fcaa/src/NzbDrone.Core/Update/UpdatePackageProvider.cs
75 version_update = requests.get(
76 f"https://services.sonarr.tv/v1/update/main?version={old_version}",
77 ).json()
78 if version_update["available"]:
79 new_version = version_update["updatePackage"]["version"]
81 if new_version == old_version:
82 sys.exit()
84 source_nix_hash, source_store_path = subprocess.run(
86 "nix-prefetch-url",
87 "--name", "source",
88 "--unpack",
89 "--print-path",
90 f"https://github.com/Sonarr/Sonarr/archive/v{new_version}.tar.gz",
92 stdout=subprocess.PIPE,
93 text=True,
94 check=True,
95 ).stdout.rstrip().split("\n")
97 old_source_hash = package_attrs["sourceHash"]
98 new_source_hash = nix_hash_to_sri(source_nix_hash)
100 old_yarn_hash = package_attrs["yarnHash"]
101 new_yarn_hash = nix_hash_to_sri(subprocess.run(
103 "prefetch-yarn-deps",
104 # does not support "--" separator :(
105 # Also --verbose writes to stdout, yikes.
106 os.path.join(source_store_path, "yarn.lock"),
108 stdout=subprocess.PIPE,
109 text=True,
110 check=True,
111 ).stdout.rstrip())
113 package_dir = package_attrs["dir"]
114 package_file_name = "package.nix"
115 deps_file_name = "deps.nix"
117 # To update deps.nix, we copy the package to a temporary directory and run
118 # passthru.fetch-deps script there.
119 with tempfile.TemporaryDirectory() as work_dir:
120 package_file = os.path.join(work_dir, package_file_name)
121 deps_file = os.path.join(work_dir, deps_file_name)
123 shutil.copytree(package_dir, work_dir, dirs_exist_ok=True)
125 replace_in_file(package_file, {
126 # NB unlike hashes, versions are likely to be used in code or comments.
127 # Try to be more specific to avoid false positive matches.
128 f"version = \"{old_version}\"": f"version = \"{new_version}\"",
129 old_source_hash: new_source_hash,
130 old_yarn_hash: new_yarn_hash,
133 # Generate nuget-to-nix dependency lock file.
134 fetch_deps = os.path.join(work_dir, "fetch-deps")
135 subprocess.run(
137 "nix",
138 "--extra-experimental-features", "nix-command",
139 "build",
140 "--impure",
141 "--nix-path", "",
142 "--include", f"nixpkgs={nixpkgs_path}",
143 "--include", f"package={package_file}",
144 "--expr", "(import <nixpkgs> { }).callPackage <package> { }",
145 "--out-link", fetch_deps,
146 "passthru.fetch-deps",
148 check=True,
150 subprocess.run(
152 fetch_deps,
153 deps_file,
155 stdout=subprocess.DEVNULL,
156 check=True,
159 shutil.copy(deps_file, os.path.join(package_dir, deps_file_name))
160 shutil.copy(package_file, os.path.join(package_dir, package_file_name))