From 3e22655ffa68c680d649505a66a66729fe9186db Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 6 Dec 2025 15:44:20 -0500 Subject: [PATCH 1/8] Split monolithic raw crates into sys crates Creating a crate for bwd-gc highlights the fact that it would be nice to fix 2! The file blocklist is a lost less unmaintainable then the more fine-grained one we had before. Fix #9 --- Cargo.lock | 71 ++++++++++++++++--- Cargo.toml | 7 +- flake.nix | 41 +++++------ nci.nix | 52 +++++++++++++- nix-bindings-bdwgc-sys/Cargo.toml | 15 ++++ nix-bindings-bdwgc-sys/README.md | 4 ++ nix-bindings-bdwgc-sys/build.rs | 27 +++++++ nix-bindings-bdwgc-sys/include/bdwgc.h | 2 + nix-bindings-bdwgc-sys/src/lib.rs | 7 ++ nix-bindings-bindgen-raw/README.md | 12 ---- nix-bindings-bindgen-raw/build.rs | 60 ---------------- nix-bindings-bindgen-raw/include/nix-c-raw.h | 7 -- nix-bindings-bindgen-raw/src/lib.rs | 22 ------ nix-bindings-expr-sys/Cargo.toml | 17 +++++ nix-bindings-expr-sys/README.md | 5 ++ nix-bindings-expr-sys/build.rs | 42 +++++++++++ nix-bindings-expr-sys/include/nix-c-expr.h | 2 + nix-bindings-expr-sys/src/lib.rs | 10 +++ nix-bindings-expr/Cargo.toml | 5 +- nix-bindings-expr/src/eval_state.rs | 20 +++--- nix-bindings-expr/src/primop.rs | 7 +- nix-bindings-expr/src/value.rs | 2 +- nix-bindings-expr/src/value/__private.rs | 2 +- nix-bindings-fetchers-sys/Cargo.toml | 16 +++++ nix-bindings-fetchers-sys/README.md | 5 ++ nix-bindings-fetchers-sys/build.rs | 40 +++++++++++ .../include/nix-c-fetchers.h | 1 + nix-bindings-fetchers-sys/src/lib.rs | 9 +++ nix-bindings-fetchers/Cargo.toml | 2 +- nix-bindings-fetchers/src/lib.rs | 2 +- nix-bindings-flake-sys/Cargo.toml | 20 ++++++ nix-bindings-flake-sys/README.md | 5 ++ nix-bindings-flake-sys/build.rs | 56 +++++++++++++++ nix-bindings-flake-sys/include/nix-c-flake.h | 3 + nix-bindings-flake-sys/src/lib.rs | 11 +++ nix-bindings-flake/Cargo.toml | 2 +- nix-bindings-flake/src/lib.rs | 2 +- nix-bindings-store-sys/Cargo.toml | 16 +++++ nix-bindings-store-sys/README.md | 5 ++ nix-bindings-store-sys/build.rs | 40 +++++++++++ nix-bindings-store-sys/include/nix-c-store.h | 1 + nix-bindings-store-sys/src/lib.rs | 9 +++ nix-bindings-store/Cargo.toml | 3 +- nix-bindings-store/src/derivation.rs | 2 +- nix-bindings-store/src/path.rs | 2 +- nix-bindings-store/src/store.rs | 5 +- .../Cargo.toml | 4 +- nix-bindings-util-sys/README.md | 5 ++ nix-bindings-util-sys/build.rs | 38 ++++++++++ nix-bindings-util-sys/include/nix-c-util.h | 1 + nix-bindings-util-sys/src/lib.rs | 7 ++ nix-bindings-util/Cargo.toml | 4 +- nix-bindings-util/src/context.rs | 6 +- nix-bindings-util/src/lib.rs | 3 + nix-bindings-util/src/settings.rs | 8 +-- nix-bindings-util/src/string_return.rs | 4 +- 56 files changed, 607 insertions(+), 169 deletions(-) create mode 100644 nix-bindings-bdwgc-sys/Cargo.toml create mode 100644 nix-bindings-bdwgc-sys/README.md create mode 100644 nix-bindings-bdwgc-sys/build.rs create mode 100644 nix-bindings-bdwgc-sys/include/bdwgc.h create mode 100644 nix-bindings-bdwgc-sys/src/lib.rs delete mode 100644 nix-bindings-bindgen-raw/README.md delete mode 100644 nix-bindings-bindgen-raw/build.rs delete mode 100644 nix-bindings-bindgen-raw/include/nix-c-raw.h delete mode 100644 nix-bindings-bindgen-raw/src/lib.rs create mode 100644 nix-bindings-expr-sys/Cargo.toml create mode 100644 nix-bindings-expr-sys/README.md create mode 100644 nix-bindings-expr-sys/build.rs create mode 100644 nix-bindings-expr-sys/include/nix-c-expr.h create mode 100644 nix-bindings-expr-sys/src/lib.rs create mode 100644 nix-bindings-fetchers-sys/Cargo.toml create mode 100644 nix-bindings-fetchers-sys/README.md create mode 100644 nix-bindings-fetchers-sys/build.rs create mode 100644 nix-bindings-fetchers-sys/include/nix-c-fetchers.h create mode 100644 nix-bindings-fetchers-sys/src/lib.rs create mode 100644 nix-bindings-flake-sys/Cargo.toml create mode 100644 nix-bindings-flake-sys/README.md create mode 100644 nix-bindings-flake-sys/build.rs create mode 100644 nix-bindings-flake-sys/include/nix-c-flake.h create mode 100644 nix-bindings-flake-sys/src/lib.rs create mode 100644 nix-bindings-store-sys/Cargo.toml create mode 100644 nix-bindings-store-sys/README.md create mode 100644 nix-bindings-store-sys/build.rs create mode 100644 nix-bindings-store-sys/include/nix-c-store.h create mode 100644 nix-bindings-store-sys/src/lib.rs rename {nix-bindings-bindgen-raw => nix-bindings-util-sys}/Cargo.toml (78%) create mode 100644 nix-bindings-util-sys/README.md create mode 100644 nix-bindings-util-sys/build.rs create mode 100644 nix-bindings-util-sys/include/nix-c-util.h create mode 100644 nix-bindings-util-sys/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 416f121..f61c51e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,11 +134,11 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.1", ] [[package]] @@ -209,7 +209,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "nix-bindings-bindgen-raw" +name = "nix-bindings-bdwgc-sys" version = "0.1.0" dependencies = [ "bindgen", @@ -224,12 +224,25 @@ dependencies = [ "cstr", "ctor", "lazy_static", - "nix-bindings-bindgen-raw", + "nix-bindings-bdwgc-sys", + "nix-bindings-expr-sys", "nix-bindings-store", + "nix-bindings-store-sys", "nix-bindings-util", + "nix-bindings-util-sys", "tempfile", ] +[[package]] +name = "nix-bindings-expr-sys" +version = "0.1.0" +dependencies = [ + "bindgen", + "nix-bindings-store-sys", + "nix-bindings-util-sys", + "pkg-config", +] + [[package]] name = "nix-bindings-fetchers" version = "0.1.0" @@ -237,12 +250,21 @@ dependencies = [ "anyhow", "cstr", "ctor", - "nix-bindings-bindgen-raw", + "nix-bindings-fetchers-sys", "nix-bindings-store", "nix-bindings-util", "tempfile", ] +[[package]] +name = "nix-bindings-fetchers-sys" +version = "0.1.0" +dependencies = [ + "bindgen", + "nix-bindings-util-sys", + "pkg-config", +] + [[package]] name = "nix-bindings-flake" version = "0.1.0" @@ -251,14 +273,27 @@ dependencies = [ "cstr", "ctor", "lazy_static", - "nix-bindings-bindgen-raw", "nix-bindings-expr", "nix-bindings-fetchers", + "nix-bindings-flake-sys", "nix-bindings-store", "nix-bindings-util", "tempfile", ] +[[package]] +name = "nix-bindings-flake-sys" +version = "0.1.0" +dependencies = [ + "bindgen", + "nix-bindings-bdwgc-sys", + "nix-bindings-expr-sys", + "nix-bindings-fetchers-sys", + "nix-bindings-store-sys", + "nix-bindings-util-sys", + "pkg-config", +] + [[package]] name = "nix-bindings-store" version = "0.1.0" @@ -266,19 +301,37 @@ dependencies = [ "anyhow", "ctor", "lazy_static", - "nix-bindings-bindgen-raw", + "nix-bindings-store-sys", "nix-bindings-util", + "nix-bindings-util-sys", "pkg-config", "tempfile", ] +[[package]] +name = "nix-bindings-store-sys" +version = "0.1.0" +dependencies = [ + "bindgen", + "nix-bindings-util-sys", + "pkg-config", +] + [[package]] name = "nix-bindings-util" version = "0.1.0" dependencies = [ "anyhow", "ctor", - "nix-bindings-bindgen-raw", + "nix-bindings-util-sys", +] + +[[package]] +name = "nix-bindings-util-sys" +version = "0.1.0" +dependencies = [ + "bindgen", + "pkg-config", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d90bd3c..67da147 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,11 @@ [workspace] members = [ - "nix-bindings-bindgen-raw", + "nix-bindings-bdwgc-sys", + "nix-bindings-util-sys", + "nix-bindings-store-sys", + "nix-bindings-expr-sys", + "nix-bindings-fetchers-sys", + "nix-bindings-flake-sys", "nix-bindings-expr", "nix-bindings-fetchers", "nix-bindings-flake", diff --git a/flake.nix b/flake.nix index 7646649..55552ca 100644 --- a/flake.nix +++ b/flake.nix @@ -29,10 +29,7 @@ { _file = ./flake.nix; options.perSystem = flake-parts-lib.mkPerSystemOption ( - { config, pkgs, ... }: - let - cfg = config.nix-bindings-rust; - in + { pkgs, ... }: { options.nix-bindings-rust = { nixPackage = lib.mkOption { @@ -49,10 +46,25 @@ A module to load into your nix-cargo-integration [`perSystem.nci.projects..depsDrvConfig`](https://flake.parts/options/nix-cargo-integration.html#opt-perSystem.nci.projects._name_.depsDrvConfig) or similar such options. + This provides common build configuration (pkg-config, libclang, etc.) but you must + add the specific Nix C libraries your crates need to `buildInputs`: + - `nix-bindings-util-sys` needs `nix-util-c` + - `nix-bindings-store-sys` needs `nix-store-c` + - `nix-bindings-expr-sys` needs `nix-expr-c` + - `nix-bindings-fetchers-sys` needs `nix-fetchers-c` (Nix >= 2.29) + - `nix-bindings-flake-sys` needs `nix-flake-c` + - `nix-bindings-bdwgc-sys` needs `boehmgc` + Example: ```nix - perSystem = perSystem@{ config, ... }: { - nci.projects."my_project".depsDrvConfig = perSystem.config.nix-bindings-rust.nciBuildConfig; + perSystem = perSystem@{ config, pkgs, ... }: { + nci.projects."my_project".depsDrvConfig = { + imports = [ perSystem.config.nix-bindings-rust.nciBuildConfig ]; + mkDerivation.buildInputs = [ + perSystem.config.nix-bindings-rust.nixPackage.libs.nix-store-c + # ... add other libs as needed + ]; + }; } ``` ''; @@ -64,22 +76,7 @@ buildInputs = [ # stdbool.h pkgs.stdenv.cc - ] - ++ ( - if cfg.nixPackage ? libs then - let - l = cfg.nixPackage.libs; - in - [ - l.nix-expr-c - l.nix-store-c - l.nix-util-c - l.nix-fetchers-c or null # Nix >= 2.29 - l.nix-flake-c - ] - else - [ cfg.nixPackage ] - ); + ]; nativeBuildInputs = [ pkgs.pkg-config ]; diff --git a/nci.nix b/nci.nix index 053a832..6faa221 100644 --- a/nci.nix +++ b/nci.nix @@ -2,8 +2,24 @@ perSystem = { config, + pkgs, ... }: + let + cfg = config.nix-bindings-rust; + nixLibs = + if cfg.nixPackage ? libs then + cfg.nixPackage.libs + else + # Fallback for older Nix versions without split libs + { + nix-util-c = cfg.nixPackage; + nix-store-c = cfg.nixPackage; + nix-expr-c = cfg.nixPackage; + nix-fetchers-c = cfg.nixPackage; + nix-flake-c = cfg.nixPackage; + }; + in { # https://flake.parts/options/nix-cargo-integration nci.projects.nix-bindings = { @@ -38,12 +54,46 @@ echo "experimental-features = ca-derivations flakes" > "$NIX_CONF_DIR/nix.conf" # Init ahead of time, because concurrent initialization is flaky - ${config.nix-bindings-rust.nixPackage}/bin/nix-store --init + ${cfg.nixPackage}/bin/nix-store --init echo "Store initialized." ''; }; }; }; + + # Per-crate configuration: only provide the specific Nix libs each crate needs + # FIXME should use propagatedBuildInputs + nci.crates.nix-bindings-bdwgc-sys.drvConfig.mkDerivation.buildInputs = [ + pkgs.boehmgc + ]; + nci.crates.nix-bindings-util-sys.drvConfig.mkDerivation.buildInputs = [ + nixLibs.nix-util-c + ]; + nci.crates.nix-bindings-util.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-util-sys.drvConfig.mkDerivation.buildInputs; + nci.crates.nix-bindings-store-sys.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-util-sys.drvConfig.mkDerivation.buildInputs + ++ [ nixLibs.nix-store-c ]; + nci.crates.nix-bindings-store.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-store-sys.drvConfig.mkDerivation.buildInputs; + nci.crates.nix-bindings-expr-sys.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-store-sys.drvConfig.mkDerivation.buildInputs + ++ [ + nixLibs.nix-expr-c + pkgs.boehmgc + ]; + nci.crates.nix-bindings-expr.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-expr-sys.drvConfig.mkDerivation.buildInputs; + nci.crates.nix-bindings-fetchers-sys.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-expr-sys.drvConfig.mkDerivation.buildInputs + ++ [ nixLibs.nix-fetchers-c ]; + nci.crates.nix-bindings-fetchers.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-fetchers-sys.drvConfig.mkDerivation.buildInputs; + nci.crates.nix-bindings-flake-sys.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-fetchers-sys.drvConfig.mkDerivation.buildInputs + ++ [ nixLibs.nix-flake-c ]; + nci.crates.nix-bindings-flake.drvConfig.mkDerivation.buildInputs = + config.nci.crates.nix-bindings-flake-sys.drvConfig.mkDerivation.buildInputs; }; } diff --git a/nix-bindings-bdwgc-sys/Cargo.toml b/nix-bindings-bdwgc-sys/Cargo.toml new file mode 100644 index 0000000..46c3f15 --- /dev/null +++ b/nix-bindings-bdwgc-sys/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "nix-bindings-bdwgc-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] + +[build-dependencies] +bindgen = "0.69" +pkg-config = "0.3" diff --git a/nix-bindings-bdwgc-sys/README.md b/nix-bindings-bdwgc-sys/README.md new file mode 100644 index 0000000..3723e90 --- /dev/null +++ b/nix-bindings-bdwgc-sys/README.md @@ -0,0 +1,4 @@ +# nix-bindings-bdwgc-sys + +This crate contains generated bindings for the Boehm-Demers-Weiser garbage collector (`bdw-gc`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. diff --git a/nix-bindings-bdwgc-sys/build.rs b/nix-bindings-bdwgc-sys/build.rs new file mode 100644 index 0000000..aed2a8c --- /dev/null +++ b/nix-bindings-bdwgc-sys/build.rs @@ -0,0 +1,27 @@ +use std::env; +use std::path::PathBuf; + +fn main() { + println!("cargo:rerun-if-changed=include/bdwgc.h"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("bdw-gc") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let bindings = bindgen::Builder::default() + .header("include/bdwgc.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-bdwgc-sys/include/bdwgc.h b/nix-bindings-bdwgc-sys/include/bdwgc.h new file mode 100644 index 0000000..2a70434 --- /dev/null +++ b/nix-bindings-bdwgc-sys/include/bdwgc.h @@ -0,0 +1,2 @@ +#define GC_THREADS +#include diff --git a/nix-bindings-bdwgc-sys/src/lib.rs b/nix-bindings-bdwgc-sys/src/lib.rs new file mode 100644 index 0000000..0cf64d2 --- /dev/null +++ b/nix-bindings-bdwgc-sys/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-bindgen-raw/README.md b/nix-bindings-bindgen-raw/README.md deleted file mode 100644 index 1c7e5f0..0000000 --- a/nix-bindings-bindgen-raw/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# nix-bindings-bindgen-raw - -This crate contains generated bindings for the Nix C API. -**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. -Instead, use the `nix-bindings-util`, `nix-bindings-store` and `nix-bindings-expr` crates, which _should_ be sufficient. - -## Design - -Rust bindgen currently does not allow "layered" libraries to be split into separate crates. -For example, the expr crate would have all-new types that are distinct and incompatible with the store crate. - -Ideally bindgen will support reusing already generated modules, and we could move the code generation into the appropriate crates, so that the system dependencies of each crate become accurate. diff --git a/nix-bindings-bindgen-raw/build.rs b/nix-bindings-bindgen-raw/build.rs deleted file mode 100644 index 5dbdbc7..0000000 --- a/nix-bindings-bindgen-raw/build.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::env; -use std::path::PathBuf; - -#[derive(Debug)] -struct StripNixPrefix {} -impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { - fn item_name(&self, name: &str) -> Option { - name.strip_prefix("nix_").map(String::from) - } -} - -fn main() { - // Tell cargo to invalidate the built crate whenever the wrapper changes - println!("cargo:rerun-if-changed=include/nix-c-raw.h"); - println!("cargo:rustc-link-lib=nixflake"); - - // https://rust-lang.github.io/rust-bindgen/library-usage.html - let bindings = bindgen::Builder::default() - .header("include/nix-c-raw.h") - // Find the includes - .clang_args(c_headers()) - // Tell cargo to invalidate the built crate whenever any of the - // included header files changed. - .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) - .parse_callbacks(Box::new(StripNixPrefix {})) - // Finish the builder and generate the bindings. - .generate() - // Unwrap the Result and panic on failure. - .expect("Unable to generate bindings"); - - // Write the bindings to the $OUT_DIR/bindings.rs file. - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - bindings - .write_to_file(out_path.join("bindings.rs")) - .expect("Couldn't write bindings!"); -} - -fn c_headers() -> Vec { - let mut args = Vec::new(); - // args.push("-isystem".to_string()); - for path in pkg_config::probe_library("nix-flake-c") - .unwrap() - .include_paths - .iter() - { - args.push(format!("-I{}", path.to_str().unwrap())); - } - - for path in pkg_config::probe_library("bdw-gc") - .unwrap() - .include_paths - .iter() - { - args.push(format!("-I{}", path.to_str().unwrap())); - } - - // write to stderr for debugging - eprintln!("c_headers: {:?}", args); - args -} diff --git a/nix-bindings-bindgen-raw/include/nix-c-raw.h b/nix-bindings-bindgen-raw/include/nix-c-raw.h deleted file mode 100644 index 88e252f..0000000 --- a/nix-bindings-bindgen-raw/include/nix-c-raw.h +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include -#define GC_THREADS -#include -#include -#include -#include diff --git a/nix-bindings-bindgen-raw/src/lib.rs b/nix-bindings-bindgen-raw/src/lib.rs deleted file mode 100644 index 05c7e41..0000000 --- a/nix-bindings-bindgen-raw/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Raw bindings to Nix C API -//! -//! This crate contains automatically generated bindings from the Nix C headers. -//! The bindings are generated by bindgen and include C-style naming conventions -//! and documentation comments that don't always conform to Rust standards. -//! -//! Normally you don't have to use this crate directly. -//! Instead use `nix-store` and `nix-expr`. - -// Standard bindgen suppressions for C naming conventions -#![allow(non_upper_case_globals)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -// Rustdoc suppressions for generated C documentation -// The C headers contain Doxygen-style documentation that doesn't translate -// well to Rust's rustdoc format, causing various warnings: -#![allow(rustdoc::broken_intra_doc_links)] // @param[in]/[out] references don't resolve -#![allow(rustdoc::bare_urls)] // C docs may contain unescaped URLs -#![allow(rustdoc::invalid_html_tags)] // Doxygen HTML tags like -#![allow(rustdoc::invalid_codeblock_attributes)] // C code examples may use unsupported attributes - -include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-expr-sys/Cargo.toml b/nix-bindings-expr-sys/Cargo.toml new file mode 100644 index 0000000..d1971f2 --- /dev/null +++ b/nix-bindings-expr-sys/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "nix-bindings-expr-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } +nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } + +[build-dependencies] +bindgen = "0.69" +pkg-config = "0.3" diff --git a/nix-bindings-expr-sys/README.md b/nix-bindings-expr-sys/README.md new file mode 100644 index 0000000..ccdcc26 --- /dev/null +++ b/nix-bindings-expr-sys/README.md @@ -0,0 +1,5 @@ +# nix-bindings-expr-sys + +This crate contains generated bindings for the Nix C API (`nix-expr-c`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. +Instead, use the `nix-bindings-expr` crate, which _should_ be sufficient. diff --git a/nix-bindings-expr-sys/build.rs b/nix-bindings-expr-sys/build.rs new file mode 100644 index 0000000..6e0eed2 --- /dev/null +++ b/nix-bindings-expr-sys/build.rs @@ -0,0 +1,42 @@ +use std::path::PathBuf; + +#[derive(Debug)] +struct StripNixPrefix; + +impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { + fn item_name(&self, name: &str) -> Option { + name.strip_prefix("nix_").map(String::from) + } +} + +fn main() { + println!("cargo:rerun-if-changed=include/nix-c-expr.h"); + println!("cargo:rustc-link-lib=nixexprc"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("nix-expr-c") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let bindings = bindgen::Builder::default() + .header("include/nix-c-expr.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(StripNixPrefix)) + // Blocklist symbols from nix-bindings-util-sys + .blocklist_file(".*nix_api_util\\.h") + // Blocklist symbols from nix-bindings-store-sys + .blocklist_file(".*nix_api_store\\.h") + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-expr-sys/include/nix-c-expr.h b/nix-bindings-expr-sys/include/nix-c-expr.h new file mode 100644 index 0000000..c2649a4 --- /dev/null +++ b/nix-bindings-expr-sys/include/nix-c-expr.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/nix-bindings-expr-sys/src/lib.rs b/nix-bindings-expr-sys/src/lib.rs new file mode 100644 index 0000000..afd13d3 --- /dev/null +++ b/nix-bindings-expr-sys/src/lib.rs @@ -0,0 +1,10 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +use nix_bindings_store_sys::*; +use nix_bindings_util_sys::*; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-expr/Cargo.toml b/nix-bindings-expr/Cargo.toml index 044e70a..c06a59b 100644 --- a/nix-bindings-expr/Cargo.toml +++ b/nix-bindings-expr/Cargo.toml @@ -11,7 +11,10 @@ path = "src/lib.rs" anyhow = "1.0" nix-bindings-store = { path = "../nix-bindings-store" } nix-bindings-util = { path = "../nix-bindings-util" } -nix-bindings-bindgen-raw = { path = "../nix-bindings-bindgen-raw" } +nix-bindings-bdwgc-sys = { path = "../nix-bindings-bdwgc-sys" } +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } +nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } +nix-bindings-expr-sys = { path = "../nix-bindings-expr-sys" } lazy_static = "1.4" ctor = "0.2" tempfile = "3.10" diff --git a/nix-bindings-expr/src/eval_state.rs b/nix-bindings-expr/src/eval_state.rs index 7d0808c..1fb3410 100644 --- a/nix-bindings-expr/src/eval_state.rs +++ b/nix-bindings-expr/src/eval_state.rs @@ -134,9 +134,11 @@ use anyhow::Context as _; use anyhow::{bail, Result}; use cstr::cstr; use lazy_static::lazy_static; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_bdwgc_sys as gc; +use nix_bindings_expr_sys as raw; use nix_bindings_store::path::StorePath; use nix_bindings_store::store::{Store, StoreWeak}; +use nix_bindings_store_sys as raw_store; use nix_bindings_util::context::Context; use nix_bindings_util::string_return::{ callback_get_result_string, callback_get_result_string_data, @@ -151,7 +153,7 @@ use std::sync::{Arc, Weak}; lazy_static! { static ref INIT: Result<()> = { unsafe { - raw::GC_allow_register_threads(); + gc::GC_allow_register_threads(); check_call!(raw::libexpr_init(&mut Context::new()))?; Ok(()) } @@ -887,7 +889,7 @@ impl EvalState { let mut paths = Vec::with_capacity(n as usize); for i in 0..n { let path = raw::realised_string_get_store_path(rs, i); - let path = NonNull::new(path as *mut raw::StorePath).ok_or_else(|| { + let path = NonNull::new(path as *mut raw_store::StorePath).ok_or_else(|| { anyhow::format_err!( "nix_realised_string_get_store_path returned a null pointer" ) @@ -1153,7 +1155,7 @@ impl Drop for ThreadRegistrationGuard { fn drop(&mut self) { if self.must_unregister { unsafe { - raw::GC_unregister_my_thread(); + gc::GC_unregister_my_thread(); } } } @@ -1161,14 +1163,14 @@ impl Drop for ThreadRegistrationGuard { fn gc_register_my_thread_do_it() -> Result<()> { unsafe { - let mut sb: raw::GC_stack_base = raw::GC_stack_base { + let mut sb: gc::GC_stack_base = gc::GC_stack_base { mem_base: null_mut(), }; - let r = raw::GC_get_stack_base(&mut sb); - if r as u32 != raw::GC_SUCCESS { + let r = gc::GC_get_stack_base(&mut sb); + if r as u32 != gc::GC_SUCCESS { Err(anyhow::format_err!("GC_get_stack_base failed: {}", r))?; } - raw::GC_register_my_thread(&sb); + gc::GC_register_my_thread(&sb); Ok(()) } } @@ -1179,7 +1181,7 @@ fn gc_register_my_thread_do_it() -> Result<()> { pub fn gc_register_my_thread() -> Result { init()?; unsafe { - let already_done = raw::GC_thread_is_registered(); + let already_done = gc::GC_thread_is_registered(); if already_done != 0 { return Ok(ThreadRegistrationGuard { must_unregister: false, diff --git a/nix-bindings-expr/src/primop.rs b/nix-bindings-expr/src/primop.rs index f430d4d..02410fc 100644 --- a/nix-bindings-expr/src/primop.rs +++ b/nix-bindings-expr/src/primop.rs @@ -1,8 +1,9 @@ use crate::eval_state::{EvalState, EvalStateWeak}; use crate::value::Value; use anyhow::Result; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_expr_sys as raw; use nix_bindings_util::check_call; +use nix_bindings_util_sys as raw_util; use std::ffi::{c_int, c_void, CStr, CString}; use std::mem::ManuallyDrop; use std::ptr::{null, null_mut}; @@ -84,7 +85,7 @@ struct PrimOpContext { unsafe extern "C" fn function_adapter( user_data: *mut ::std::os::raw::c_void, - context_out: *mut raw::c_context, + context_out: *mut raw_util::c_context, _state: *mut raw::EvalState, args: *mut *mut raw::Value, ret: *mut raw::Value, @@ -111,7 +112,7 @@ unsafe extern "C" fn function_adapter( CString::new("") .unwrap() }); - raw::set_err_msg(context_out, raw::err_NIX_ERR_UNKNOWN, cstr.as_ptr()); + raw_util::set_err_msg(context_out, raw_util::err_NIX_ERR_UNKNOWN, cstr.as_ptr()); }, } } diff --git a/nix-bindings-expr/src/value.rs b/nix-bindings-expr/src/value.rs index 086a343..1abe4d5 100644 --- a/nix-bindings-expr/src/value.rs +++ b/nix-bindings-expr/src/value.rs @@ -1,6 +1,6 @@ pub mod __private; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_expr_sys as raw; use nix_bindings_util::{check_call, context::Context}; use std::ptr::{null_mut, NonNull}; diff --git a/nix-bindings-expr/src/value/__private.rs b/nix-bindings-expr/src/value/__private.rs index 84151e1..770a217 100644 --- a/nix-bindings-expr/src/value/__private.rs +++ b/nix-bindings-expr/src/value/__private.rs @@ -1,6 +1,6 @@ //! Functions that are relevant for other bindings modules, but normally not end users. use super::Value; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_expr_sys as raw; /// Take ownership of a new [`Value`]. /// diff --git a/nix-bindings-fetchers-sys/Cargo.toml b/nix-bindings-fetchers-sys/Cargo.toml new file mode 100644 index 0000000..dff5b42 --- /dev/null +++ b/nix-bindings-fetchers-sys/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "nix-bindings-fetchers-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } + +[build-dependencies] +bindgen = "0.69" +pkg-config = "0.3" diff --git a/nix-bindings-fetchers-sys/README.md b/nix-bindings-fetchers-sys/README.md new file mode 100644 index 0000000..b403eac --- /dev/null +++ b/nix-bindings-fetchers-sys/README.md @@ -0,0 +1,5 @@ +# nix-bindings-fetchers-sys + +This crate contains generated bindings for the Nix C API (`nix-fetchers-c`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. +Instead, use the `nix-bindings-fetchers` crate, which _should_ be sufficient. diff --git a/nix-bindings-fetchers-sys/build.rs b/nix-bindings-fetchers-sys/build.rs new file mode 100644 index 0000000..34f6640 --- /dev/null +++ b/nix-bindings-fetchers-sys/build.rs @@ -0,0 +1,40 @@ +use std::path::PathBuf; + +#[derive(Debug)] +struct StripNixPrefix; + +impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { + fn item_name(&self, name: &str) -> Option { + name.strip_prefix("nix_").map(String::from) + } +} + +fn main() { + println!("cargo:rerun-if-changed=include/nix-c-fetchers.h"); + println!("cargo:rustc-link-lib=nixfetchersc"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("nix-fetchers-c") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let bindings = bindgen::Builder::default() + .header("include/nix-c-fetchers.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(StripNixPrefix)) + // Blocklist symbols from nix-bindings-util-sys + .blocklist_file(".*nix_api_util\\.h") + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-fetchers-sys/include/nix-c-fetchers.h b/nix-bindings-fetchers-sys/include/nix-c-fetchers.h new file mode 100644 index 0000000..2f4c542 --- /dev/null +++ b/nix-bindings-fetchers-sys/include/nix-c-fetchers.h @@ -0,0 +1 @@ +#include diff --git a/nix-bindings-fetchers-sys/src/lib.rs b/nix-bindings-fetchers-sys/src/lib.rs new file mode 100644 index 0000000..4c5c9fe --- /dev/null +++ b/nix-bindings-fetchers-sys/src/lib.rs @@ -0,0 +1,9 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +use nix_bindings_util_sys::*; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-fetchers/Cargo.toml b/nix-bindings-fetchers/Cargo.toml index 6cbb103..49edb2e 100644 --- a/nix-bindings-fetchers/Cargo.toml +++ b/nix-bindings-fetchers/Cargo.toml @@ -11,7 +11,7 @@ path = "src/lib.rs" anyhow = "1.0" nix-bindings-store = { path = "../nix-bindings-store" } nix-bindings-util = { path = "../nix-bindings-util" } -nix-bindings-bindgen-raw = { path = "../nix-bindings-bindgen-raw" } +nix-bindings-fetchers-sys = { path = "../nix-bindings-fetchers-sys" } ctor = "0.2" tempfile = "3.10" cstr = "0.2" diff --git a/nix-bindings-fetchers/src/lib.rs b/nix-bindings-fetchers/src/lib.rs index 06bf45f..0b7b6cc 100644 --- a/nix-bindings-fetchers/src/lib.rs +++ b/nix-bindings-fetchers/src/lib.rs @@ -1,5 +1,5 @@ use anyhow::{Context as _, Result}; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_fetchers_sys as raw; use nix_bindings_util::context::{self, Context}; use std::ptr::NonNull; diff --git a/nix-bindings-flake-sys/Cargo.toml b/nix-bindings-flake-sys/Cargo.toml new file mode 100644 index 0000000..1109b5f --- /dev/null +++ b/nix-bindings-flake-sys/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "nix-bindings-flake-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } +nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } +nix-bindings-expr-sys = { path = "../nix-bindings-expr-sys" } +nix-bindings-fetchers-sys = { path = "../nix-bindings-fetchers-sys" } +nix-bindings-bdwgc-sys = { path = "../nix-bindings-bdwgc-sys" } + +[build-dependencies] +bindgen = "0.69" +pkg-config = "0.3" diff --git a/nix-bindings-flake-sys/README.md b/nix-bindings-flake-sys/README.md new file mode 100644 index 0000000..10a9d96 --- /dev/null +++ b/nix-bindings-flake-sys/README.md @@ -0,0 +1,5 @@ +# nix-bindings-flake-sys + +This crate contains generated bindings for the Nix C API (`nix-flake-c`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. +Instead, use the `nix-bindings-flake` crate, which _should_ be sufficient. diff --git a/nix-bindings-flake-sys/build.rs b/nix-bindings-flake-sys/build.rs new file mode 100644 index 0000000..1fb3233 --- /dev/null +++ b/nix-bindings-flake-sys/build.rs @@ -0,0 +1,56 @@ +use std::path::PathBuf; + +#[derive(Debug)] +struct StripNixPrefix; + +impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { + fn item_name(&self, name: &str) -> Option { + name.strip_prefix("nix_").map(String::from) + } +} + +fn main() { + println!("cargo:rerun-if-changed=include/nix-c-flake.h"); + println!("cargo:rustc-link-lib=nixflakec"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("nix-flake-c") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + for path in pkg_config::probe_library("bdw-gc") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let bindings = bindgen::Builder::default() + .header("include/nix-c-flake.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(StripNixPrefix)) + // Blocklist symbols from nix-bindings-util-sys + .blocklist_file(".*nix_api_util\\.h") + // Blocklist symbols from nix-bindings-store-sys + .blocklist_file(".*nix_api_store\\.h") + // Blocklist symbols from nix-bindings-expr-sys + .blocklist_file(".*nix_api_expr\\.h") + .blocklist_file(".*nix_api_value\\.h") + // Blocklist symbols from nix-bindings-fetchers-sys + .blocklist_file(".*nix_api_fetchers\\.h") + // Blocklist symbols from nix-bindings-bdwgc-sys + .blocklist_file(".*/gc\\.h") + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-flake-sys/include/nix-c-flake.h b/nix-bindings-flake-sys/include/nix-c-flake.h new file mode 100644 index 0000000..89a45f1 --- /dev/null +++ b/nix-bindings-flake-sys/include/nix-c-flake.h @@ -0,0 +1,3 @@ +#define GC_THREADS +#include +#include diff --git a/nix-bindings-flake-sys/src/lib.rs b/nix-bindings-flake-sys/src/lib.rs new file mode 100644 index 0000000..1bcac64 --- /dev/null +++ b/nix-bindings-flake-sys/src/lib.rs @@ -0,0 +1,11 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +use nix_bindings_expr_sys::*; +use nix_bindings_fetchers_sys::*; +use nix_bindings_util_sys::*; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-flake/Cargo.toml b/nix-bindings-flake/Cargo.toml index 3606a7c..889f830 100644 --- a/nix-bindings-flake/Cargo.toml +++ b/nix-bindings-flake/Cargo.toml @@ -13,7 +13,7 @@ nix-bindings-expr = { path = "../nix-bindings-expr" } nix-bindings-fetchers = { path = "../nix-bindings-fetchers" } nix-bindings-store = { path = "../nix-bindings-store" } nix-bindings-util = { path = "../nix-bindings-util" } -nix-bindings-bindgen-raw = { path = "../nix-bindings-bindgen-raw" } +nix-bindings-flake-sys = { path = "../nix-bindings-flake-sys" } lazy_static = "1.4" ctor = "0.2" tempfile = "3.10" diff --git a/nix-bindings-flake/src/lib.rs b/nix-bindings-flake/src/lib.rs index bd531b9..cb8e850 100644 --- a/nix-bindings-flake/src/lib.rs +++ b/nix-bindings-flake/src/lib.rs @@ -1,9 +1,9 @@ use std::{ffi::CString, os::raw::c_char, ptr::NonNull}; use anyhow::{Context as _, Result}; -use nix_bindings_bindgen_raw as raw; use nix_bindings_expr::eval_state::EvalState; use nix_bindings_fetchers::FetchersSettings; +use nix_bindings_flake_sys as raw; use nix_bindings_util::{ context::{self, Context}, result_string_init, diff --git a/nix-bindings-store-sys/Cargo.toml b/nix-bindings-store-sys/Cargo.toml new file mode 100644 index 0000000..d24f30a --- /dev/null +++ b/nix-bindings-store-sys/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "nix-bindings-store-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } + +[build-dependencies] +bindgen = "0.69" +pkg-config = "0.3" diff --git a/nix-bindings-store-sys/README.md b/nix-bindings-store-sys/README.md new file mode 100644 index 0000000..73138ee --- /dev/null +++ b/nix-bindings-store-sys/README.md @@ -0,0 +1,5 @@ +# nix-bindings-store-sys + +This crate contains generated bindings for the Nix C API (`nix-store-c`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. +Instead, use the `nix-bindings-store` crate, which _should_ be sufficient. diff --git a/nix-bindings-store-sys/build.rs b/nix-bindings-store-sys/build.rs new file mode 100644 index 0000000..bafdfae --- /dev/null +++ b/nix-bindings-store-sys/build.rs @@ -0,0 +1,40 @@ +use std::path::PathBuf; + +#[derive(Debug)] +struct StripNixPrefix; + +impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { + fn item_name(&self, name: &str) -> Option { + name.strip_prefix("nix_").map(String::from) + } +} + +fn main() { + println!("cargo:rerun-if-changed=include/nix-c-store.h"); + println!("cargo:rustc-link-lib=nixstorec"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("nix-store-c") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let bindings = bindgen::Builder::default() + .header("include/nix-c-store.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(StripNixPrefix)) + // Blocklist symbols from nix-bindings-util-sys + .blocklist_file(".*nix_api_util\\.h") + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-store-sys/include/nix-c-store.h b/nix-bindings-store-sys/include/nix-c-store.h new file mode 100644 index 0000000..2c04d1d --- /dev/null +++ b/nix-bindings-store-sys/include/nix-c-store.h @@ -0,0 +1 @@ +#include diff --git a/nix-bindings-store-sys/src/lib.rs b/nix-bindings-store-sys/src/lib.rs new file mode 100644 index 0000000..4c5c9fe --- /dev/null +++ b/nix-bindings-store-sys/src/lib.rs @@ -0,0 +1,9 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +use nix_bindings_util_sys::*; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-store/Cargo.toml b/nix-bindings-store/Cargo.toml index f3d7211..566a650 100644 --- a/nix-bindings-store/Cargo.toml +++ b/nix-bindings-store/Cargo.toml @@ -11,7 +11,8 @@ path = "src/lib.rs" [dependencies] anyhow = "1.0" nix-bindings-util = { path = "../nix-bindings-util" } -nix-bindings-bindgen-raw = { path = "../nix-bindings-bindgen-raw" } +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } +nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } lazy_static = "1.4" [dev-dependencies] diff --git a/nix-bindings-store/src/derivation.rs b/nix-bindings-store/src/derivation.rs index 6be5e75..a1ee1c6 100644 --- a/nix-bindings-store/src/derivation.rs +++ b/nix-bindings-store/src/derivation.rs @@ -1,6 +1,6 @@ #![cfg(nix_at_least = "2.33.0pre")] -use nix_bindings_bindgen_raw as raw; +use nix_bindings_store_sys as raw; use std::ptr::NonNull; /// A Nix derivation diff --git a/nix-bindings-store/src/path.rs b/nix-bindings-store/src/path.rs index b07bf11..51469af 100644 --- a/nix-bindings-store/src/path.rs +++ b/nix-bindings-store/src/path.rs @@ -1,7 +1,7 @@ use std::ptr::NonNull; use anyhow::Result; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_store_sys as raw; use nix_bindings_util::{ result_string_init, string_return::{callback_get_result_string, callback_get_result_string_data}, diff --git a/nix-bindings-store/src/store.rs b/nix-bindings-store/src/store.rs index fa9adad..30d402b 100644 --- a/nix-bindings-store/src/store.rs +++ b/nix-bindings-store/src/store.rs @@ -1,11 +1,12 @@ use anyhow::{bail, Error, Result}; use lazy_static::lazy_static; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_store_sys as raw; use nix_bindings_util::context::Context; use nix_bindings_util::string_return::{ callback_get_result_string, callback_get_result_string_data, }; use nix_bindings_util::{check_call, result_string_init}; +use nix_bindings_util_sys as raw_util; #[cfg(nix_at_least = "2.33.0pre")] use std::collections::BTreeMap; use std::collections::HashMap; @@ -73,7 +74,7 @@ lazy_static! { #[cfg(nix_at_least = "2.33.0pre")] unsafe extern "C" fn callback_get_result_store_path_set( - _context: *mut raw::c_context, + _context: *mut raw_util::c_context, user_data: *mut std::os::raw::c_void, store_path: *const raw::StorePath, ) { diff --git a/nix-bindings-bindgen-raw/Cargo.toml b/nix-bindings-util-sys/Cargo.toml similarity index 78% rename from nix-bindings-bindgen-raw/Cargo.toml rename to nix-bindings-util-sys/Cargo.toml index 7668b60..8811ead 100644 --- a/nix-bindings-bindgen-raw/Cargo.toml +++ b/nix-bindings-util-sys/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "nix-bindings-bindgen-raw" +name = "nix-bindings-util-sys" version = "0.1.0" edition = "2021" build = "build.rs" @@ -8,6 +8,8 @@ license = "LGPL-2.1" [lib] path = "src/lib.rs" +[dependencies] + [build-dependencies] bindgen = "0.69" pkg-config = "0.3" diff --git a/nix-bindings-util-sys/README.md b/nix-bindings-util-sys/README.md new file mode 100644 index 0000000..82debbf --- /dev/null +++ b/nix-bindings-util-sys/README.md @@ -0,0 +1,5 @@ +# nix-bindings-util-sys + +This crate contains generated bindings for the Nix C API (`nix-util-c`). +**You should not have to use this crate directly,** and so you should probably not add it to your dependencies. +Instead, use the `nix-bindings-util` crate, which _should_ be sufficient. diff --git a/nix-bindings-util-sys/build.rs b/nix-bindings-util-sys/build.rs new file mode 100644 index 0000000..441192a --- /dev/null +++ b/nix-bindings-util-sys/build.rs @@ -0,0 +1,38 @@ +use std::path::PathBuf; + +#[derive(Debug)] +struct StripNixPrefix; + +impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { + fn item_name(&self, name: &str) -> Option { + name.strip_prefix("nix_").map(String::from) + } +} + +fn main() { + println!("cargo:rerun-if-changed=include/nix-c-util.h"); + println!("cargo:rustc-link-lib=nixutilc"); + + let mut args = Vec::new(); + for path in pkg_config::probe_library("nix-util-c") + .unwrap() + .include_paths + .iter() + { + args.push(format!("-I{}", path.to_str().unwrap())); + } + + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + + let bindings = bindgen::Builder::default() + .header("include/nix-c-util.h") + .clang_args(args) + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) + .parse_callbacks(Box::new(StripNixPrefix)) + .generate() + .expect("Unable to generate bindings"); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/nix-bindings-util-sys/include/nix-c-util.h b/nix-bindings-util-sys/include/nix-c-util.h new file mode 100644 index 0000000..7fd0bc6 --- /dev/null +++ b/nix-bindings-util-sys/include/nix-c-util.h @@ -0,0 +1 @@ +#include diff --git a/nix-bindings-util-sys/src/lib.rs b/nix-bindings-util-sys/src/lib.rs new file mode 100644 index 0000000..0cf64d2 --- /dev/null +++ b/nix-bindings-util-sys/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(dead_code)] +#![allow(clippy::all)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/nix-bindings-util/Cargo.toml b/nix-bindings-util/Cargo.toml index 9242e99..101e0e8 100644 --- a/nix-bindings-util/Cargo.toml +++ b/nix-bindings-util/Cargo.toml @@ -9,7 +9,9 @@ path = "src/lib.rs" [dependencies] anyhow = "1.0" -nix-bindings-bindgen-raw = { path = "../nix-bindings-bindgen-raw" } +nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } + +[dev-dependencies] ctor = "0.2" [lints.rust] diff --git a/nix-bindings-util/src/context.rs b/nix-bindings-util/src/context.rs index 4999a7b..dbb333e 100644 --- a/nix-bindings-util/src/context.rs +++ b/nix-bindings-util/src/context.rs @@ -1,9 +1,9 @@ use anyhow::{bail, Result}; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_util_sys as raw; use std::ptr::null_mut; use std::ptr::NonNull; -/// A context for error handling, when interacting directly with the generated bindings for the C API in [nix_bindings_bindgen_raw]. +/// A context for error handling, when interacting directly with the generated bindings for the C API in [nix_bindings_util_sys]. /// /// The `nix-store` and `nix-expr` libraries that consume this type internally store a private context in their `EvalState` and `Store` structs to avoid allocating a new context for each operation. The state of a context is irrelevant when used correctly (e.g. with [check_call!]), so it's safe to reuse, and safe to allocate more contexts in methods such as [Clone::clone]. pub struct Context { @@ -113,7 +113,7 @@ macro_rules! check_call_opt_key { { let ctx : &mut $crate::context::Context = $ctx; let ret = $($f)::*(ctx.ptr(), $($arg,)*); - if unsafe { raw::err_code(ctx.ptr()) == raw::err_NIX_ERR_KEY } { + if unsafe { $crate::raw_sys::err_code(ctx.ptr()) == $crate::raw_sys::err_NIX_ERR_KEY } { ctx.clear(); return Ok(None); } diff --git a/nix-bindings-util/src/lib.rs b/nix-bindings-util/src/lib.rs index c74208c..f626d96 100644 --- a/nix-bindings-util/src/lib.rs +++ b/nix-bindings-util/src/lib.rs @@ -3,3 +3,6 @@ pub mod settings; #[macro_use] pub mod string_return; pub mod nix_version; + +// Re-export for use in macros +pub use nix_bindings_util_sys as raw_sys; diff --git a/nix-bindings-util/src/settings.rs b/nix-bindings-util/src/settings.rs index 5b5b5ef..8c213aa 100644 --- a/nix-bindings-util/src/settings.rs +++ b/nix-bindings-util/src/settings.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use nix_bindings_bindgen_raw as raw; +use nix_bindings_util_sys as raw; use std::sync::Mutex; use crate::{ @@ -74,20 +74,20 @@ mod tests { fn setup() { let mut ctx = context::Context::new(); unsafe { - check_call!(raw::libstore_init(&mut ctx)).unwrap(); + check_call!(nix_bindings_util_sys::libutil_init(&mut ctx)).unwrap(); } } #[test] fn set_get() { // Something that shouldn't matter if it's a different value temporarily - let key = "user-agent-suffix"; + let key = "json-log-path"; // Save the old value, in case it's important. Probably not. // If this doesn't work, pick a different setting to test with let old_value = get(key).unwrap(); - let new_value = "just a string that we're storing into some option for testing purposes"; + let new_value = "/just/a/path/that/we/are/storing/into/some/option/for/testing/purposes"; let res_e = (|| { set(key, new_value)?; diff --git a/nix-bindings-util/src/string_return.rs b/nix-bindings-util/src/string_return.rs index 9851a0d..205cebe 100644 --- a/nix-bindings-util/src/string_return.rs +++ b/nix-bindings-util/src/string_return.rs @@ -52,9 +52,9 @@ macro_rules! result_string_init { #[cfg(test)] mod tests { use super::*; - use nix_bindings_bindgen_raw as raw; + use nix_bindings_util_sys as raw; - /// Typecheck the function signature against the generated bindings in nix_bindings_bindgen_raw. + /// Typecheck the function signature against the generated bindings in nix_bindings_util_sys. static _CALLBACK_GET_RESULT_STRING: raw::get_string_callback = Some(callback_get_result_string); #[test] From 79cc8bd2e34ecd697338fd1d55261962b99b5601 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 22:11:43 -0500 Subject: [PATCH 2/8] Add zerocopy instance to raw bindings struct This will come in handy later, when we integrate harmonia. It is a very stable thing to do. --- Cargo.lock | 21 +++++++++++++++++++++ nix-bindings-store-sys/Cargo.toml | 1 + nix-bindings-store-sys/build.rs | 17 +++++++++++++++++ nix-bindings-store/src/path.rs | 1 + 4 files changed, 40 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index f61c51e..727b180 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,6 +315,7 @@ dependencies = [ "bindgen", "nix-bindings-util-sys", "pkg-config", + "zerocopy", ] [[package]] @@ -610,3 +611,23 @@ name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zerocopy" +version = "0.8.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/nix-bindings-store-sys/Cargo.toml b/nix-bindings-store-sys/Cargo.toml index d24f30a..82855d6 100644 --- a/nix-bindings-store-sys/Cargo.toml +++ b/nix-bindings-store-sys/Cargo.toml @@ -10,6 +10,7 @@ path = "src/lib.rs" [dependencies] nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } +zerocopy = { version = "0.8", features = ["derive"] } [build-dependencies] bindgen = "0.69" diff --git a/nix-bindings-store-sys/build.rs b/nix-bindings-store-sys/build.rs index bafdfae..8702756 100644 --- a/nix-bindings-store-sys/build.rs +++ b/nix-bindings-store-sys/build.rs @@ -9,6 +9,22 @@ impl bindgen::callbacks::ParseCallbacks for StripNixPrefix { } } +#[derive(Debug)] +struct AddZerocopyDerives {} +impl bindgen::callbacks::ParseCallbacks for AddZerocopyDerives { + fn add_derives(&self, info: &bindgen::callbacks::DeriveInfo<'_>) -> Vec { + if info.name == "store_path_hash_part" { + vec![ + "zerocopy::FromBytes".to_string(), + "zerocopy::IntoBytes".to_string(), + "zerocopy::Immutable".to_string(), + ] + } else { + vec![] + } + } +} + fn main() { println!("cargo:rerun-if-changed=include/nix-c-store.h"); println!("cargo:rustc-link-lib=nixstorec"); @@ -29,6 +45,7 @@ fn main() { .clang_args(args) .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .parse_callbacks(Box::new(StripNixPrefix)) + .parse_callbacks(Box::new(AddZerocopyDerives {})) // Blocklist symbols from nix-bindings-util-sys .blocklist_file(".*nix_api_util\\.h") .generate() diff --git a/nix-bindings-store/src/path.rs b/nix-bindings-store/src/path.rs index 51469af..cfd3895 100644 --- a/nix-bindings-store/src/path.rs +++ b/nix-bindings-store/src/path.rs @@ -10,6 +10,7 @@ use nix_bindings_util::{ pub struct StorePath { raw: NonNull, } + impl StorePath { /// Get the name of the store path. /// From d15dc92a37ffffed42629c50ece053e1df108b1e Mon Sep 17 00:00:00 2001 From: John Ericson Date: Mon, 15 Dec 2025 20:54:28 -0500 Subject: [PATCH 3/8] Add new `StorePath` bindings --- nix-bindings-store/Cargo.toml | 1 + nix-bindings-store/src/path.rs | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/nix-bindings-store/Cargo.toml b/nix-bindings-store/Cargo.toml index 566a650..67e9f90 100644 --- a/nix-bindings-store/Cargo.toml +++ b/nix-bindings-store/Cargo.toml @@ -14,6 +14,7 @@ nix-bindings-util = { path = "../nix-bindings-util" } nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } lazy_static = "1.4" +zerocopy = "0.8" [dev-dependencies] ctor = "0.2" diff --git a/nix-bindings-store/src/path.rs b/nix-bindings-store/src/path.rs index cfd3895..a858816 100644 --- a/nix-bindings-store/src/path.rs +++ b/nix-bindings-store/src/path.rs @@ -7,6 +7,9 @@ use nix_bindings_util::{ string_return::{callback_get_result_string, callback_get_result_string_data}, }; +/// The size of a store path hash in bytes (20 bytes, decoded from nix32). +pub const STORE_PATH_HASH_SIZE: usize = 20; + pub struct StorePath { raw: NonNull, } @@ -27,6 +30,43 @@ impl StorePath { } } + /// Get the hash part of the store path. + /// + /// This returns the decoded hash (not the nix32-encoded string). + #[cfg(nix_at_least = "2.33")] + pub fn hash(&self) -> Result<[u8; STORE_PATH_HASH_SIZE]> { + let mut result = [0u8; STORE_PATH_HASH_SIZE]; + let hash_part: &mut raw::store_path_hash_part = zerocopy::transmute_mut!(&mut result); + + let mut ctx = Context::new(); + + unsafe { + check_call!(raw::store_path_hash(&mut ctx, self.as_ptr(), hash_part))?; + } + Ok(result) + } + + /// Create a StorePath from hash and name components. + #[cfg(nix_at_least = "2.33")] + pub fn from_parts(hash: &[u8; STORE_PATH_HASH_SIZE], name: &str) -> Result { + let hash_part: &raw::store_path_hash_part = zerocopy::transmute_ref!(hash); + + let mut ctx = Context::new(); + + let out_path = unsafe { + check_call!(raw::store_create_from_parts( + &mut ctx, + hash_part, + name.as_ptr() as *const i8, + name.len() + ))? + }; + + NonNull::new(out_path) + .map(|ptr| unsafe { Self::new_raw(ptr) }) + .context("store_create_from_parts returned null") + } + /// This is a low level function that you shouldn't have to call unless you are developing the Nix bindings. /// /// Construct a new `StorePath` by first cloning the C store path. From 0e44d105bac0b6af94d6423454b4e0937bb10a4c Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 22:11:43 -0500 Subject: [PATCH 4/8] Higher-level `StorePath` with `harmonia-store-core` --- Cargo.lock | 1060 ++++++++++++++++++++++-- Cargo.toml | 1 + nix-bindings-store-harmonia/Cargo.toml | 25 + nix-bindings-store-harmonia/build.rs | 6 + nix-bindings-store-harmonia/src/lib.rs | 86 ++ 5 files changed, 1114 insertions(+), 64 deletions(-) create mode 100644 nix-bindings-store-harmonia/Cargo.toml create mode 100644 nix-bindings-store-harmonia/build.rs create mode 100644 nix-bindings-store-harmonia/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 727b180..0742361 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,19 +4,40 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bindgen" version = "0.69.5" @@ -42,9 +63,34 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "bumpalo" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.2.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +dependencies = [ + "find-msvc-tools", + "shlex", +] [[package]] name = "cexpr" @@ -57,9 +103,21 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] [[package]] name = "clang-sys" @@ -72,6 +130,21 @@ dependencies = [ "libloading", ] +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cstr" version = "0.2.12" @@ -92,12 +165,98 @@ dependencies = [ "syn", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_more" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", + "unicode-xid", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.14" @@ -105,7 +264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -114,31 +273,171 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "getrandom" -version = "0.3.3" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "r-efi", "wasi", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "glob" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "harmonia-store-core" +version = "2.1.0" +source = "git+https://github.com/nix-community/harmonia.git#27bef83e88aea6fab6d70f073977133804540334" +dependencies = [ + "bytes", + "data-encoding", + "derive_more", + "harmonia-utils-base-encoding", + "harmonia-utils-hash", + "num_enum", + "ring", + "serde", + "serde_json", + "serde_with", + "thiserror", + "tokio", + "tracing", + "zerocopy", +] + +[[package]] +name = "harmonia-utils-base-encoding" +version = "2.1.0" +source = "git+https://github.com/nix-community/harmonia.git#27bef83e88aea6fab6d70f073977133804540334" +dependencies = [ + "data-encoding", + "derive_more", + "serde", +] + +[[package]] +name = "harmonia-utils-hash" +version = "2.1.0" +source = "git+https://github.com/nix-community/harmonia.git#27bef83e88aea6fab6d70f073977133804540334" +dependencies = [ + "data-encoding", + "derive_more", + "harmonia-utils-base-encoding", + "md5", + "ring", + "serde", + "thiserror", + "tokio", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "home" version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -150,6 +449,22 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -164,9 +479,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.176" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -192,9 +507,15 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "md5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0" [[package]] name = "memchr" @@ -208,6 +529,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + [[package]] name = "nix-bindings-bdwgc-sys" version = "0.1.0" @@ -306,6 +638,20 @@ dependencies = [ "nix-bindings-util-sys", "pkg-config", "tempfile", + "zerocopy", +] + +[[package]] +name = "nix-bindings-store-harmonia" +version = "0.1.0" +dependencies = [ + "anyhow", + "ctor", + "harmonia-store-core", + "nix-bindings-store", + "nix-bindings-util", + "pkg-config", + "tempfile", ] [[package]] @@ -345,18 +691,67 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + [[package]] name = "pkg-config" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.37" @@ -367,20 +762,29 @@ dependencies = [ "syn", ] +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -391,11 +795,31 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -405,9 +829,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -416,9 +840,23 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] [[package]] name = "rustc-hash" @@ -426,6 +864,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.44" @@ -449,54 +896,349 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] -name = "syn" -version = "2.0.106" +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schemars" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "dyn-clone", + "ref-cast", + "serde", + "serde_json", ] [[package]] -name = "tempfile" -version = "3.23.0" +name = "schemars" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.12.1", + "schemars 0.9.0", + "schemars 1.1.0", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +dependencies = [ + "libc", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.3.4", "once_cell", "rustix 1.1.2", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] -name = "unicode-ident" -version = "1.0.19" +name = "thiserror" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl", +] [[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" +name = "thiserror-impl" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ - "wasip2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +dependencies = [ + "once_cell", ] +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -506,6 +1248,51 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + [[package]] name = "which" version = "4.4.2" @@ -518,11 +1305,73 @@ dependencies = [ "rustix 0.38.44", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] [[package]] name = "windows-sys" @@ -530,14 +1379,23 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] @@ -548,14 +1406,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -564,48 +1439,105 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.46.0" @@ -614,18 +1546,18 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "zerocopy" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 67da147..2cc5f18 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "nix-bindings-fetchers", "nix-bindings-flake", "nix-bindings-store", + "nix-bindings-store-harmonia", "nix-bindings-util", ] resolver = "2" diff --git a/nix-bindings-store-harmonia/Cargo.toml b/nix-bindings-store-harmonia/Cargo.toml new file mode 100644 index 0000000..d075f63 --- /dev/null +++ b/nix-bindings-store-harmonia/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "nix-bindings-store-harmonia" +version = "0.1.0" +edition = "2021" +build = "build.rs" +license = "LGPL-2.1" + +[lib] +path = "src/lib.rs" + +[dependencies] +anyhow = "1.0" +nix-bindings-store = { path = "../nix-bindings-store" } +harmonia-store-core = { git = "https://github.com/nix-community/harmonia.git" } + +[dev-dependencies] +ctor = "0.2" +tempfile = "3.10" + +[build-dependencies] +pkg-config = "0.3" +nix-bindings-util = { path = "../nix-bindings-util" } + +[lints] +workspace = true diff --git a/nix-bindings-store-harmonia/build.rs b/nix-bindings-store-harmonia/build.rs new file mode 100644 index 0000000..38020a7 --- /dev/null +++ b/nix-bindings-store-harmonia/build.rs @@ -0,0 +1,6 @@ +use nix_bindings_util::nix_version::emit_version_cfg; + +fn main() { + let nix_version = pkg_config::probe_library("nix-store-c").unwrap().version; + emit_version_cfg(&nix_version, &["2.33"]); +} diff --git a/nix-bindings-store-harmonia/src/lib.rs b/nix-bindings-store-harmonia/src/lib.rs new file mode 100644 index 0000000..69acb60 --- /dev/null +++ b/nix-bindings-store-harmonia/src/lib.rs @@ -0,0 +1,86 @@ +//! Harmonia integration for nix-bindings-store. +//! +//! This crate provides conversions between nix-bindings-store types and +//! harmonia-store-core types. +//! +//! **Requires Nix 2.33 or later for StorePath conversions.** + +#[cfg(nix_at_least = "2.33")] +use anyhow::{Context as AnyhowContext, Result}; + +// Re-export the main types for convenience +pub use nix_bindings_store::path::{StorePath, STORE_PATH_HASH_SIZE}; + +// StorePath conversions - require Nix 2.33 for from_parts() and hash() +#[cfg(nix_at_least = "2.33")] +impl TryFrom<&harmonia_store_core::store_path::StorePath> for StorePath { + type Error = anyhow::Error; + + fn try_from(harmonia_path: &harmonia_store_core::store_path::StorePath) -> Result { + let hash: &[u8; STORE_PATH_HASH_SIZE] = harmonia_path.hash().as_ref(); + StorePath::from_parts(hash, harmonia_path.name().as_ref()) + } +} + +#[cfg(nix_at_least = "2.33")] +impl TryFrom for StorePath { + type Error = anyhow::Error; + + fn try_from(harmonia_path: harmonia_store_core::store_path::StorePath) -> Result { + (&harmonia_path).try_into() + } +} + +#[cfg(nix_at_least = "2.33")] +impl TryFrom<&StorePath> for harmonia_store_core::store_path::StorePath { + type Error = anyhow::Error; + + fn try_from(nix_path: &StorePath) -> Result { + let hash = nix_path + .hash() + .context("Failed to get hash from nix StorePath")?; + let harmonia_hash = harmonia_store_core::store_path::StorePathHash::new(hash); + + let name = nix_path + .name() + .context("Failed to get name from nix StorePath")?; + + let harmonia_name: harmonia_store_core::store_path::StorePathName = name + .parse() + .context("Failed to parse name as StorePathName")?; + + Ok(harmonia_store_core::store_path::StorePath::from(( + harmonia_hash, + harmonia_name, + ))) + } +} + +#[cfg(nix_at_least = "2.33")] +impl TryFrom for harmonia_store_core::store_path::StorePath { + type Error = anyhow::Error; + + fn try_from(nix_path: StorePath) -> Result { + (&nix_path).try_into() + } +} + +#[cfg(test)] +mod tests { + #[allow(unused_imports)] + use super::*; + + #[test] + #[cfg(nix_at_least = "2.33")] + fn store_path_round_trip_harmonia() { + let harmonia_path: harmonia_store_core::store_path::StorePath = + "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv".parse().unwrap(); + + let nix_path: StorePath = (&harmonia_path).try_into().unwrap(); + + let harmonia_round_trip: harmonia_store_core::store_path::StorePath = + (&nix_path).try_into().unwrap(); + + assert_eq!(harmonia_path, harmonia_round_trip); + } +} From 3e68ca94169f4ca2c6f4f5f53e306e64066496c4 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 22:28:34 -0500 Subject: [PATCH 5/8] Test `Clone` for `StorePath` --- Cargo.lock | 2 ++ nix-bindings-store/Cargo.toml | 2 ++ nix-bindings-store/src/path.rs | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 0742361..5b89598 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -632,7 +632,9 @@ version = "0.1.0" dependencies = [ "anyhow", "ctor", + "harmonia-store-core", "lazy_static", + "nix-bindings-store-harmonia", "nix-bindings-store-sys", "nix-bindings-util", "nix-bindings-util-sys", diff --git a/nix-bindings-store/Cargo.toml b/nix-bindings-store/Cargo.toml index 67e9f90..b8e5487 100644 --- a/nix-bindings-store/Cargo.toml +++ b/nix-bindings-store/Cargo.toml @@ -19,6 +19,8 @@ zerocopy = "0.8" [dev-dependencies] ctor = "0.2" tempfile = "3.10" +harmonia-store-core = { git = "https://github.com/nix-community/harmonia.git" } +nix-bindings-store-harmonia = { path = "../nix-bindings-store-harmonia" } [build-dependencies] pkg-config = "0.3" diff --git a/nix-bindings-store/src/path.rs b/nix-bindings-store/src/path.rs index a858816..689bc45 100644 --- a/nix-bindings-store/src/path.rs +++ b/nix-bindings-store/src/path.rs @@ -1,7 +1,11 @@ use std::ptr::NonNull; use anyhow::Result; +#[cfg(nix_at_least = "2.33")] +use anyhow::Context as AnyhowContext; use nix_bindings_store_sys as raw; +#[cfg(nix_at_least = "2.33")] +use nix_bindings_util::{check_call, context::Context}; use nix_bindings_util::{ result_string_init, string_return::{callback_get_result_string, callback_get_result_string_data}, @@ -132,4 +136,22 @@ mod tests { let store_path = store.parse_store_path(store_path_string.as_str()).unwrap(); assert_eq!(store_path.name().unwrap(), "bash-interactive-5.2p26"); } + + #[test] + #[cfg(nix_at_least = "2.33")] + fn store_path_clone() { + use super::StorePath; + // Import TryFrom impls from the harmonia integration crate + use nix_bindings_store_harmonia as _; + + let harmonia_path: harmonia_store_core::store_path::StorePath = + "g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv".parse().unwrap(); + + let nix_path: StorePath = (&harmonia_path).try_into().unwrap(); + let cloned_path = nix_path.clone(); + + // Verify both paths have the same name and hash + assert_eq!(nix_path.name().unwrap(), cloned_path.name().unwrap()); + assert_eq!(nix_path.hash().unwrap(), cloned_path.hash().unwrap()); + } } From d00c06f7569786ddfda656746f9f5a8ad51f31f1 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 22:45:01 -0500 Subject: [PATCH 6/8] Higher-level `Derivation` with `harmonia-store-core` --- Cargo.lock | 2 + nix-bindings-store-harmonia/Cargo.toml | 1 + nix-bindings-store-harmonia/src/lib.rs | 112 ++++++++++++++++++++++++- nix-bindings-store/Cargo.toml | 1 + nix-bindings-store/src/derivation.rs | 23 +++++ nix-bindings-store/src/store.rs | 4 +- 6 files changed, 140 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b89598..a9455df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -639,6 +639,7 @@ dependencies = [ "nix-bindings-util", "nix-bindings-util-sys", "pkg-config", + "serde_json", "tempfile", "zerocopy", ] @@ -653,6 +654,7 @@ dependencies = [ "nix-bindings-store", "nix-bindings-util", "pkg-config", + "serde_json", "tempfile", ] diff --git a/nix-bindings-store-harmonia/Cargo.toml b/nix-bindings-store-harmonia/Cargo.toml index d075f63..2cd97e4 100644 --- a/nix-bindings-store-harmonia/Cargo.toml +++ b/nix-bindings-store-harmonia/Cargo.toml @@ -12,6 +12,7 @@ path = "src/lib.rs" anyhow = "1.0" nix-bindings-store = { path = "../nix-bindings-store" } harmonia-store-core = { git = "https://github.com/nix-community/harmonia.git" } +serde_json = "1.0" [dev-dependencies] ctor = "0.2" diff --git a/nix-bindings-store-harmonia/src/lib.rs b/nix-bindings-store-harmonia/src/lib.rs index 69acb60..96aa1e8 100644 --- a/nix-bindings-store-harmonia/src/lib.rs +++ b/nix-bindings-store-harmonia/src/lib.rs @@ -3,13 +3,17 @@ //! This crate provides conversions between nix-bindings-store types and //! harmonia-store-core types. //! -//! **Requires Nix 2.33 or later for StorePath conversions.** +//! **Requires Nix 2.33 or later.** #[cfg(nix_at_least = "2.33")] use anyhow::{Context as AnyhowContext, Result}; // Re-export the main types for convenience +#[cfg(nix_at_least = "2.33")] +pub use nix_bindings_store::derivation::Derivation; pub use nix_bindings_store::path::{StorePath, STORE_PATH_HASH_SIZE}; +#[cfg(nix_at_least = "2.33")] +pub use nix_bindings_store::store::Store; // StorePath conversions - require Nix 2.33 for from_parts() and hash() #[cfg(nix_at_least = "2.33")] @@ -65,6 +69,43 @@ impl TryFrom for harmonia_store_core::store_path::StorePath { } } +// Derivation conversions - require Nix 2.33 +#[cfg(nix_at_least = "2.33")] +impl TryFrom<&Derivation> for harmonia_store_core::derivation::Derivation { + type Error = anyhow::Error; + + fn try_from(nix_drv: &Derivation) -> Result { + let json = nix_drv + .to_json() + .context("Failed to convert nix Derivation to JSON")?; + + serde_json::from_str(&json).context("Failed to parse JSON as harmonia Derivation") + } +} + +#[cfg(nix_at_least = "2.33")] +impl TryFrom for harmonia_store_core::derivation::Derivation { + type Error = anyhow::Error; + + fn try_from(nix_drv: Derivation) -> Result { + (&nix_drv).try_into() + } +} + +/// Convert harmonia Derivation to nix-bindings Derivation. +/// +/// This requires a Store instance because the Nix C API needs it for internal validation. +#[cfg(nix_at_least = "2.33")] +pub fn harmonia_derivation_to_nix( + store: &mut Store, + harmonia_drv: &harmonia_store_core::derivation::Derivation, +) -> Result { + let json = serde_json::to_string(harmonia_drv) + .context("Failed to serialize harmonia Derivation to JSON")?; + + store.derivation_from_json(&json) +} + #[cfg(test)] mod tests { #[allow(unused_imports)] @@ -83,4 +124,73 @@ mod tests { assert_eq!(harmonia_path, harmonia_round_trip); } + + #[cfg(nix_at_least = "2.33")] + fn create_test_derivation() -> harmonia_store_core::derivation::Derivation { + use harmonia_store_core::derivation::{self, Derivation, Output}; + use std::collections::BTreeMap; + + let system = format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS); + let out_path = "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9"; + + let mut env = BTreeMap::new(); + env.insert("builder".to_string(), "/bin/sh".to_string()); + env.insert("name".to_string(), "myname".to_string()); + env.insert("out".to_string(), out_path.to_string()); + env.insert("system".to_string(), system.clone()); + + let mut outputs = BTreeMap::new(); + outputs.insert( + "out".to_string(), + Output::InputAddressed(derivation::InputAddressed { + path: out_path.to_string(), + }), + ); + + Derivation { + args: vec!["-c".to_string(), "echo $name foo > $out".to_string()], + builder: "/bin/sh".to_string(), + env, + inputs: derivation::Inputs { + drvs: BTreeMap::new(), + srcs: vec![], + }, + name: "myname".to_string(), + outputs, + system, + } + } + + #[test] + #[cfg(nix_at_least = "2.33")] + fn derivation_round_trip_harmonia() { + let mut store = Store::open(Some("dummy://"), []).unwrap(); + let harmonia_drv = create_test_derivation(); + + // Convert to nix-bindings Derivation + let nix_drv = harmonia_derivation_to_nix(&mut store, &harmonia_drv).unwrap(); + + // Convert back to harmonia Derivation + let harmonia_round_trip: harmonia_store_core::derivation::Derivation = + (&nix_drv).try_into().unwrap(); + + assert_eq!(harmonia_drv, harmonia_round_trip); + } + + #[test] + #[cfg(nix_at_least = "2.33")] + fn derivation_clone() { + let mut store = Store::open(Some("dummy://"), []).unwrap(); + let harmonia_drv = create_test_derivation(); + + let derivation = harmonia_derivation_to_nix(&mut store, &harmonia_drv).unwrap(); + let cloned_derivation = derivation.clone(); + + let original_harmonia: harmonia_store_core::derivation::Derivation = + (&derivation).try_into().unwrap(); + let cloned_harmonia: harmonia_store_core::derivation::Derivation = + (&cloned_derivation).try_into().unwrap(); + + assert_eq!(original_harmonia, cloned_harmonia); + } } diff --git a/nix-bindings-store/Cargo.toml b/nix-bindings-store/Cargo.toml index b8e5487..002afe7 100644 --- a/nix-bindings-store/Cargo.toml +++ b/nix-bindings-store/Cargo.toml @@ -15,6 +15,7 @@ nix-bindings-util-sys = { path = "../nix-bindings-util-sys" } nix-bindings-store-sys = { path = "../nix-bindings-store-sys" } lazy_static = "1.4" zerocopy = "0.8" +serde_json = "1.0" [dev-dependencies] ctor = "0.2" diff --git a/nix-bindings-store/src/derivation.rs b/nix-bindings-store/src/derivation.rs index a1ee1c6..0ca7989 100644 --- a/nix-bindings-store/src/derivation.rs +++ b/nix-bindings-store/src/derivation.rs @@ -1,6 +1,13 @@ #![cfg(nix_at_least = "2.33.0pre")] +use anyhow::Result; use nix_bindings_store_sys as raw; +use nix_bindings_util::{ + check_call, + context::Context, + result_string_init, + string_return::{callback_get_result_string, callback_get_result_string_data}, +}; use std::ptr::NonNull; /// A Nix derivation @@ -15,6 +22,22 @@ impl Derivation { Derivation { inner } } + /// Convert the derivation to a JSON string. + pub fn to_json(&self) -> Result { + let mut ctx = Context::new(); + + unsafe { + let mut r = result_string_init!(); + check_call!(raw::derivation_to_json( + &mut ctx, + self.inner.as_ptr(), + Some(callback_get_result_string), + callback_get_result_string_data(&mut r) + ))?; + r + } + } + /// This is a low level function that you shouldn't have to call unless you are developing the Nix bindings. /// /// Construct a new `Derivation` by first cloning the C derivation. diff --git a/nix-bindings-store/src/store.rs b/nix-bindings-store/src/store.rs index 30d402b..76722c6 100644 --- a/nix-bindings-store/src/store.rs +++ b/nix-bindings-store/src/store.rs @@ -431,7 +431,7 @@ impl Clone for Store { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use ctor::ctor; use std::collections::HashMap; @@ -572,7 +572,7 @@ mod tests { } #[cfg(nix_at_least = "2.33")] - fn create_test_derivation_json() -> String { + pub(crate) fn create_test_derivation_json() -> String { let system = current_system().unwrap_or_else(|_| { // Fallback to Rust's platform detection format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS) From b4ed412d86b762cb09413134d4cb5119fe827c20 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 26 Nov 2025 23:28:13 -0500 Subject: [PATCH 7/8] Instead of raw JSON literals, construct Derivation in Rust for tests Utilize `harmonia-store-core` for higher level, well-typed, tests. If the JSON format changes, we update that in that library instead. The only purpose of raw JSON would be testing obselete JSON formats versions, which we don't have (that are still supported) yet. --- Cargo.lock | 1 + nix-bindings-store/Cargo.toml | 1 + nix-bindings-store/src/path.rs | 2 +- nix-bindings-store/src/store.rs | 321 +++++++++++++++----------------- 4 files changed, 157 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9455df..99b8e3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -633,6 +633,7 @@ dependencies = [ "anyhow", "ctor", "harmonia-store-core", + "harmonia-utils-hash", "lazy_static", "nix-bindings-store-harmonia", "nix-bindings-store-sys", diff --git a/nix-bindings-store/Cargo.toml b/nix-bindings-store/Cargo.toml index 002afe7..f78ce20 100644 --- a/nix-bindings-store/Cargo.toml +++ b/nix-bindings-store/Cargo.toml @@ -19,6 +19,7 @@ serde_json = "1.0" [dev-dependencies] ctor = "0.2" +harmonia-utils-hash = { git = "https://github.com/nix-community/harmonia.git" } tempfile = "3.10" harmonia-store-core = { git = "https://github.com/nix-community/harmonia.git" } nix-bindings-store-harmonia = { path = "../nix-bindings-store-harmonia" } diff --git a/nix-bindings-store/src/path.rs b/nix-bindings-store/src/path.rs index 689bc45..40bf2c8 100644 --- a/nix-bindings-store/src/path.rs +++ b/nix-bindings-store/src/path.rs @@ -1,8 +1,8 @@ use std::ptr::NonNull; -use anyhow::Result; #[cfg(nix_at_least = "2.33")] use anyhow::Context as AnyhowContext; +use anyhow::Result; use nix_bindings_store_sys as raw; #[cfg(nix_at_least = "2.33")] use nix_bindings_util::{check_call, context::Context}; diff --git a/nix-bindings-store/src/store.rs b/nix-bindings-store/src/store.rs index 76722c6..591f9f6 100644 --- a/nix-bindings-store/src/store.rs +++ b/nix-bindings-store/src/store.rs @@ -433,6 +433,7 @@ impl Clone for Store { #[cfg(test)] pub(crate) mod tests { use ctor::ctor; + use std::collections::HashMap; use super::*; @@ -572,46 +573,44 @@ pub(crate) mod tests { } #[cfg(nix_at_least = "2.33")] - pub(crate) fn create_test_derivation_json() -> String { + pub(crate) fn create_test_derivation() -> harmonia_store_core::derivation::Derivation { let system = current_system().unwrap_or_else(|_| { // Fallback to Rust's platform detection format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS) }); - format!( - r#"{{ - "args": ["-c", "echo $name foo > $out"], - "builder": "/bin/sh", - "env": {{ - "builder": "/bin/sh", - "name": "myname", - "out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9", - "system": "{}" - }}, - "inputs": {{ - "drvs": {{}}, - "srcs": [] - }}, - "name": "myname", - "outputs": {{ - "out": {{ - "hashAlgo": "sha256", - "method": "nar" - }} - }}, - "system": "{}", - "version": 4 - }}"#, - system, system - ) + + harmonia_store_core::derivation::Derivation { + args: vec!["-c".into(), "echo $name foo > $out".into()], + builder: "/bin/sh".into(), + env: BTreeMap::from([ + ("builder".into(), "/bin/sh".into()), + ("name".into(), "myname".into()), + ( + "out".into(), + "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + ), + ("system".into(), system.clone().into()), + ]), + inputs: BTreeSet::new(), + name: "myname".parse().unwrap(), + outputs: BTreeMap::from([( + "out".parse().unwrap(), + DerivationOutput::CAFloating(ContentAddressMethodAlgorithm::Recursive( + Algorithm::SHA256, + )), + )]), + platform: system.clone().into(), + structured_attrs: None, + } } #[test] #[cfg(nix_at_least = "2.33")] fn derivation_from_json() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); - // If we got here, parsing succeeded + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); + // If we got here, creating the derivation succeeded drop(drv); drop(store); drop(temp_dir); @@ -631,8 +630,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn add_derivation() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Verify we got a .drv path @@ -647,8 +646,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn realise() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Build the derivation @@ -665,59 +664,56 @@ pub(crate) mod tests { } #[cfg(nix_at_least = "2.33")] - fn create_multi_output_derivation_json() -> String { + fn create_multi_output_derivation() -> harmonia_store_core::derivation::Derivation { let system = current_system() .unwrap_or_else(|_| format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS)); - format!( - r#"{{ - "version": 4, - "name": "multi-output-test", - "system": "{}", - "builder": "/bin/sh", - "args": ["-c", "echo a > $outa; echo b > $outb; echo c > $outc; echo d > $outd; echo e > $oute; echo f > $outf; echo g > $outg; echo h > $outh; echo i > $outi; echo j > $outj"], - "env": {{ - "builder": "/bin/sh", - "name": "multi-output-test", - "system": "{}", - "outf": "/1vkfzqpwk313b51x0xjyh5s7w1lx141mr8da3dr9wqz5aqjyr2fh", - "outd": "/1ypxifgmbzp5sd0pzsp2f19aq68x5215260z3lcrmy5fch567lpm", - "outi": "/1wmasjnqi12j1mkjbxazdd0qd0ky6dh1qry12fk8qyp5kdamhbdx", - "oute": "/1f9r2k1s168js509qlw8a9di1qd14g5lqdj5fcz8z7wbqg11qp1f", - "outh": "/1rkx1hmszslk5nq9g04iyvh1h7bg8p92zw0hi4155hkjm8bpdn95", - "outc": "/1rj4nsf9pjjqq9jsq58a2qkwa7wgvgr09kgmk7mdyli6h1plas4w", - "outb": "/1p7i1dxifh86xq97m5kgb44d7566gj7rfjbw7fk9iij6ca4akx61", - "outg": "/14f8qi0r804vd6a6v40ckylkk1i6yl6fm243qp6asywy0km535lc", - "outj": "/0gkw1366qklqfqb2lw1pikgdqh3cmi3nw6f1z04an44ia863nxaz", - "outa": "/039akv9zfpihrkrv4pl54f3x231x362bll9afblsgfqgvx96h198" - }}, - "inputs": {{ - "drvs": {{}}, - "srcs": [] - }}, - "outputs": {{ - "outd": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outf": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outg": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outb": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outc": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outi": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outj": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outh": {{ "hashAlgo": "sha256", "method": "nar" }}, - "outa": {{ "hashAlgo": "sha256", "method": "nar" }}, - "oute": {{ "hashAlgo": "sha256", "method": "nar" }} - }} - }}"#, - system, system - ) + harmonia_store_core::derivation::Derivation { + args: vec!["-c".into(), "echo a > $outa; echo b > $outb; echo c > $outc; echo d > $outd; echo e > $oute; echo f > $outf; echo g > $outg; echo h > $outh; echo i > $outi; echo j > $outj".into()], + builder: "/bin/sh".into(), + env: BTreeMap::from([ + ("builder".into(), "/bin/sh".into()), + ("name".into(), "multi-output-test".into()), + ("system".into(), system.clone().into()), + ("outa".into(), "/039akv9zfpihrkrv4pl54f3x231x362bll9afblsgfqgvx96h198".into()), + ("outb".into(), "/1p7i1dxifh86xq97m5kgb44d7566gj7rfjbw7fk9iij6ca4akx61".into()), + ("outc".into(), "/1rj4nsf9pjjqq9jsq58a2qkwa7wgvgr09kgmk7mdyli6h1plas4w".into()), + ("outd".into(), "/1ypxifgmbzp5sd0pzsp2f19aq68x5215260z3lcrmy5fch567lpm".into()), + ("oute".into(), "/1f9r2k1s168js509qlw8a9di1qd14g5lqdj5fcz8z7wbqg11qp1f".into()), + ("outf".into(), "/1vkfzqpwk313b51x0xjyh5s7w1lx141mr8da3dr9wqz5aqjyr2fh".into()), + ("outg".into(), "/14f8qi0r804vd6a6v40ckylkk1i6yl6fm243qp6asywy0km535lc".into()), + ("outh".into(), "/1rkx1hmszslk5nq9g04iyvh1h7bg8p92zw0hi4155hkjm8bpdn95".into()), + ("outi".into(), "/1wmasjnqi12j1mkjbxazdd0qd0ky6dh1qry12fk8qyp5kdamhbdx".into()), + ("outj".into(), "/0gkw1366qklqfqb2lw1pikgdqh3cmi3nw6f1z04an44ia863nxaz".into()), + ]), + inputs: BTreeSet::new(), + name: "multi-output-test".parse().unwrap(), + outputs: { + let ca_floating = DerivationOutput::CAFloating(ContentAddressMethodAlgorithm::Recursive(Algorithm::SHA256)); + BTreeMap::from([ + ("outa".parse().unwrap(), ca_floating.clone()), + ("outb".parse().unwrap(), ca_floating.clone()), + ("outc".parse().unwrap(), ca_floating.clone()), + ("outd".parse().unwrap(), ca_floating.clone()), + ("oute".parse().unwrap(), ca_floating.clone()), + ("outf".parse().unwrap(), ca_floating.clone()), + ("outg".parse().unwrap(), ca_floating.clone()), + ("outh".parse().unwrap(), ca_floating.clone()), + ("outi".parse().unwrap(), ca_floating.clone()), + ("outj".parse().unwrap(), ca_floating), + ]) + }, + platform: system.clone().into(), + structured_attrs: None, + } } #[test] #[cfg(nix_at_least = "2.33")] fn realise_multi_output_ordering() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_multi_output_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_multi_output_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Build the derivation @@ -741,34 +737,31 @@ pub(crate) mod tests { // Create a derivation with an invalid system let system = "bogus65-bogusos"; - let drv_json = format!( - r#"{{ - "args": ["-c", "echo $name foo > $out"], - "builder": "/bin/sh", - "env": {{ - "builder": "/bin/sh", - "name": "myname", - "out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9", - "system": "{}" - }}, - "inputs": {{ - "drvs": {{}}, - "srcs": [] - }}, - "name": "myname", - "outputs": {{ - "out": {{ - "hashAlgo": "sha256", - "method": "nar" - }} - }}, - "system": "{}", - "version": 4 - }}"#, - system, system - ); + let harmonia_drv = harmonia_store_core::derivation::Derivation { + args: vec!["-c".into(), "echo $name foo > $out".into()], + builder: "/bin/sh".into(), + env: BTreeMap::from([ + ("builder".into(), "/bin/sh".into()), + ("name".into(), "myname".into()), + ( + "out".into(), + "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + ), + ("system".into(), system.into()), + ]), + inputs: BTreeSet::new(), + name: "myname".parse().unwrap(), + outputs: BTreeMap::from([( + "out".parse().unwrap(), + DerivationOutput::CAFloating(ContentAddressMethodAlgorithm::Recursive( + Algorithm::SHA256, + )), + )]), + platform: system.into(), + structured_attrs: None, + }; - let drv = store.derivation_from_json(&drv_json).unwrap(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Try to build - should fail @@ -796,34 +789,31 @@ pub(crate) mod tests { .unwrap_or_else(|_| format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS)); // Create a derivation where the builder exits with error - let drv_json = format!( - r#"{{ - "args": ["-c", "exit 1"], - "builder": "/bin/sh", - "env": {{ - "builder": "/bin/sh", - "name": "failing", - "out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9", - "system": "{}" - }}, - "inputs": {{ - "drvs": {{}}, - "srcs": [] - }}, - "name": "failing", - "outputs": {{ - "out": {{ - "hashAlgo": "sha256", - "method": "nar" - }} - }}, - "system": "{}", - "version": 4 - }}"#, - system, system - ); + let harmonia_drv = harmonia_store_core::derivation::Derivation { + args: vec!["-c".into(), "exit 1".into()], + builder: "/bin/sh".into(), + env: BTreeMap::from([ + ("builder".into(), "/bin/sh".into()), + ("name".into(), "failing".into()), + ( + "out".into(), + "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + ), + ("system".into(), system.clone().into()), + ]), + inputs: BTreeSet::new(), + name: "failing".parse().unwrap(), + outputs: BTreeMap::from([( + "out".parse().unwrap(), + DerivationOutput::CAFloating(ContentAddressMethodAlgorithm::Recursive( + Algorithm::SHA256, + )), + )]), + platform: system.clone().into(), + structured_attrs: None, + }; - let drv = store.derivation_from_json(&drv_json).unwrap(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Try to build - should fail @@ -851,34 +841,31 @@ pub(crate) mod tests { .unwrap_or_else(|_| format!("{}-{}", std::env::consts::ARCH, std::env::consts::OS)); // Create a derivation where the builder succeeds but produces no output - let drv_json = format!( - r#"{{ - "args": ["-c", "true"], - "builder": "/bin/sh", - "env": {{ - "builder": "/bin/sh", - "name": "no-output", - "out": "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9", - "system": "{}" - }}, - "inputs": {{ - "drvs": {{}}, - "srcs": [] - }}, - "name": "no-output", - "outputs": {{ - "out": {{ - "hashAlgo": "sha256", - "method": "nar" - }} - }}, - "system": "{}", - "version": 4 - }}"#, - system, system - ); + let harmonia_drv = harmonia_store_core::derivation::Derivation { + args: vec!["-c".into(), "true".into()], + builder: "/bin/sh".into(), + env: BTreeMap::from([ + ("builder".into(), "/bin/sh".into()), + ("name".into(), "no-output".into()), + ( + "out".into(), + "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + ), + ("system".into(), system.clone().into()), + ]), + inputs: BTreeSet::new(), + name: "no-output".parse().unwrap(), + outputs: BTreeMap::from([( + "out".parse().unwrap(), + DerivationOutput::CAFloating(ContentAddressMethodAlgorithm::Recursive( + Algorithm::SHA256, + )), + )]), + platform: system.clone().into(), + structured_attrs: None, + }; - let drv = store.derivation_from_json(&drv_json).unwrap(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Try to build - should fail @@ -901,8 +888,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn get_fs_closure_with_outputs() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Build the derivation to get the output path @@ -934,8 +921,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn get_fs_closure_without_outputs() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Build the derivation to get the output path @@ -963,8 +950,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn get_fs_closure_flip_direction() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); // Build the derivation to get the output path @@ -990,8 +977,8 @@ pub(crate) mod tests { #[cfg(nix_at_least = "2.33")] fn get_fs_closure_include_derivers() { let (mut store, temp_dir) = create_temp_store(); - let drv_json = create_test_derivation_json(); - let drv = store.derivation_from_json(&drv_json).unwrap(); + let harmonia_drv = create_test_derivation(); + let drv = crate::derivation::harmonia_to_nix(&mut store, &harmonia_drv).unwrap(); let drv_path = store.add_derivation(&drv).unwrap(); let drv_path_name = drv_path.name().unwrap(); From 1fe5dce56a846d23d0ffd8f97c249ab505e83ac7 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Thu, 27 Nov 2025 12:17:01 -0500 Subject: [PATCH 8/8] Use new placeholder interface from Harmonia It makes some tests more readable. --- nix-bindings-store/src/store.rs | 56 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/nix-bindings-store/src/store.rs b/nix-bindings-store/src/store.rs index 591f9f6..a3b7d92 100644 --- a/nix-bindings-store/src/store.rs +++ b/nix-bindings-store/src/store.rs @@ -433,9 +433,19 @@ impl Clone for Store { #[cfg(test)] pub(crate) mod tests { use ctor::ctor; - use std::collections::HashMap; + #[cfg(nix_at_least = "2.33")] + use harmonia_store_core::derivation::DerivationOutput; + #[cfg(nix_at_least = "2.33")] + use harmonia_store_core::placeholder::Placeholder; + #[cfg(nix_at_least = "2.33")] + use harmonia_store_core::store_path::ContentAddressMethodAlgorithm; + #[cfg(nix_at_least = "2.33")] + use harmonia_utils_hash::Algorithm; + #[cfg(nix_at_least = "2.33")] + use std::collections::{BTreeMap, BTreeSet}; + use super::*; #[ctor] @@ -587,7 +597,11 @@ pub(crate) mod tests { ("name".into(), "myname".into()), ( "out".into(), - "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + Placeholder::standard_output(&"out".parse().unwrap()) + .render() + .to_string_lossy() + .to_string() + .into(), ), ("system".into(), system.clone().into()), ]), @@ -675,16 +689,16 @@ pub(crate) mod tests { ("builder".into(), "/bin/sh".into()), ("name".into(), "multi-output-test".into()), ("system".into(), system.clone().into()), - ("outa".into(), "/039akv9zfpihrkrv4pl54f3x231x362bll9afblsgfqgvx96h198".into()), - ("outb".into(), "/1p7i1dxifh86xq97m5kgb44d7566gj7rfjbw7fk9iij6ca4akx61".into()), - ("outc".into(), "/1rj4nsf9pjjqq9jsq58a2qkwa7wgvgr09kgmk7mdyli6h1plas4w".into()), - ("outd".into(), "/1ypxifgmbzp5sd0pzsp2f19aq68x5215260z3lcrmy5fch567lpm".into()), - ("oute".into(), "/1f9r2k1s168js509qlw8a9di1qd14g5lqdj5fcz8z7wbqg11qp1f".into()), - ("outf".into(), "/1vkfzqpwk313b51x0xjyh5s7w1lx141mr8da3dr9wqz5aqjyr2fh".into()), - ("outg".into(), "/14f8qi0r804vd6a6v40ckylkk1i6yl6fm243qp6asywy0km535lc".into()), - ("outh".into(), "/1rkx1hmszslk5nq9g04iyvh1h7bg8p92zw0hi4155hkjm8bpdn95".into()), - ("outi".into(), "/1wmasjnqi12j1mkjbxazdd0qd0ky6dh1qry12fk8qyp5kdamhbdx".into()), - ("outj".into(), "/0gkw1366qklqfqb2lw1pikgdqh3cmi3nw6f1z04an44ia863nxaz".into()), + ("outa".into(), Placeholder::standard_output(&"outa".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outb".into(), Placeholder::standard_output(&"outb".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outc".into(), Placeholder::standard_output(&"outc".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outd".into(), Placeholder::standard_output(&"outd".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("oute".into(), Placeholder::standard_output(&"oute".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outf".into(), Placeholder::standard_output(&"outf".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outg".into(), Placeholder::standard_output(&"outg".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outh".into(), Placeholder::standard_output(&"outh".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outi".into(), Placeholder::standard_output(&"outi".parse().unwrap()).render().to_string_lossy().to_string().into()), + ("outj".into(), Placeholder::standard_output(&"outj".parse().unwrap()).render().to_string_lossy().to_string().into()), ]), inputs: BTreeSet::new(), name: "multi-output-test".parse().unwrap(), @@ -745,7 +759,11 @@ pub(crate) mod tests { ("name".into(), "myname".into()), ( "out".into(), - "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + Placeholder::standard_output(&"out".parse().unwrap()) + .render() + .to_string_lossy() + .to_string() + .into(), ), ("system".into(), system.into()), ]), @@ -797,7 +815,11 @@ pub(crate) mod tests { ("name".into(), "failing".into()), ( "out".into(), - "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + Placeholder::standard_output(&"out".parse().unwrap()) + .render() + .to_string_lossy() + .to_string() + .into(), ), ("system".into(), system.clone().into()), ]), @@ -849,7 +871,11 @@ pub(crate) mod tests { ("name".into(), "no-output".into()), ( "out".into(), - "/1rz4g4znpzjwh1xymhjpm42vipw92pr73vdgl6xs1hycac8kf2n9".into(), + Placeholder::standard_output(&"out".parse().unwrap()) + .render() + .to_string_lossy() + .to_string() + .into(), ), ("system".into(), system.clone().into()), ]),