beed354904
testRustSimple is intended to wrap rustSimpleLib and rustSimpleBin and theoretically pkgs.buildRustCrate with { buildTests = false; } while building and running their tests, making them fail if the tests don't succeed. This is implemented using nix.drvSeqL which is a perfect fit here: * { buildTests = true; } only returns an output with the test binaries and does not actually run the tests. With drvSeqL we can easily wrap this derivation. * { buildTests = true } doesn't contain anything other derivations want to depend on, so it is an derivation output we don't want to have. drvSeqL hides the tests derivation away and only requires us to build it once. * Usually drvSeqL has the issue that tests (or advantage) are not rebuilt if the test derivation changes. This is no question in this case as due to the embedded nature of Rust's test, both the derivation with and without tests change anyways regardless of which part was changed. Future work: Allow injecting other tests? Change-Id: If6ecfb3a360ce059320dbb05642b391b617aede7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2529 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
163 lines
4 KiB
Nix
163 lines
4 KiB
Nix
{ depot, pkgs, lib, ... }:
|
|
let
|
|
bins = depot.nix.getBins pkgs.coreutils ["printf" "mkdir" "cat" "ln" "ls" "touch" ];
|
|
|
|
inherit (depot.nix.yants) defun struct restrict attrs list string drv any;
|
|
|
|
inherit (depot.nix) drvSeqL;
|
|
|
|
FlakeError =
|
|
restrict
|
|
"flake error"
|
|
(s: lib.any (prefix: (builtins.substring 0 1 s) == prefix)
|
|
[ "E" "W" ])
|
|
string;
|
|
Libraries = defun [ (attrs any) (list drv) ];
|
|
|
|
python3 = {
|
|
name,
|
|
libraries ? (_: []),
|
|
flakeIgnore ? []
|
|
}: pkgs.writers.writePython3 name {
|
|
libraries = Libraries libraries pkgs.python3Packages;
|
|
flakeIgnore =
|
|
let ignoreTheseErrors = [
|
|
# whitespace after {
|
|
"E201"
|
|
# whitespace before }
|
|
"E202"
|
|
# fuck 4-space indentation
|
|
"E121" "E111"
|
|
# who cares about blank lines …
|
|
# … at end of files
|
|
"W391"
|
|
# … between functions
|
|
"E302" "E305"
|
|
];
|
|
in list FlakeError (ignoreTheseErrors ++ flakeIgnore);
|
|
};
|
|
|
|
# TODO: add the same flake check as the pyhon3 writer
|
|
python3Lib = { name, libraries ? (_: []) }: moduleString:
|
|
let srcTree = depot.nix.runExecline.local name { stdin = moduleString; } [
|
|
"importas" "out" "out"
|
|
"if" [ bins.mkdir "-p" "\${out}/${name}" ]
|
|
"if" [
|
|
"redirfd" "-w" "1" "\${out}/setup.py"
|
|
bins.printf ''
|
|
from distutils.core import setup
|
|
|
|
setup(
|
|
name='%s',
|
|
packages=['%s']
|
|
)
|
|
'' name name
|
|
]
|
|
"if" [
|
|
# redirect stdin to the init py
|
|
"redirfd" "-w" "1" "\${out}/${name}/__init__.py"
|
|
bins.cat
|
|
]
|
|
];
|
|
in pkgs.python3Packages.buildPythonPackage {
|
|
inherit name;
|
|
src = srcTree;
|
|
propagatedBuildInputs = libraries pkgs.python3Packages;
|
|
doCheck = false;
|
|
};
|
|
|
|
rustSimple = args@{name, ...}: src:
|
|
linkTo name "${rustSimpleBin args src}/bin/${name}";
|
|
|
|
linkTo = name: path: depot.nix.runExecline.local name {} [
|
|
"importas" "out" "out"
|
|
bins.ln "-sT" path "$out"
|
|
];
|
|
|
|
rustSimpleBin = {
|
|
name,
|
|
dependencies ? [],
|
|
...
|
|
}@args: src: 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);
|
|
|
|
rustSimpleLib = {
|
|
name,
|
|
dependencies ? [],
|
|
...
|
|
}@args: src: 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.ls "${crate true}/tests" ]
|
|
"forstdin" "test"
|
|
"importas" "test" "test"
|
|
"${crate true}/tests/$test"
|
|
]
|
|
bins.touch "$out"
|
|
];
|
|
in drvSeqL [ tests ] (crate false);
|
|
|
|
|
|
tests = import ./tests.nix {
|
|
inherit
|
|
depot
|
|
pkgs
|
|
python3
|
|
python3Lib
|
|
rustSimpleLib
|
|
rustSimple
|
|
;
|
|
};
|
|
|
|
in {
|
|
inherit
|
|
python3
|
|
python3Lib
|
|
rustSimple
|
|
rustSimpleBin
|
|
rustSimpleLib
|
|
testRustSimple
|
|
tests
|
|
;
|
|
}
|