nix: Add flake check that builds at MSRV

This commit is contained in:
Lorenz Leutgeb 2025-05-13 11:38:36 +02:00 committed by Fintan Halpenny
parent 105b65c2ac
commit 41f9048d96
1 changed files with 118 additions and 99 deletions

197
flake.nix
View File

@ -46,8 +46,19 @@
overlays = [(import rust-overlay)]; overlays = [(import rust-overlay)];
}; };
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; msrv = let
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; msrv = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.rust-version;
in rec {
toolchain = pkgs.rust-bin.stable.${msrv}.default;
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
commonArgs = mkCommonArgs craneLib;
};
rustup = rec {
toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
commonArgs = mkCommonArgs craneLib;
};
srcFilters = path: type: srcFilters = path: type:
builtins.any (suffix: lib.hasSuffix suffix path) [ builtins.any (suffix: lib.hasSuffix suffix path) [
@ -56,10 +67,11 @@
".md" # testing ".md" # testing
".adoc" # man pages ".adoc" # man pages
".json" # testing samples ".json" # testing samples
"rad-cob-multiset" # testing external COBs
] ]
|| ||
# Default filter from crane (allow .rs files) # Default filter from crane (allow .rs files)
(craneLib.filterCargoSources path type); (rustup.craneLib.filterCargoSources path type);
src = lib.cleanSourceWith { src = lib.cleanSourceWith {
src = ./.; src = ./.;
@ -72,23 +84,25 @@
strictDeps = true; strictDeps = true;
}; };
# Common arguments can be set here to avoid repeating them later
mkCommonArgs = craneLib:
basicArgs
// {
# Build *just* the cargo dependencies, so we can reuse # Build *just* the cargo dependencies, so we can reuse
# all of that work (e.g. via cachix) when running in CI # all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib.buildDepsOnly basicArgs; cargoArtifacts = craneLib.buildDepsOnly basicArgs;
# Common arguments can be set here to avoid repeating them later
commonArgs =
basicArgs
// {
inherit cargoArtifacts;
nativeBuildInputs = with pkgs; [ nativeBuildInputs = with pkgs; [
asciidoctor
git git
# Add additional build inputs here installShellFiles
]; ];
buildInputs = lib.optionals pkgs.stdenv.buildPlatform.isDarwin (with pkgs; [ buildInputs = lib.optionals pkgs.stdenv.buildPlatform.isDarwin (with pkgs; [
darwin.apple_sdk.frameworks.Security darwin.apple_sdk.frameworks.Security
]); ]);
nativeCheckInputs = with pkgs; [
jq
];
env = env =
{ {
@ -102,88 +116,16 @@
else {} else {}
); );
}; };
in {
# Formatter
formatter = pkgs.alejandra;
# Set of checks that are run: `nix flake check` buildCrate = rust: {
checks = {
pre-commit-check = inputs.git-hooks.lib.${system}.run {
src = ./.;
settings.rust.check.cargoDeps = pkgs.rustPlatform.importCargoLock {lockFile = ./Cargo.lock;};
hooks = {
alejandra.enable = true;
rustfmt.enable = true;
cargo-check = {
enable = true;
stages = ["pre-push"];
};
clippy = {
enable = true;
stages = ["pre-push"];
settings.denyWarnings = true;
packageOverrides.cargo = rustToolchain;
packageOverrides.clippy = rustToolchain;
};
shellcheck.enable = true;
};
};
# Build the crate as part of `nix flake check` for convenience
inherit (self.packages.${system}) radicle;
# Run clippy (and deny all warnings) on the crate source,
# again, reusing the dependency artifacts from above.
#
# Note that this is done as a separate derivation so that
# we can block the CI if there are issues here, but not
# prevent downstream consumers from building our crate by itself.
clippy = craneLib.cargoClippy (commonArgs
// {
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
});
doc = craneLib.cargoDoc commonArgs;
deny = craneLib.cargoDeny commonArgs;
fmt = craneLib.cargoFmt basicArgs;
audit = craneLib.cargoAudit {
inherit src advisory-db;
};
# Run tests with cargo-nextest
nextest = craneLib.cargoNextest (commonArgs
// {
partitions = 1;
partitionType = "count";
nativeBuildInputs = [
# git is required so the sandbox can access it.
pkgs.git
];
# Ensure that the binaries are built for the radicle-cli tests to
# avoid timeouts
preCheck = ''
cargo build -p radicle-remote-helper --target-dir radicle-cli/target
cargo build -p radicle-cli --target-dir radicle-cli/target
'';
# Ensure dev is used since we rely on env variables being
# set in tests.
env.CARGO_PROFILE = "dev";
});
};
packages = let
crate = {
name, name,
pages ? [], pages ? [],
}: }:
craneLib.buildPackage (commonArgs rust.craneLib.buildPackage (rust.commonArgs
// { // {
inherit (craneLib.crateNameFromCargoToml {cargoToml = src + "/" + name + "/Cargo.toml";}) pname version; inherit (rust.craneLib.crateNameFromCargoToml {cargoToml = src + "/" + name + "/Cargo.toml";}) pname version;
cargoExtraArgs = "-p ${name}"; cargoExtraArgs = "-p ${name}";
doCheck = false; doCheck = false;
nativeBuildInputs = with pkgs; [asciidoctor installShellFiles jq];
postInstall = '' postInstall = ''
for page in ${lib.escapeShellArgs pages}; do for page in ${lib.escapeShellArgs pages}; do
asciidoctor -d manpage -b manpage $page asciidoctor -d manpage -b manpage $page
@ -191,8 +133,12 @@
done done
''; '';
}); });
crates = builtins.listToAttrs (map buildCrates = {
({name, ...} @ package: lib.nameValuePair name (crate package)) rust ? rustup,
prefix ? "",
}:
builtins.listToAttrs (map
({name, ...} @ package: lib.nameValuePair (prefix + name) ((buildCrate rust) package))
[ [
{ {
name = "radicle-cli"; name = "radicle-cli";
@ -211,6 +157,79 @@
pages = ["radicle-node.1.adoc"]; pages = ["radicle-node.1.adoc"];
} }
]); ]);
in {
# Formatter
formatter = pkgs.alejandra;
# Set of checks that are run: `nix flake check`
checks =
(buildCrates {
rust = msrv;
prefix = "msrv-";
})
// {
pre-commit-check = inputs.git-hooks.lib.${system}.run {
src = ./.;
settings.rust.check.cargoDeps = pkgs.rustPlatform.importCargoLock {lockFile = ./Cargo.lock;};
hooks = {
alejandra.enable = true;
rustfmt.enable = true;
cargo-check = {
enable = true;
stages = ["pre-push"];
};
clippy = {
enable = true;
stages = ["pre-push"];
settings.denyWarnings = true;
packageOverrides.cargo = rustup.toolchain;
packageOverrides.clippy = rustup.toolchain;
};
shellcheck.enable = true;
};
};
# Build the crate as part of `nix flake check` for convenience
inherit (self.packages.${system}) radicle;
# Run clippy (and deny all warnings) on the crate source,
# again, reusing the dependency artifacts from above.
#
# Note that this is done as a separate derivation so that
# we can block the CI if there are issues here, but not
# prevent downstream consumers from building our crate by itself.
clippy = rustup.craneLib.cargoClippy (rustup.commonArgs
// {
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
});
doc = rustup.craneLib.cargoDoc rustup.commonArgs;
deny = rustup.craneLib.cargoDeny rustup.commonArgs;
fmt = rustup.craneLib.cargoFmt basicArgs;
audit = rustup.craneLib.cargoAudit {
inherit src advisory-db;
};
# Run tests with cargo-nextest
nextest = rustup.craneLib.cargoNextest (rustup.commonArgs
// {
# Ensure that the binaries are built for the radicle-cli tests to
# avoid timeouts
preCheck = ''
patchShebangs --build radicle-cli/examples/rad-cob-multiset
cargo build -p radicle-remote-helper --target-dir radicle-cli/target
cargo build -p radicle-cli --target-dir radicle-cli/target
'';
# Ensure dev is used since we rely on env variables being
# set in tests.
env.CARGO_PROFILE = "dev";
cargoNextestExtraArgs = "--no-capture";
});
};
packages = let
crates = buildCrates {};
in in
crates crates
// rec { // rec {
@ -253,7 +272,7 @@
drv = self.packages.${system}.radicle-node; drv = self.packages.${system}.radicle-node;
}; };
devShells.default = craneLib.devShell { devShells.default = rustup.craneLib.devShell {
inherit (self.checks.${system}.pre-commit-check) shellHook; inherit (self.checks.${system}.pre-commit-check) shellHook;
buildInputs = self.checks.${system}.pre-commit-check.enabledPackages; buildInputs = self.checks.${system}.pre-commit-check.enabledPackages;
@ -268,7 +287,7 @@
sqlite sqlite
]; ];
env.RUST_SRC_PATH = "${rustToolchain}/lib/rustlib/src/rust/library"; env.RUST_SRC_PATH = "${rustup.toolchain}/lib/rustlib/src/rust/library";
}; };
}); });
} }