diff options
author | Profpatsch <mail@profpatsch.de> | 2021-04-23T20·04+0200 |
---|---|---|
committer | Profpatsch <mail@profpatsch.de> | 2021-04-24T10·23+0000 |
commit | eb41eef6127216543d8b28c9c423ac1be0a4ee24 (patch) | |
tree | c01e67c4062711b3623841e8e56791ec8a14edc1 /nix/writers | |
parent | 7e888c3c7bb36f6ab6e83d4a6f6a755ff4156791 (diff) |
chore(nix): move rustSimple from users.Profpatsch.writers r/2547
I think it’s solid enough to use in a wider context. Change-Id: If53e8bbb6b90fa88d73fb42730db470e822ea182 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3055 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: lukegb <lukegb@tvl.fyi>
Diffstat (limited to 'nix/writers')
-rw-r--r-- | nix/writers/default.nix | 97 | ||||
-rw-r--r-- | nix/writers/tests/rust.nix | 68 |
2 files changed, 165 insertions, 0 deletions
diff --git a/nix/writers/default.nix b/nix/writers/default.nix new file mode 100644 index 000000000000..f43761865fc2 --- /dev/null +++ b/nix/writers/default.nix @@ -0,0 +1,97 @@ +{ depot, pkgs, lib, ... }: + +let + bins = depot.nix.getBins pkgs.s6-portable-utils [ "s6-ln" "s6-ls" "s6-touch" ] + ; + + linkTo = name: path: depot.nix.runExecline.local name {} [ + "importas" "out" "out" + bins.s6-ln "-s" path "$out" + ]; + + # Build a rust executable. + # Takes all arguments that `pkgs.buildRustCrate` accepts. + # Rather leaky abstraction. + rustSimple = args@{name, ...}: src: + linkTo name "${rustSimpleBin args src}/bin/${name}"; + + # Like `rustSimple`, but put the binary in `$out/bin/`. + rustSimpleBin = { + name, + dependencies ? [], + doCheck ? true, + ... + }@args: src: + (if doCheck then testRustSimple else pkgs.lib.id) + (pkgs.buildRustCrate ({ + pname = name; + version = "1.0.0"; + crateName = name; + crateBin = [ name ]; + dependencies = dependencies; + src = pkgs.runCommandLocal "write-main.rs" { + src = src; + passAsFile = [ "src" ]; + } '' + mkdir -p $out/src/bin + cp "$srcPath" $out/src/bin/${name}.rs + find $out + ''; + } // args)); + + # Build a rust library, that can be used as dependency to `rustSimple`. + # Wrapper around `pkgs.buildRustCrate`, takes all its arguments. + rustSimpleLib = { + name, + dependencies ? [], + doCheck ? true, + ... + }@args: src: + (if doCheck then testRustSimple else pkgs.lib.id) + (pkgs.buildRustCrate ({ + pname = name; + version = "1.0.0"; + crateName = name; + dependencies = dependencies; + src = pkgs.runCommandLocal "write-lib.rs" { + src = src; + passAsFile = [ "src" ]; + } '' + mkdir -p $out/src + cp "$srcPath" $out/src/lib.rs + find $out + ''; + } // args)); + + /* Takes a `buildRustCrate` derivation as an input, + * builds it with `{ buildTests = true; }` and runs + * all tests found in its `tests` dir. If they are + * all successful, `$out` will point to the crate + * built with `{ buildTests = false; }`, otherwise + * it will fail to build. + * + * See also `nix.drvSeqL` which is used to implement + * this behavior. + */ + testRustSimple = rustDrv: + let + crate = buildTests: rustDrv.override { inherit buildTests; }; + tests = depot.nix.runExecline.local "${rustDrv.name}-tests-run" {} [ + "importas" "out" "out" + "if" [ + "pipeline" [ bins.s6-ls "${crate true}/tests" ] + "forstdin" "-o0" "test" + "importas" "test" "test" + "${crate true}/tests/$test" + ] + bins.s6-touch "$out" + ]; + in depot.nix.drvSeqL [ tests ] (crate false); + +in { + inherit + rustSimple + rustSimpleBin + rustSimpleLib + ; +} diff --git a/nix/writers/tests/rust.nix b/nix/writers/tests/rust.nix new file mode 100644 index 000000000000..4b87676118f5 --- /dev/null +++ b/nix/writers/tests/rust.nix @@ -0,0 +1,68 @@ +{ depot, pkgs, ... }: + +let + inherit (depot.nix.writers) + rustSimple + rustSimpleLib + rustSimpleBin + ; + + inherit (pkgs) + coreutils + ; + + run = drv: depot.nix.runExecline.local "run-${drv.name}" {} [ + "if" [ drv ] + "importas" "out" "out" + "${coreutils}/bin/touch" "$out" + ]; + + rustTransitiveLib = rustSimpleLib { + name = "transitive"; + } '' + pub fn transitive(s: &str) -> String { + let mut new = s.to_string(); + new.push_str(" 1 2 3"); + new + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn test_transitive() { + assert_eq!(transitive("foo").as_str(), "foo 1 2 3") + } + } + ''; + + rustTestLib = rustSimpleLib { + name = "test_lib"; + dependencies = [ rustTransitiveLib ]; + } '' + extern crate transitive; + use transitive::{transitive}; + pub fn test() -> String { + transitive("test") + } + ''; + + rustWithLib = run (rustSimple { + name = "rust-with-lib"; + dependencies = [ rustTestLib ]; + } '' + extern crate test_lib; + + fn main() { + assert_eq!(test_lib::test(), String::from("test 1 2 3")); + } + ''); + + +in depot.nix.utils.drvTargets { + inherit + rustTransitiveLib + rustWithLib + ; +} |