summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--justfile5
-rw-r--r--nix/fetch-crate.nix17
-rw-r--r--nix/flake.nix21
-rw-r--r--tests/test_crate_fetchurl.py41
4 files changed, 83 insertions, 1 deletions
diff --git a/justfile b/justfile
index 6d2c2e9..7267729 100644
--- a/justfile
+++ b/justfile
@@ -99,6 +99,11 @@ arch-news-read:
# Refresh package releases and Nix flake inputs, then re-activate the profile.
nix-update: _nix-release-update _nix-flake-update nix-switch
+# Fetch a locked Rust crate and repeat the download without using its cached output.
+nix-crate-check:
+ nix build --no-link ./nix#checks.x86_64-linux.crate-download
+ nix build --no-link --rebuild ./nix#checks.x86_64-linux.crate-download
+
_nix-release-update:
@bash "{{ justfile_directory() }}/nix/update-releases.sh"
diff --git a/nix/fetch-crate.nix b/nix/fetch-crate.nix
new file mode 100644
index 0000000..733d83a
--- /dev/null
+++ b/nix/fetch-crate.nix
@@ -0,0 +1,17 @@
+fetchurl: attrs:
+let
+ crate = builtins.match "https://crates[.]io/api/v1/crates/([^/]+)/([^/]+)/download" (
+ attrs.url or ""
+ );
+in
+fetchurl (
+ attrs
+ // (
+ if crate == null then
+ { }
+ else
+ {
+ url = "https://static.crates.io/crates/${builtins.elemAt crate 0}/${builtins.elemAt crate 0}-${builtins.elemAt crate 1}.crate";
+ }
+ )
+)
diff --git a/nix/flake.nix b/nix/flake.nix
index b140bf0..33dbe42 100644
--- a/nix/flake.nix
+++ b/nix/flake.nix
@@ -44,7 +44,11 @@
# Expose external flake packages so common.nix can list them next to
# nixpkgs packages without threading inputs into every module.
(final: prev: {
- tuicr = tuicr.packages.${system}.default;
+ tuicr =
+ (final.callPackage tuicr.inputs.naersk {
+ fetchurl = import ./fetch-crate.nix final.fetchurl;
+ }).buildPackage
+ tuicr;
aibox = aibox.packages.${system}.default;
claude-release = prev.claude-code.overrideAttrs {
version = releases.claude.version;
@@ -257,6 +261,21 @@
};
in
{
+ checks.${system}.crate-download =
+ let
+ lock = builtins.fromTOML (builtins.readFile "${tuicr}/Cargo.lock");
+ crate = builtins.head (
+ builtins.filter (
+ package: (package.source or "") == "registry+https://github.com/rust-lang/crates.io-index"
+ ) lock.package
+ );
+ in
+ import ./fetch-crate.nix pkgs.fetchurl {
+ name = "crate-download-check-${crate.name}-${crate.version}";
+ url = "https://crates.io/api/v1/crates/${crate.name}/${crate.version}/download";
+ sha256 = crate.checksum;
+ };
+
devShells.${system}.default = pkgs.mkShellNoCC {
packages = with pkgs; [
basedpyright
diff --git a/tests/test_crate_fetchurl.py b/tests/test_crate_fetchurl.py
new file mode 100644
index 0000000..b4619eb
--- /dev/null
+++ b/tests/test_crate_fetchurl.py
@@ -0,0 +1,41 @@
+import json
+import subprocess
+import unittest
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parents[1]
+
+
+class CrateFetchTests(unittest.TestCase):
+ def evaluate(self, attrs):
+ expression = (
+ f"let fetch = import {ROOT}/nix/fetch-crate.nix (args: args); "
+ f"in fetch (builtins.fromJSON {json.dumps(json.dumps(attrs))})"
+ )
+ return json.loads(
+ subprocess.check_output(
+ ["nix", "eval", "--impure", "--json", "--expr", expression], text=True
+ )
+ )
+
+ def test_crate_uses_static_archive_and_keeps_hash(self):
+ attrs = {
+ "name": "download-hashbrown-0.16.1",
+ "url": "https://crates.io/api/v1/crates/hashbrown/0.16.1/download",
+ "sha256": "locked-checksum",
+ }
+ self.assertEqual(
+ self.evaluate(attrs),
+ {
+ **attrs,
+ "url": "https://static.crates.io/crates/hashbrown/hashbrown-0.16.1.crate",
+ },
+ )
+
+ def test_other_downloads_are_unchanged(self):
+ attrs = {"url": "https://example.org/source.tar.gz", "hash": "unchanged"}
+ self.assertEqual(self.evaluate(attrs), attrs)
+
+ def test_url_lists_are_unchanged(self):
+ attrs = {"urls": ["https://example.org/source.tar.gz"], "hash": "unchanged"}
+ self.assertEqual(self.evaluate(attrs), attrs)