chore(npins): Update SRI patch
All checks were successful
Check meta / check_meta (pull_request) Successful in 15s
Check meta / check_dns (pull_request) Successful in 15s
Check workflows / check_workflows (pull_request) Successful in 17s
Run pre-commit on all files / pre-commit (pull_request) Successful in 28s
Build all the nodes / ap01 (pull_request) Successful in 37s
Build all the nodes / bridge01 (pull_request) Successful in 43s
Build all the nodes / cof02 (pull_request) Successful in 47s
Build all the nodes / build01 (pull_request) Successful in 51s
Build all the nodes / geo01 (pull_request) Successful in 51s
Build all the nodes / compute01 (pull_request) Successful in 1m12s
Build all the nodes / geo02 (pull_request) Successful in 45s
Build all the nodes / hypervisor01 (pull_request) Successful in 43s
Build all the nodes / hypervisor02 (pull_request) Successful in 43s
Build all the nodes / hypervisor03 (pull_request) Successful in 42s
Build all the nodes / iso (pull_request) Successful in 52s
Build all the nodes / netaccess01 (pull_request) Successful in 20s
Build all the nodes / lab-router01 (pull_request) Successful in 43s
Build all the nodes / netcore00 (pull_request) Successful in 20s
Build all the nodes / netcore01 (pull_request) Successful in 20s
Build all the nodes / netcore02 (pull_request) Successful in 21s
Build all the nodes / krz01 (pull_request) Successful in 1m28s
Build all the nodes / tower01 (pull_request) Successful in 1m14s
Build all the nodes / rescue01 (pull_request) Successful in 1m25s
Build all the nodes / vault01 (pull_request) Successful in 57s
Build all the nodes / storage01 (pull_request) Successful in 1m24s
Build all the nodes / web02 (pull_request) Successful in 47s
Build all the nodes / web03 (pull_request) Successful in 50s
Build all the nodes / web01 (pull_request) Successful in 1m5s
Build the shell / build-shell (pull_request) Successful in 57s
Run pre-commit on all files / pre-commit (push) Successful in 29s
Build all the nodes / ap01 (push) Successful in 38s
Build all the nodes / bridge01 (push) Successful in 51s
Build all the nodes / geo01 (push) Successful in 51s
Build all the nodes / hypervisor01 (push) Successful in 52s
Build all the nodes / geo02 (push) Successful in 54s
Build all the nodes / cof02 (push) Successful in 57s
Build all the nodes / build01 (push) Successful in 58s
Build all the nodes / compute01 (push) Successful in 1m14s
Build all the nodes / netaccess01 (push) Successful in 21s
Build all the nodes / netcore00 (push) Successful in 22s
Build all the nodes / hypervisor02 (push) Successful in 43s
Build all the nodes / netcore01 (push) Successful in 21s
Build all the nodes / hypervisor03 (push) Successful in 45s
Build all the nodes / netcore02 (push) Successful in 21s
Build all the nodes / lab-router01 (push) Successful in 46s
Build all the nodes / iso (push) Successful in 54s
Build all the nodes / rescue01 (push) Successful in 55s
Build all the nodes / tower01 (push) Successful in 52s
Build all the nodes / krz01 (push) Successful in 1m35s
Build all the nodes / vault01 (push) Successful in 57s
Build all the nodes / web02 (push) Successful in 48s
Build all the nodes / web01 (push) Successful in 1m3s
Build the shell / build-shell (push) Successful in 22s
Build all the nodes / storage01 (push) Successful in 1m38s
Build all the nodes / web03 (push) Successful in 47s

This commit is contained in:
Tom Hubrecht 2025-05-12 10:37:55 +02:00
parent 10f5322016
commit c299614b50
Signed by: thubrecht
SSH key fingerprint: SHA256:r+nK/SIcWlJ0zFZJGHtlAoRwq1Rm+WcKAm5ADYMoQPc
8 changed files with 1381 additions and 616 deletions

View file

@ -13,7 +13,7 @@
"submodules": false,
"version": "0.15.0",
"revision": "564595d0ad4be7277e07fa63b5a991b3c645655d",
"url": "https://api.github.com/repos/ryantm/agenix/tarball/0.15.0",
"url": "https://api.github.com/repos/ryantm/agenix/tarball/refs/tags/0.15.0",
"hash": "sha256-ipqShkBmHKC9ft1ZAsA6aeKps32k7+XZSPwfxeHLsAU="
},
"arkheon": {
@ -91,7 +91,7 @@
"submodules": false,
"version": "v1.11.0",
"revision": "cdf8deded8813edfa6e65544f69fdd3a59fa2bb4",
"url": "https://api.github.com/repos/nix-community/disko/tarball/v1.11.0",
"url": "https://api.github.com/repos/nix-community/disko/tarball/refs/tags/v1.11.0",
"hash": "sha256-ItkIZyebGvNH2dK9jVGzJHGPtb6BSWLN8Gmef16NeY0="
},
"dns.nix": {
@ -107,7 +107,7 @@
"submodules": false,
"version": "v1.2.0",
"revision": "a3196708a56dee76186a9415c187473b94e6cbae",
"url": "https://api.github.com/repos/nix-community/dns.nix/tarball/v1.2.0",
"url": "https://api.github.com/repos/nix-community/dns.nix/tarball/refs/tags/v1.2.0",
"hash": "sha256-IK3r16N9pizf53AipOmrcrcyjVsPJwC4PI5hIqEyKwQ="
},
"git-hooks": {
@ -279,19 +279,19 @@
"type": "Channel",
"name": "nixos-24.05",
"url": "https://releases.nixos.org/nixos/24.05/nixos-24.05.7376.b134951a4c9f/nixexprs.tar.xz",
"hash": "1f8j7fh0nl4qmqlxn6lis8zf7dnckm6jri4rwmj0qm1qivhr58lv"
"hash": "sha256-m6KS4Y44VAxk5ZnELE2dzLbjPtKRGtsprphQC6A7Erk="
},
"nixos-24.11": {
"type": "Channel",
"name": "nixos-24.11",
"url": "https://releases.nixos.org/nixos/24.11/nixos-24.11.717608.bf3287dac860/nixexprs.tar.xz",
"hash": "1qf7ccpbad2p58q894g4zij3nvsqw503615apjb3iz06yribbrwb"
"hash": "sha256-i+e1YvYG/DiWvKoEM0DhWG87ZPzkkYQwKlc0tS5jx+E="
},
"nixos-unstable": {
"type": "Channel",
"name": "nixos-unstable",
"url": "https://releases.nixos.org/nixos/unstable/nixos-25.05pre785698.b024ced1aac2/nixexprs.tar.xz",
"hash": "1bb0wz4yc87dmpc37pp6yirdqlaj3hfiny21mk9v4bzfkhbslqwz"
"hash": "sha256-n2OqF5zuL7LTrEF4Gx0cUlHccvTm3jPYre0g5snnYK0="
},
"npins": {
"type": "GitRelease",
@ -304,10 +304,10 @@
"version_upper_bound": null,
"release_prefix": null,
"submodules": false,
"version": "0.3.0",
"revision": "6cc1930e703698487bd703258126435a536ca492",
"url": "https://api.github.com/repos/andir/npins/tarball/0.3.0",
"hash": "sha256-nTm6IqCHNFQLU7WR7dJRP7ktBctpE/O2LHbUV25roJA="
"version": "0.3.1",
"revision": "476671559d5879ad2f95fe21b9eb7c7541b3e718",
"url": "https://api.github.com/repos/andir/npins/tarball/refs/tags/0.3.1",
"hash": "sha256-PPk9Ve1pM3X7NfGeGb8Jiq4YDEwAjErP4xzGwLaakTU="
},
"proxmox-nixos": {
"type": "Git",

View file

@ -46,10 +46,7 @@ with {
];
"npins" = [
(local ./npins/01-libnpins-1.patch)
(local ./npins/01-libnpins-2.patch)
(local ./npins/01-libnpins-3.patch)
(local ./npins/01-libnpins-4.patch)
(local ./npins/02-git-narHash.patch)
(local ./npins/00-master.patch)
(local ./npins/01-sri-hashes.patch)
];
}

