aboutsummaryrefslogtreecommitdiff
path: root/vcpkg/scripts/update_suitesparse.py
diff options
context:
space:
mode:
authorEthan Morgan <ethan@gweithio.com>2026-02-14 16:44:06 +0000
committerEthan Morgan <ethan@gweithio.com>2026-02-14 16:44:06 +0000
commit54409423f767d8b1cf30cb7d0efca6b4ca138823 (patch)
treed915ac7828703ce4b963efdd9728a1777ba18c1e /vcpkg/scripts/update_suitesparse.py
move to own git serverHEADmaster
Diffstat (limited to 'vcpkg/scripts/update_suitesparse.py')
-rwxr-xr-xvcpkg/scripts/update_suitesparse.py120
1 files changed, 120 insertions, 0 deletions
diff --git a/vcpkg/scripts/update_suitesparse.py b/vcpkg/scripts/update_suitesparse.py
new file mode 100755
index 0000000..419683d
--- /dev/null
+++ b/vcpkg/scripts/update_suitesparse.py
@@ -0,0 +1,120 @@
+#!/usr/bin/env python3
+
+# Usage: ./update_suitesparse.py <new_version>
+#
+# Updates the `suitesparse` port and all of its `suitesparse-*` sub-packages
+# based on the source archive automatically downloaded of the given version.
+
+import hashlib
+import io
+import json
+import re
+import sys
+import tarfile
+from pathlib import Path
+
+import requests
+
+ports_root = Path(__file__).resolve().parent.parent / "ports"
+
+
+def download(url):
+ print(f"Downloading {url}...")
+ r = requests.get(url)
+ r.raise_for_status()
+ return r.content
+
+
+def sha512(data):
+ sha = hashlib.sha512()
+ sha.update(data)
+ return sha.hexdigest()
+
+
+def extract_version(content):
+ major = re.search(r"^set *\( *(\w+)_VERSION_MAJOR +(\d+) ", content, re.M).group(2)
+ minor = re.search(r"^set *\( *(\w+)_VERSION_MINOR +(\d+) ", content, re.M).group(2)
+ sub = re.search(r"^set *\( *(\w+)_VERSION_(?:SUB|PATCH|UPDATE) +(\d+) ", content, re.M).group(2)
+ return f"{major}.{minor}.{sub}"
+
+
+def load_versions(tar_gz_bytes):
+ versions = {}
+ tar_gz_file = io.BytesIO(tar_gz_bytes)
+ with tarfile.open(fileobj=tar_gz_file, mode="r:gz") as tar:
+ for member in tar.getmembers():
+ if not member.isfile():
+ continue
+ if m := re.fullmatch(r"SuiteSparse-[^/]+/(\w+)/CMakeLists.txt", member.name):
+ name = m.group(1)
+ if name in ["Example", "GraphBLAS", "CSparse"]:
+ continue
+ content = tar.extractfile(member).read().decode("utf8")
+ versions[name] = extract_version(content)
+ elif member.name.endswith("GraphBLAS_version.cmake"):
+ content = tar.extractfile(member).read().decode("utf8")
+ versions["GraphBLAS"] = extract_version(content)
+ return versions
+
+
+def update_manifest(pkg_name, version):
+ port_dir = ports_root / pkg_name
+ manifest_path = port_dir / "vcpkg.json"
+ manifest = json.loads(manifest_path.read_text("utf8"))
+ if manifest["version-semver"] == version:
+ return False
+ manifest["version-semver"] = version
+ manifest_path.write_text(json.dumps(manifest, indent=2) + "\n")
+ return True
+
+
+def update_portfile(pkg_name, new_version, new_hash):
+ port_dir = ports_root / pkg_name
+ portfile_path = port_dir / "portfile.cmake"
+ content = portfile_path.read_text("utf8")
+ content, n = re.subn(r"\bREF v\S+", f"REF v{new_version}", content, re.M)
+ if n != 1:
+ raise Exception(f"Updating {pkg_name} portfile ref failed!")
+ content, n = re.subn(r"\bSHA512 \S+", f"SHA512 {new_hash}", content, re.M)
+ if n != 1:
+ raise Exception(f"Updating {pkg_name} portfile hash failed!")
+ portfile_path.write_text(content)
+
+
+def update_port(pkg_name, new_version, suitesparse_hash):
+ port_dir = ports_root / pkg_name
+ if not port_dir.exists():
+ raise Exception(f"'{pkg_name}' does not exist!")
+ update_manifest(pkg_name, new_version)
+ # Always update the tag in vcpkg_from_github() even if version has not changed
+ # to avoid having to download multiple versions of the source archive.
+ print(f"{pkg_name}: updating...")
+ if pkg_name == "suitesparse-graphblas":
+ url = f"https://github.com/DrTimothyAldenDavis/GraphBLAS/archive/refs/tags/v{new_version}.tar.gz"
+ graphblas_hash = sha512(download(url))
+ update_portfile(pkg_name, new_version, graphblas_hash)
+ else:
+ update_portfile(pkg_name, suitesparse_version, suitesparse_hash)
+
+
+def main(suitesparse_version):
+ suitesparse_url = (
+ f"https://github.com/DrTimothyAldenDavis/SuiteSparse/archive/refs/tags/v{suitesparse_version}.tar.gz"
+ )
+ tar_gz_bytes = download(suitesparse_url)
+ suitesparse_hash = sha512(tar_gz_bytes)
+ print("Reading versions from CMakeLists.txt files...")
+ versions = load_versions(tar_gz_bytes)
+ for lib, new_version in versions.items():
+ pkg_name = "suitesparse-config" if lib == "SuiteSparse_config" else "suitesparse-" + lib.lower()
+ update_port(pkg_name, new_version, suitesparse_hash)
+ update_manifest("suitesparse", suitesparse_version)
+ print("Done!")
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 2:
+ print("Usage: ./update_suitesparse.py <new_version>")
+ sys.exit(1)
+ suitesparse_version = sys.argv[1]
+ main(suitesparse_version)