File diff suppressed because it is too large Load diff

View file

@ -1,40 +0,0 @@
From 8bfcd4881322ddda5daa46114272d0f41478214e Mon Sep 17 00:00:00 2001
From: piegames <git@piegames.de>
Date: Mon, 3 Mar 2025 10:31:53 +0100
Subject: [PATCH 1/4] Fix visibility modifiers
---
src/main.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index d6c2610..0b700cc 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -139,7 +139,7 @@ macro_rules! mkPin {
})*
/* If an error is returned, `self` remains unchanged */
- async fn update(&mut self) -> Result<Vec<diff::DiffEntry>> {
+ pub async fn update(&mut self) -> Result<Vec<diff::DiffEntry>> {
Ok(match self {
$(Self::$name { input, version, .. } => {
/* Use very explicit syntax to force the correct types and get good compile errors */
@@ -152,7 +152,7 @@ macro_rules! mkPin {
/* If an error is returned, `self` remains unchanged. This returns a double result: the outer one
* indicates that `update` should be called first, the inner is from the actual operation.
*/
- async fn fetch(&mut self) -> Result<Vec<diff::DiffEntry>> {
+ pub async fn fetch(&mut self) -> Result<Vec<diff::DiffEntry>> {
Ok(match self {
$(Self::$name { input, version, hashes, .. } => {
let version = version.as_ref()
@@ -259,7 +259,7 @@ mkPin! {
/// For serialization purposes, use the `NixPinsVersioned` wrapper instead.
#[derive(Debug, Serialize, Deserialize, Clone, Default, PartialEq, Eq)]
pub struct NixPins {
- pins: BTreeMap<String, Pin>,
+ pub pins: BTreeMap<String, Pin>,
}
impl NixPins {

View file

@ -1,173 +0,0 @@
From 9d497f4efd7c25842b737478f6582abff2e8b1cd Mon Sep 17 00:00:00 2001
From: piegames <git@piegames.de>
Date: Wed, 12 Mar 2025 22:13:29 +0100
Subject: [PATCH 2/4] libnpins: Init
---
.github/workflows/test.yml | 6 +++++-
Cargo.toml | 20 +++++++++++++++++---
npins.nix | 7 +++++++
src/cli.rs | 22 +++++++++++++++++++++-
src/main.rs | 22 ----------------------
5 files changed, 50 insertions(+), 27 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 04db4ec..ecc0878 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,10 +13,14 @@ jobs:
- uses: DeterminateSystems/nix-installer-action@v10
- name: Build
run: nix-build
+ - name: Cargo Build Lib
+ run: nix-shell --run "cargo build --lib"
+ - name: Cargo Build CLI
+ run: nix-shell --run "cargo build --bin npins --features=clap,crossterm,env_logger"
- name: Run pre-commit hooks
run: nix-shell --run "pre-commit run --all"
- name: Cargo test
- run: nix-shell --run "cargo test"
+ run: nix-shell --run "cargo test --all"
- name: Test dev shell
# Simple check that the pins in the current repository are still working.
# Importantly, this will fail on any version mismatch, indicating that versions need to be upgraded.
diff --git a/Cargo.toml b/Cargo.toml
index c0d8be3..9b855bb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,20 +4,34 @@ version = "0.3.0"
edition = "2021"
license = "EUPL-1.2"
+[lib]
+name = "npins"
+path = "src/main.rs"
+
+[[bin]]
+name = "npins"
+path = "src/cli.rs"
+required-features = [ "clap", "crossterm", "env_logger" ]
+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "^1.0", features = [ "derive" ] }
serde_json = { version = "^1.0", features = ["preserve_order"] }
url = { version = "^2.2.2", features = [ "serde" ] }
-clap = { version = "4.5", features = [ "derive", "env" ] }
anyhow = "^1.0"
tokio = { version = "^1.0", features = ["macros", "rt-multi-thread", "process"] }
-env_logger = { version = "^0.11.0", features = ["color", "auto-color", "regex"], default-features = false }
log = "^0.4"
reqwest = { version = "^0.12.0", features = [ "rustls-tls" ], default-features = false }
async-trait = "0.1.52"
lenient_semver_parser = { version = "0.4.2", default-features = false }
lenient_version = { version = "0.4.2" }
futures = "0.3.31"
-crossterm = { version = "0.28.1", default-features = false }
+
+# CLI dependencies
+clap = { version = "4.5", features = [ "derive", "env" ], optional = true }
+crossterm = { version = "0.28.1", default-features = false, optional = true }
+env_logger = { version = "^0.11.0", features = ["color", "auto-color", "regex"], default-features = false, optional = true }
+
+[dev-dependencies]
+env_logger = { version = "^0.11.0", features = ["color", "auto-color", "regex"], default-features = false }
diff --git a/npins.nix b/npins.nix
index b51871f..912d431 100644
--- a/npins.nix
+++ b/npins.nix
@@ -58,6 +58,13 @@ let
buildInputs = lib.optional stdenv.isDarwin (with darwin.apple_sdk.frameworks; [ Security ]);
nativeBuildInputs = [ makeWrapper ];
+ cargoBuildFlags = [
+ "--bin"
+ "npins"
+ "--features"
+ "clap,crossterm,env_logger"
+ ];
+
# (Almost) all tests require internet
doCheck = false;
diff --git a/src/cli.rs b/src/cli.rs
index a689658..3f5a347 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,6 +1,8 @@
//! The main CLI application
+use std::collections::BTreeMap;
+use std::path::PathBuf;
-use super::*;
+use npins::*;
use std::{
collections::BTreeSet,
@@ -1097,3 +1099,21 @@ impl Opts {
Ok(())
}
}
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ let opts = Opts::parse();
+
+ env_logger::builder()
+ .filter_level(if opts.verbose {
+ log::LevelFilter::Debug
+ } else {
+ log::LevelFilter::Info
+ })
+ .format_timestamp(None)
+ .format_target(false)
+ .init();
+
+ opts.run().await?;
+ Ok(())
+}
diff --git a/src/main.rs b/src/main.rs
index 0b700cc..46b7a5f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,14 +1,10 @@
-use std::path::PathBuf;
-
use anyhow::Result;
-use clap::Parser;
use diff::{Diff, OptionExt};
use reqwest::IntoUrl;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
pub mod channel;
-pub mod cli;
pub mod diff;
pub mod flake;
pub mod git;
@@ -348,24 +344,6 @@ impl diff::Diff for GenericUrlHashes {
}
}
-#[tokio::main]
-async fn main() -> Result<()> {
- let opts = cli::Opts::parse();
-
- env_logger::builder()
- .filter_level(if opts.verbose {
- log::LevelFilter::Debug
- } else {
- log::LevelFilter::Info
- })
- .format_timestamp(None)
- .format_target(false)
- .init();
-
- opts.run().await?;
- Ok(())
-}
-
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,31 +0,0 @@
From 7aa1804eb6fa5557b79ca20effb7d9cd1226e10f Mon Sep 17 00:00:00 2001
From: piegames <git@piegames.de>
Date: Wed, 12 Mar 2025 22:06:40 +0100
Subject: [PATCH 3/4] =?UTF-8?q?Rename=20main.rs=20=E2=86=92=20lib.rs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Cargo.toml | 2 +-
src/{main.rs => lib.rs} | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename src/{main.rs => lib.rs} (100%)
diff --git a/Cargo.toml b/Cargo.toml
index 9b855bb..3ffb414 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,7 +6,7 @@ license = "EUPL-1.2"
[lib]
name = "npins"
-path = "src/main.rs"
+path = "src/lib.rs"
[[bin]]
name = "npins"
diff --git a/src/main.rs b/src/lib.rs
similarity index 100%
rename from src/main.rs
rename to src/lib.rs

View file

@ -1,79 +0,0 @@
From 8e21005d54b4232db16218c1d0a27982b1297747 Mon Sep 17 00:00:00 2001
From: piegames <git@piegames.de>
Date: Mon, 3 Mar 2025 11:13:14 +0100
Subject: [PATCH 4/4] Small API cleanup
---
src/cli.rs | 4 ++--
src/lib.rs | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/cli.rs b/src/cli.rs
index 3f5a347..853c2ec 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -610,7 +610,7 @@ impl Opts {
path.display()
)
})?);
- versions::from_value_versioned(serde_json::from_reader(fh)?)
+ NixPins::from_json_versioned(serde_json::from_reader(fh)?)
.context("Failed to deserialize sources.json")
}
@@ -625,7 +625,7 @@ impl Opts {
};
let mut fh = std::fs::File::create(&path)
.with_context(move || format!("Failed to open {} for writing.", path.display()))?;
- serde_json::to_writer_pretty(&mut fh, &versions::to_value_versioned(pins))?;
+ serde_json::to_writer_pretty(&mut fh, &pins.to_value_versioned())?;
fh.write_all(b"\n")?;
Ok(())
}
diff --git a/src/lib.rs b/src/lib.rs
index 46b7a5f..f30521d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,8 @@
+//! The npins library
+//!
+//! Currently, it pretty much exposes the internals of the CLI 1:1, but in the future
+//! this is supposed to evolve into a more standalone library.
+
use anyhow::Result;
use diff::{Diff, OptionExt};
use reqwest::IntoUrl;
@@ -15,6 +20,7 @@ pub mod tarball;
pub mod versions;
/// Helper method to build you a client.
+// TODO make injectable via a configuration mechanism
pub fn build_client() -> Result<reqwest::Client, reqwest::Error> {
reqwest::Client::builder()
.user_agent(concat!(
@@ -259,6 +265,7 @@ pub struct NixPins {
}
impl NixPins {
+ /// Create a new `NixPins` with a pin `nixpkgs` pointing to the `nixpkgs-unstable` channel
pub fn new_with_nixpkgs() -> Self {
let mut pins = BTreeMap::new();
pins.insert(
@@ -267,6 +274,16 @@ impl NixPins {
);
Self { pins }
}
+
+ /// Custom manual deserialize wrapper that checks the version
+ pub fn from_json_versioned(value: serde_json::Value) -> Result<Self> {
+ versions::from_value_versioned(value)
+ }
+
+ /// Custom manual serialize wrapper that adds a version field
+ pub fn to_value_versioned(&self) -> serde_json::Value {
+ versions::to_value_versioned(self)
+ }
}
/// Just a version string

View file

@ -1,21 +1,29 @@
From 3d714ed94a08b13ea7f8f225c8547c98215bd963 Mon Sep 17 00:00:00 2001
From 6d86eb4b9884f46a38baaafd6a048cbfdc6a6b9b Mon Sep 17 00:00:00 2001
From: Tom Hubrecht <tom@hubrecht.ovh>
Date: Tue, 6 May 2025 18:32:31 +0200
Subject: [PATCH 1/3] feat: Use narHash for Git sources
Subject: [PATCH] feat: Use SRI hashes for locking pins
Here, we:
- Switch to using SRI hashes for all locked inputs
- Add support for narHash in fetchGit
It is a follow-up of #87 using snix nix-compat crate for manipulating
hashes
Co-authored-by: Raito Bezarius <masterancpp@gmail.com>
---
Cargo.lock | 373 ++++++++++++++++++++++++++++++++++++++++++++++++
Cargo.lock | 386 +++++++++++++++++++++++++++++++++++++++++++++++-
Cargo.toml | 2 +
npins.nix | 4 +
src/default.nix | 10 +-
src/nix.rs | 14 +-
src/versions.rs | 34 ++++-
6 files changed, 430 insertions(+), 7 deletions(-)
src/git.rs | 22 +--
src/nix.rs | 20 ++-
src/pypi.rs | 20 ++-
src/versions.rs | 40 +++--
8 files changed, 466 insertions(+), 38 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 21f2e5b..7186269 100644
index fc0b0df..6345d09 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -120,12 +120,38 @@ version = "0.22.1"
@ -221,7 +229,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "getrandom"
version = "0.2.15"
@@ -388,6 +543,12 @@ version = "0.31.1"
@@ -402,6 +557,12 @@ version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
@ -234,9 +242,9 @@ index 21f2e5b..7186269 100644
[[package]]
name = "hashbrown"
version = "0.15.2"
@@ -704,6 +865,16 @@ version = "0.2.171"
@@ -719,6 +880,16 @@ version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
+[[package]]
+name = "libmimalloc-sys"
@ -251,7 +259,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
@@ -738,6 +909,15 @@ version = "2.7.4"
@@ -753,6 +924,15 @@ version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
@ -267,14 +275,14 @@ index 21f2e5b..7186269 100644
[[package]]
name = "mime"
version = "0.3.17"
@@ -764,6 +944,53 @@ dependencies = [
@@ -779,6 +959,53 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "nix-compat"
+version = "0.1.0"
+source = "git+https://git.snix.dev/snix/snix#8903fbb9752edfee02499319ea61a6f291eff608"
+source = "git+https://git.snix.dev/snix/snix#4749964f06a7aa20ee19c5f7b3c97079e5c67911"
+dependencies = [
+ "bitflags",
+ "bstr",
@ -302,7 +310,7 @@ index 21f2e5b..7186269 100644
+[[package]]
+name = "nix-compat-derive"
+version = "0.1.0"
+source = "git+https://git.snix.dev/snix/snix#8903fbb9752edfee02499319ea61a6f291eff608"
+source = "git+https://git.snix.dev/snix/snix#4749964f06a7aa20ee19c5f7b3c97079e5c67911"
+dependencies = [
+ "proc-macro2",
+ "quote",
@ -320,8 +328,8 @@ index 21f2e5b..7186269 100644
+
[[package]]
name = "npins"
version = "0.3.0"
@@ -772,11 +999,13 @@ dependencies = [
version = "0.3.1"
@@ -787,11 +1014,13 @@ dependencies = [
"async-trait",
"clap",
"crossterm",
@ -335,7 +343,7 @@ index 21f2e5b..7186269 100644
"reqwest",
"serde",
"serde_json",
@@ -784,6 +1013,36 @@ dependencies = [
@@ -799,6 +1028,36 @@ dependencies = [
"url",
]
@ -372,7 +380,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "object"
version = "0.36.7"
@@ -840,6 +1099,16 @@ version = "0.1.0"
@@ -855,6 +1114,16 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
@ -389,7 +397,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@@ -849,6 +1118,15 @@ dependencies = [
@@ -864,6 +1133,15 @@ dependencies = [
"zerocopy",
]
@ -405,7 +413,34 @@ index 21f2e5b..7186269 100644
[[package]]
name = "proc-macro2"
version = "1.0.94"
@@ -1056,6 +1334,15 @@ version = "2.1.1"
@@ -949,7 +1227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha",
- "rand_core",
+ "rand_core 0.9.3",
"zerocopy",
]
@@ -960,7 +1238,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
- "rand_core",
+ "rand_core 0.9.3",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom 0.2.15",
]
[[package]]
@@ -1079,6 +1366,15 @@ version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
@ -421,7 +456,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "rustix"
version = "0.38.44"
@@ -1130,6 +1417,12 @@ version = "1.2.0"
@@ -1153,6 +1449,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
@ -434,7 +469,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "serde"
version = "1.0.219"
@@ -1175,6 +1468,17 @@ dependencies = [
@@ -1198,6 +1500,17 @@ dependencies = [
"serde",
]
@ -452,7 +487,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "shlex"
version = "1.3.0"
@@ -1190,6 +1494,15 @@ dependencies = [
@@ -1213,6 +1526,15 @@ dependencies = [
"libc",
]
@ -462,13 +497,13 @@ index 21f2e5b..7186269 100644
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+dependencies = [
+ "rand_core",
+ "rand_core 0.6.4",
+]
+
[[package]]
name = "slab"
version = "0.4.9"
@@ -1215,6 +1528,16 @@ dependencies = [
@@ -1238,6 +1560,16 @@ dependencies = [
"windows-sys 0.52.0",
]
@ -485,7 +520,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@@ -1347,6 +1670,23 @@ dependencies = [
@@ -1370,6 +1702,23 @@ dependencies = [
"tokio",
]
@ -509,7 +544,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "tower"
version = "0.5.2"
@@ -1381,9 +1721,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1404,9 +1753,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
@ -531,7 +566,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "tracing-core"
version = "0.1.33"
@@ -1399,6 +1751,12 @@ version = "0.2.5"
@@ -1422,6 +1783,12 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
@ -544,7 +579,7 @@ index 21f2e5b..7186269 100644
[[package]]
name = "unicode-ident"
version = "1.0.18"
@@ -1441,6 +1799,12 @@ version = "0.2.2"
@@ -1464,6 +1831,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
@ -557,24 +592,24 @@ index 21f2e5b..7186269 100644
[[package]]
name = "want"
version = "0.3.1"
@@ -1737,6 +2101,15 @@ version = "0.53.0"
@@ -1769,6 +2142,15 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+[[package]]
+name = "winnow"
+version = "0.7.9"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
+checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "write16"
version = "1.0.0"
name = "wit-bindgen-rt"
version = "0.39.0"
diff --git a/Cargo.toml b/Cargo.toml
index 3ffb414..0b6909c 100644
index b603f77..badbe24 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,6 +32,8 @@ futures = "0.3.31"
@ -587,7 +622,7 @@ index 3ffb414..0b6909c 100644
[dev-dependencies]
env_logger = { version = "^0.11.0", features = ["color", "auto-color", "regex"], default-features = false }
diff --git a/npins.nix b/npins.nix
index 912d431..10d0edc 100644
index 912d431..dfdcda8 100644
--- a/npins.nix
+++ b/npins.nix
@@ -51,6 +51,10 @@ let
@ -596,7 +631,7 @@ index 912d431..10d0edc 100644
lockFile = src + "/Cargo.lock";
+
+ outputHashes = {
+ "nix-compat-0.1.0" = "sha256-QmOI/LsjwVNGo2xjtH5BDkt/93hC+VxtpK5O5XJQ3Gw=";
+ "nix-compat-0.1.0" = "sha256-U9pAde6R2yoP8ivnoNX/1rve+ALrDk8+4R2BKoGzg24=";
+ };
};
@ -636,24 +671,126 @@ index 6592476..fc9ebc5 100644
builtins.mapAttrs mkSource data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"
diff --git a/src/git.rs b/src/git.rs
index 334e9d1..c7c5241 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -852,7 +852,7 @@ mod test {
pin.fetch(&version).await?,
OptionalUrlHashes {
url: None,
- hash: "17giznxp84h53jsm334dkp1fz6x9ff2yqfkq34ihq0ray1x3yhyd".into(),
+ hash: "sha256-zUM/evAqAwwjGXg67IVzqZvvwp2NjFG1HAUSdLv98Z0=".into(),
}
);
Ok(())
@@ -880,7 +880,7 @@ mod test {
pin.fetch(&version).await?,
ReleasePinHashes {
url: None,
- hash: "0q06gjh6129bfs0x072xicmq0q2psnq6ckf05p1jfdxwl7jljg06".into(),
+ hash: "sha256-BjxJ5aG8NyfDLcBNZrDVV2CAK4tdHNCBdiuJYKB8BmA=".into(),
revision: "35be5b2b2c3431de1100996487d53134f658b866".into(),
}
);
@@ -908,7 +908,7 @@ mod test {
pin.fetch(&version).await?,
OptionalUrlHashes {
url: Some("https://github.com/oliverwatkins/swing_library/archive/1edb0a9cebe046cc915a218c57dbf7f40739aeee.tar.gz".parse().unwrap()),
- hash: "17giznxp84h53jsm334dkp1fz6x9ff2yqfkq34ihq0ray1x3yhyd".into(),
+ hash: "sha256-zUM/evAqAwwjGXg67IVzqZvvwp2NjFG1HAUSdLv98Z0=".into(),
}
);
Ok(())
@@ -942,7 +942,7 @@ mod test {
.parse()
.unwrap()
),
- hash: "0q06gjh6129bfs0x072xicmq0q2psnq6ckf05p1jfdxwl7jljg06".into(),
+ hash: "sha256-BjxJ5aG8NyfDLcBNZrDVV2CAK4tdHNCBdiuJYKB8BmA=".into(),
}
);
Ok(())
@@ -976,7 +976,7 @@ mod test {
.parse()
.unwrap()
),
- hash: "0arqpja90n3yy767x0ckwg4biqm4igcpa0vznvx3daaywjkb1v7v".into(),
+ hash: "sha256-++ywpuReqTb6tn8DddmLpOK4yOOTgX7M8X5YkJS8OCs=".into(),
}
);
Ok(())
@@ -1004,7 +1004,7 @@ mod test {
pin.fetch(&version).await?,
OptionalUrlHashes {
url: Some("https://git.lix.systems/lix-project/lix/archive/4bbdb2f5564b9b42bcaf0e1eec28325300f31c72.tar.gz".parse().unwrap()),
- hash: "03rygh7i9wzl6mhha6cv5q26iyzwy8l59d5cq4r6j5kpss9l1hn3".into(),
+ hash: "sha256-w8JAk9Z3Fmkyway0VCjy/PtoBC6bGQVhNfTzFA98Pg8=".into(),
}
);
Ok(())
@@ -1039,7 +1039,7 @@ mod test {
.parse()
.unwrap()
),
- hash: "1iyylsiv1n6mf6rbi4k4fm5nv24a940cwfz92gk9fx6axh2kxjbz".into(),
+ hash: "sha256-f8k+BezKdJfmE+k7zgBJiohtS3VkkriycdXYsKOm3sc=".into(),
}
);
Ok(())
@@ -1067,7 +1067,7 @@ mod test {
pin.fetch(&version).await?,
OptionalUrlHashes {
url: Some("https://gitlab.com/api/v4/projects/maxigaz%2Fgitlab-dark/repository/archive.tar.gz?sha=e7145078163692697b843915a665d4f41139a65c".parse().unwrap()),
- hash: "0nmcr0g0cms4yx9wsgbyvxyvdlqwa9qdb8179g47rs0y04iylcsv".into(),
+ hash: "sha256-WzPqIwEe6HzISyeg1XBSHNO2fd9+Pc1T90RXBh7IrFo=".into(),
}
);
Ok(())
@@ -1100,7 +1100,7 @@ mod test {
url: Some("https://gitlab.com/api/v4/projects/maxigaz%2Fgitlab-dark/repository/archive.tar.gz?ref=v1.16.0"
.parse()
.unwrap()),
- hash: "0nmcr0g0cms4yx9wsgbyvxyvdlqwa9qdb8179g47rs0y04iylcsv".into(),
+ hash: "sha256-WzPqIwEe6HzISyeg1XBSHNO2fd9+Pc1T90RXBh7IrFo=".into(),
}
);
Ok(())
@@ -1128,7 +1128,7 @@ mod test {
pin.fetch(&version).await?,
OptionalUrlHashes {
url: Some("https://gitlab.gnome.org/api/v4/projects/Archive%2Fgnome-games/repository/archive.tar.gz?sha=bca2071b6923d45d9aabac27b3ea1e40f5fa3006".parse().unwrap()),
- hash: "0pn7mdj56flvvlhm96igx8g833sslzgypfb2a4zv7lj8z3kiikmg".into(),
+ hash: "sha256-r84Y5/hI0rM/UWK569+nWo+BHuovmlQh3Zs6U2Srx14=".into(),
}
);
Ok(())
@@ -1159,7 +1159,7 @@ mod test {
ReleasePinHashes {
revision: "2c89145d52d072a4ca5da900c2676d890bfab1ff".into(),
url: Some("https://gitlab.gnome.org/api/v4/projects/Archive%2Fgnome-games/repository/archive.tar.gz?ref=40.0".parse().unwrap()),
- hash: "0pn7mdj56flvvlhm96igx8g833sslzgypfb2a4zv7lj8z3kiikmg".into(),
+ hash: "sha256-r84Y5/hI0rM/UWK569+nWo+BHuovmlQh3Zs6U2Srx14=".into(),
}
);
Ok(())
diff --git a/src/nix.rs b/src/nix.rs
index 0bde5b2..41a67da 100644
index 2248079..499e0e7 100644
--- a/src/nix.rs
+++ b/src/nix.rs
@@ -1,5 +1,7 @@
@@ -1,5 +1,6 @@
use crate::check_url;
use anyhow::{Context, Result};
+use data_encoding::BASE64;
use log::debug;
+use nix_compat::nixhash::from_str;
#[allow(unused)]
pub struct PrefetchInfo {
@@ -38,6 +40,16 @@ pub async fn nix_prefetch_tarball(url: impl AsRef<str>) -> Result<String> {
Ok(String::from(stdout.trim()))
@@ -8,6 +9,16 @@ pub struct PrefetchInfo {
hash: String,
}
+pub fn hash_to_sri(s: &str, algo: &str) -> Result<String> {
+ let hash = from_str(s, Some(algo))?;
+ let hash = nix_compat::nixhash::from_str(s, Some(algo))?;
+
+ Ok(format!(
+ "{}-{}",
@ -662,18 +799,83 @@ index 0bde5b2..41a67da 100644
+ ))
+}
+
pub async fn nix_prefetch_tarball(url: impl AsRef<str>) -> Result<String> {
let url = url.as_ref();
check_url(url).await?;
@@ -37,8 +48,11 @@ pub async fn nix_prefetch_tarball(url: impl AsRef<str>) -> Result<String> {
}
let stdout = String::from_utf8_lossy(&output.stdout);
- log::debug!("Got hash: {}", stdout);
- Ok(String::from(stdout.trim()))
+ let hash = stdout.trim();
+
+ log::debug!("Got sha256: {}", hash);
+
+ hash_to_sri(&hash, "sha256")
}
pub async fn nix_prefetch_git(
url: impl AsRef<str>,
git_ref: impl AsRef<str>,
@@ -105,5 +117,5 @@ pub async fn nix_prefetch_git(
@@ -111,5 +125,5 @@ pub async fn nix_prefetch_git(
let info: NixPrefetchGitResponse = serde_json::from_slice(&output.stdout)
.context("Failed to deserialize nix-pfetch-git JSON response.")?;
- Ok(info.sha256)
+ hash_to_sri(&info.sha256, "sha256")
}
diff --git a/src/pypi.rs b/src/pypi.rs
index 51191d2..5d744ef 100644
--- a/src/pypi.rs
+++ b/src/pypi.rs
@@ -1,6 +1,6 @@
//! Pin a PyPi package
-use crate::*;
+use crate::{nix::hash_to_sri, *};
use anyhow::{Context, Result};
use lenient_version::Version;
use serde::{Deserialize, Serialize};
@@ -125,11 +125,15 @@ impl Updatable for Pin {
anyhow::format_err!("Unsupported package: must contain some \"source\" download",)
})?;
- let hash = latest_source.digests.remove("sha256").ok_or_else(|| {
- anyhow::format_err!(
- "JSON metadata is invalid: must contain a `sha256` entry within `digests`",
- )
- })?;
+ let hash = latest_source
+ .digests
+ .remove("sha256")
+ .ok_or_else(|| {
+ anyhow::format_err!(
+ "JSON metadata is invalid: must contain a `sha256` entry within `digests`",
+ )
+ })
+ .and_then(|s| hash_to_sri(&s, "sha256"))?;
Ok(GenericUrlHashes {
hash,
@@ -190,7 +194,7 @@ mod test {
assert_eq!(
pin.fetch(&version).await?,
GenericUrlHashes {
- hash: "3953b158b7b690642d68cd6beb1d59f6e10526f2ee10a6fb4636a913cc95e718".into(),
+ hash: "sha256-OVOxWLe2kGQtaM1r6x1Z9uEFJvLuEKb7RjapE8yV5xg=".into(),
url: "https://files.pythonhosted.org/packages/d1/d5/0c270c22d61ff6b883d0f24956f13e904b131b5ac2829e0af1cda99d70b1/gaiatest-0.34.tar.gz".parse().unwrap(),
}
);
@@ -216,7 +220,7 @@ mod test {
assert_eq!(
pin.fetch(&version).await?,
GenericUrlHashes {
- hash: "39d09c6627255fcf39c938937995665b6377799c4fa141f6b481bcb5e6a688ac".into(),
+ hash: "sha256-OdCcZiclX885yTiTeZVmW2N3eZxPoUH2tIG8teamiKw=".into(),
url: "https://files.pythonhosted.org/packages/fd/75/6e72889c3b154a179040b94963a50901966ff30b68600271df374b2ded7a/streamlit-0.89.0.tar.gz".parse().unwrap(),
}
);
diff --git a/src/versions.rs b/src/versions.rs
index 1317c48..6e8d43e 100644
index 003402f..a65c995 100644
--- a/src/versions.rs
+++ b/src/versions.rs
@@ -1,11 +1,12 @@
@ -690,235 +892,71 @@ index 1317c48..6e8d43e 100644
/// Custom manual deserialize wrapper that checks the version
pub fn from_value_versioned(value: Value) -> Result<NixPins> {
@@ -78,6 +79,37 @@ pub fn upgrade(mut pins_raw: Map<String, Value>) -> Result<Value> {
log::info!("There is nothing to do");
},
5 => {
+ let pins = pins_raw
+ .get_mut("pins")
+ .and_then(Value::as_object_mut)
+ .ok_or_else(|| anyhow::format_err!("sources.json must contain a `pins` object"))?;
+
+ for (name, pin) in pins.iter_mut() {
+ let raw_pin = pin
+ .as_object_mut()
+ .ok_or_else(|| anyhow::format_err!("Pin {} must be an object", name))?;
+ let pin: Pin = serde_json::from_value(serde_json::Value::Object(raw_pin.clone()))?;
+
+ if let Pin::Git { hashes, .. } = pin {
+ if let Some(url_hashes) = hashes {
+ log::debug!("Migrating Git hash of '{}' to SRI format", name);
+ let sri_hash = hash_to_sri("sha256", &url_hashes.hash)?;
+
+ raw_pin.remove("hash");
+ raw_pin.insert("hash".into(), sri_hash.into());
+ }
+ } else if let Pin::GitRelease { hashes, .. } = pin {
+ if let Some(url_hashes) = hashes {
+ log::debug!("Migrating GitRelease hash of '{}' to SRI format", name);
+ let sri_hash = hash_to_sri("sha256", &url_hashes.hash)?;
+
+ raw_pin.remove("hash");
+ raw_pin.insert("hash".into(), sri_hash.into());
+ }
+ }
+ }
+ },
+ 6 => {
log::info!("sources.json is already up to date");
},
unknown => {
From 688deb8064efd3a9b352517cf12d5b1c97074bd9 Mon Sep 17 00:00:00 2001
From: Tom Hubrecht <tom@hubrecht.ovh>
Date: Tue, 6 May 2025 18:40:49 +0200
Subject: [PATCH 2/3] chore: Update nixpkgs
This is necessary as nix-compat chain of dependencies requires cargo
1.85
---
npins/sources.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/npins/sources.json b/npins/sources.json
index 3256cac..d73cbb0 100644
--- a/npins/sources.json
+++ b/npins/sources.json
@@ -8,9 +8,9 @@
"repo": "nixpkgs"
},
"branch": "nixpkgs-unstable",
- "revision": "d9b69c3ec2a2e2e971c534065bdd53374bd68b97",
- "url": "https://github.com/nixos/nixpkgs/archive/d9b69c3ec2a2e2e971c534065bdd53374bd68b97.tar.gz",
- "hash": "111spkgprzsqd32mwzsjksk1hdzv10gyf04lh956vc1pp0g0fcq1"
+ "revision": "ed30f8aba41605e3ab46421e3dcb4510ec560ff8",
+ "url": "https://github.com/nixos/nixpkgs/archive/ed30f8aba41605e3ab46421e3dcb4510ec560ff8.tar.gz",
+ "hash": "0mg2wzzzakbb33z1a1qrlslr8q84j1ci9j53p9dj8nggmm2xv0p6"
},
"pre-commit-hooks.nix": {
"type": "Git",
From a682ba7acfb5a396db8fb111eb7f12317b1ba61a Mon Sep 17 00:00:00 2001
From: Tom Hubrecht <tom@hubrecht.ovh>
Date: Tue, 6 May 2025 19:00:39 +0200
Subject: [PATCH 3/3] fix: Make incremental upgrades to the JSON source
This simplifies logic, as only upgrades from one exact version to the
next is to consider.
---
src/versions.rs | 126 ++++++++++++++++++++++++++----------------------
1 file changed, 68 insertions(+), 58 deletions(-)
diff --git a/src/versions.rs b/src/versions.rs
index 6e8d43e..b5d4018 100644
--- a/src/versions.rs
+++ b/src/versions.rs
@@ -46,7 +46,7 @@ pub fn to_value_versioned(pins: &NixPins) -> serde_json::Value {
///
/// This operates on a JSON value level
pub fn upgrade(mut pins_raw: Map<String, Value>) -> Result<Value> {
- let version = pins_raw
+ let mut version = pins_raw
.get("version")
.and_then(Value::as_u64)
.ok_or_else(|| {
@@ -56,72 +56,82 @@ pub fn upgrade(mut pins_raw: Map<String, Value>) -> Result<Value> {
})?;
@@ -83,11 +84,18 @@ pub fn upgrade(mut pins_raw: Map<String, Value>) -> Result<Value> {
* They are omitted here; Only non-trivial upgrades should be inserted.
*/
type Upgrader = Box<dyn Fn(&mut Map<String, Value>) -> Result<()>>;
- let version_upgraders: BTreeMap<u64, Upgrader> = [(
- 0,
- Box::new(|pins_raw: &mut Map<String, Value>| generic_upgrader(pins_raw, upgrade_v0_pin))
- as Upgrader,
- )]
+ let version_upgraders: BTreeMap<u64, Upgrader> = [
+ (
+ 0,
+ Box::new(|pins_raw: &mut Map<String, Value>| generic_upgrader(pins_raw, upgrade_v0_pin))
+ as Upgrader,
+ ),
+ (
+ 5,
+ Box::new(|pins_raw: &mut Map<String, Value>| generic_upgrader(pins_raw, upgrade_v5_pin))
+ as Upgrader,
+ ),
+ ]
.into_iter()
.collect();
/* This is where the upgrading happens (at the moment we don't have any versions to upgrade from) */
- match version {
- 0 => {
- let pins = pins_raw
- .get_mut("pins")
- .and_then(Value::as_object_mut)
- .ok_or_else(|| anyhow::format_err!("sources.json must contain a `pins` object"))?;
- for (name, pin) in pins.iter_mut() {
- upgrade_v0_pin(
- name,
- pin.as_object_mut()
- .ok_or_else(|| anyhow::format_err!("Pin {} must be an object", name))?,
- )
- .context(anyhow::format_err!(
- "Pin {} could not be upgraded to the latest format version",
- name
- ))?;
- }
- },
- // All these versions are already handled by serde default fields
- 1 | 2 | 3 | 4 => {
- log::info!("There is nothing to do");
- },
- 5 => {
- let pins = pins_raw
- .get_mut("pins")
- .and_then(Value::as_object_mut)
- .ok_or_else(|| anyhow::format_err!("sources.json must contain a `pins` object"))?;
+ while version < LATEST {
+ match version {
+ 0 => {
+ let pins = pins_raw
+ .get_mut("pins")
+ .and_then(Value::as_object_mut)
+ .ok_or_else(|| {
+ anyhow::format_err!("sources.json must contain a `pins` object")
+ })?;
+ for (name, pin) in pins.iter_mut() {
+ upgrade_v0_pin(
+ name,
+ pin.as_object_mut()
+ .ok_or_else(|| anyhow::format_err!("Pin {} must be an object", name))?,
+ )
+ .context(anyhow::format_err!(
+ "Pin {} could not be upgraded to the latest format version",
+ name
+ ))?;
+ }
+ version = 1;
+ },
+ // All these versions are already handled by serde default fields
+ 1 | 2 | 3 | 4 => {
+ log::info!("There is nothing to do");
+ version = 5;
+ },
+ 5 => {
+ let pins = pins_raw
+ .get_mut("pins")
+ .and_then(Value::as_object_mut)
+ .ok_or_else(|| {
+ anyhow::format_err!("sources.json must contain a `pins` object")
+ })?;
- for (name, pin) in pins.iter_mut() {
- let raw_pin = pin
- .as_object_mut()
- .ok_or_else(|| anyhow::format_err!("Pin {} must be an object", name))?;
- let pin: Pin = serde_json::from_value(serde_json::Value::Object(raw_pin.clone()))?;
+ for (name, pin) in pins.iter_mut() {
+ let raw_pin = pin
+ .as_object_mut()
+ .ok_or_else(|| anyhow::format_err!("Pin {} must be an object", name))?;
+ let pin: Pin =
+ serde_json::from_value(serde_json::Value::Object(raw_pin.clone()))?;
- if let Pin::Git { hashes, .. } = pin {
- if let Some(url_hashes) = hashes {
- log::debug!("Migrating Git hash of '{}' to SRI format", name);
- let sri_hash = hash_to_sri("sha256", &url_hashes.hash)?;
+ if let Pin::Git { hashes, .. } = pin {
+ if let Some(url_hashes) = hashes {
+ log::debug!("Migrating Git hash of '{}' to SRI format", name);
+ let sri_hash = hash_to_sri(&url_hashes.hash, "sha256")?;
- raw_pin.remove("hash");
- raw_pin.insert("hash".into(), sri_hash.into());
- }
- } else if let Pin::GitRelease { hashes, .. } = pin {
- if let Some(url_hashes) = hashes {
- log::debug!("Migrating GitRelease hash of '{}' to SRI format", name);
- let sri_hash = hash_to_sri("sha256", &url_hashes.hash)?;
+ raw_pin.remove("hash");
+ raw_pin.insert("hash".into(), sri_hash.into());
+ }
+ } else if let Pin::GitRelease { hashes, .. } = pin {
+ if let Some(url_hashes) = hashes {
+ log::debug!("Migrating GitRelease hash of '{}' to SRI format", name);
+ let sri_hash = hash_to_sri(&url_hashes.hash, "sha256")?;
- raw_pin.remove("hash");
- raw_pin.insert("hash".into(), sri_hash.into());
+ raw_pin.remove("hash");
+ raw_pin.insert("hash".into(), sri_hash.into());
+ }
}
}
- }
- },
- 6 => {
- log::info!("sources.json is already up to date");
- },
- unknown => {
- anyhow::bail!(
- "Unknown format version {}, maybe try updating the application?",
- unknown
- );
- },
+ version = 6;
+ },
+ LATEST => {
+ log::info!("sources.json is already up to date");
+ },
+ unknown => {
+ anyhow::bail!(
+ "Unknown format version {}, maybe try updating the application?",
+ unknown
+ );
+ },
+ }
}
/* Set the new version */
- *pins_raw.get_mut("version").unwrap() = json!(LATEST);
+ *pins_raw.get_mut("version").unwrap() = json!(version);
Ok(serde_json::Value::Object(pins_raw))
@@ -224,6 +232,20 @@ fn upgrade_v0_pin(name: &str, raw_pin: &mut Map<String, Value>) -> Result<()> {
Ok(())
}
+/* v5→v6. This upgrade changes the hashes of git and git-release pins to use SRI hashes instead of
+ * raw sha256 hashes.
+ */
+fn upgrade_v5_pin(name: &str, raw_pin: &mut Map<String, Value>) -> Result<()> {
+ log::debug!("Updating {} to v6", name);
+
+ if let Some(raw_hash) = raw_pin.remove("hash") {
+ let hash: String = serde_json::from_value(raw_hash)?;
+ raw_pin.insert("hash".into(), hash_to_sri(&hash, "sha256")?.into());
+ }
+
+ Ok(())
+}
+
#[cfg(test)]
mod test {
use super::*;
@@ -301,19 +323,19 @@ mod test {
"nixos-mailserver".into() => Pin::Git {
input: git::GitPin::new(git::Repository::git("https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git".parse().unwrap()), "nixos-21.11".into(), false),
version: Some(git::GitRevision::new("6e3a7b2ea6f0d68b82027b988aa25d3423787303".into()).unwrap()),
- hashes: Some(git::OptionalUrlHashes { url: None, hash: "1i56llz037x416bw698v8j6arvv622qc0vsycd20lx3yx8n77n44".into() } ),
+ hashes: Some(git::OptionalUrlHashes { url: None, hash: "sha256-hNhzLOp+dApEY15vwLAQZu+sjEQbJcOXCaSfAT6lpsQ=".into() } ),
frozen: Frozen::default(),
},
"nixpkgs".into() => Pin::Git {
input: git::GitPin::new(git::Repository::github("nixos", "nixpkgs"), "nixpkgs-unstable".into(), false),
version: Some(git::GitRevision::new("5c37ad87222cfc1ec36d6cd1364514a9efc2f7f2".into()).unwrap()),
- hashes: Some(git::OptionalUrlHashes { url: Some("https://github.com/nixos/nixpkgs/archive/5c37ad87222cfc1ec36d6cd1364514a9efc2f7f2.tar.gz".parse().unwrap()), hash: "1r74afnalgcbpv7b9sbdfbnx1kfj0kp1yfa60bbbv27n36vqdhbb".into() }),
+ hashes: Some(git::OptionalUrlHashes { url: Some("https://github.com/nixos/nixpkgs/archive/5c37ad87222cfc1ec36d6cd1364514a9efc2f7f2.tar.gz".parse().unwrap()), hash: "sha256-a8GGtxn2iL3WAkY5H+4E0s3Q7XJt6bTOvos9qqxT5OQ=".into() }),
frozen: Frozen::default(),
},
"streamlit".into() => Pin::PyPi {
input: pypi::Pin { name: "streamlit".into(), version_upper_bound: None },
version: Some(GenericVersion { version: "1.3.1".into() }),
- hashes: Some(GenericUrlHashes { url: "https://files.pythonhosted.org/packages/c3/9d/ac871992617220442832af12c3808716f4349ab05ff939d695fe8b542f00/streamlit-1.3.1.tar.gz".parse().unwrap(), hash: "adec7935c9cf774b9115b2456cf2f48c4f49b9f67159a97db0fe228357c1afdf".into() } ),
+ hashes: Some(GenericUrlHashes { url: "https://files.pythonhosted.org/packages/c3/9d/ac871992617220442832af12c3808716f4349ab05ff939d695fe8b542f00/streamlit-1.3.1.tar.gz".parse().unwrap(), hash: "sha256-rex5NcnPd0uRFbJFbPL0jE9JufZxWal9sP4ig1fBr98=".into() } ),
frozen: Frozen::default(),
},
"youtube-dl".into() => Pin::GitRelease {