1
Fork 0
kantodb/flake.nix

261 lines
9.5 KiB
Nix

{
inputs = {
nixpkgs.url = github:nixos/nixpkgs;
nix-systems = {
url = github:nix-systems/default;
};
flake-utils = {
url = github:numtide/flake-utils;
inputs.systems.follows = "nix-systems";
};
rust-overlay = {
url = github:oxalica/rust-overlay;
inputs.nixpkgs.follows = "nixpkgs";
};
crane = {
url = "github:ipetkov/crane";
};
};
outputs = { self, flake-utils, ... }@inputs:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import inputs.nixpkgs {
inherit system;
overlays = [
inputs.rust-overlay.overlays.default
];
};
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rustToolchain;
cargoMeta = craneLib.crateNameFromCargoToml { cargoToml = ./crates/server/Cargo.toml; };
commonEnv = {
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
};
nightlyRustFlags = [
# TODO this should be in a config file (by profile, maybe not in released software?), not in environment; also want stabilized <https://github.com/rust-lang/rust/issues/106764> #dev #waiting #ecosystem/rust #severity/low #urgency/low
# background: <https://github.com/rust-lang/miri/issues/2656>
"-Zrandomize-layout"
];
commonNightlyEnv = {
RUSTFLAGS = pkgs.lib.strings.concatStringsSep " " nightlyRustFlags;
};
miriFlags = [
## necessary
# rkyv v0.8.10 does not fit the assumptions of the Stacked Borrows checker; Tree Borrows seems to considered less like actual Rust? <https://github.com/rkyv/rkyv/issues/436#issuecomment-1767450952> #ecosystem
# TODO this should be in a config file, not in environment <https://github.com/rust-lang/miri/issues/2347> #waiting #ecosystem/miri #severity/low #urgency/low
"-Zmiri-tree-borrows"
## optional
# detect more alignment issues
"-Zmiri-symbolic-alignment-check"
# detect more pointer issues
"-Zmiri-strict-provenance"
# simulate a larger computer, so we expose more concurrency issues
"-Zmiri-num-cpus=16"
# test more nondeterministic paths
"-Zmiri-many-seeds=..8"
];
miriEnv = {
MIRIFLAGS = pkgs.lib.strings.concatStringsSep " " miriFlags;
};
src = craneLib.cleanCargoSource ./.;
commonArgs = commonEnv // {
inherit src;
strictDeps = true;
nativeBuildInputs = with pkgs; [
pkg-config
clang
];
buildInputs = with pkgs; [
liburing
];
};
cargoArtifacts = craneLib.buildDepsOnly (commonArgs);
individualCrateArgs = commonArgs // {
inherit cargoArtifacts;
inherit (craneLib.crateNameFromCargoToml { inherit src; }) version;
# NOTE: we disable tests since we'll run them all via cargo-nextest
doCheck = false;
};
fileSetForCrate = crate: pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
(craneLib.fileset.cargoTomlAndLock ./.)
# TODO maybe use craneLib.fileset.commonCargoSources on all
./crates/arbitrary-arrow
./crates/backend-rocksdb
./crates/index-format-v1
./crates/kanto
./crates/key-format-v1
./crates/maybe-tracing
./crates/meta-format-v1
./crates/protocol-postgres
./crates/record-format-v1
./crates/rocky
./crates/testutil
./crates/tunables
# These are undesirable, but cargo fails to start if a workspace-members glob doesn't match anything.
./task/lint-unimplemented-sql
./task/lint-unique-error-codes
(craneLib.fileset.commonCargoSources crate)
];
};
crate-kanto-server = craneLib.buildPackage (individualCrateArgs // {
inherit (cargoMeta) pname version;
cargoExtraArgs = "-p kanto-server";
src = fileSetForCrate ./crates/server;
# We'll run workspace-wide nextest instead.
doCheck = false;
});
devShellPackages = with pkgs; [
nixpkgs-fmt
taplo
rust-analyzer
cargo-deny
cargo-shear
cargo-nextest
cargo-llvm-cov
cargo-mutants
cargo-spellcheck
typos
typos-lsp
mdbook
valgrind
cargo-valgrind
rr
# used for `llvm-symbolizer` for <https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html>
libllvm
];
in
rec {
# `nix build`
packages = {
inherit crate-kanto-server;
default = crate-kanto-server;
doc-manual =
let
src = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
./doc/manual
];
};
in
pkgs.runCommand "kantodb-manual" { } ''
# TODO mdbook breaks when source is read-only <https://github.com/rust-lang/mdBook/issues/1015> #waiting #ecosystem/mdbook
cp --recursive --no-dereference --preserve=links --no-preserve=mode -- "${src}/doc/manual" /tmp/mdbook-build
"${pkgs.mdbook}/bin/mdbook" build --dest-dir "$out" "/tmp/mdbook-build"
'';
doc-developer-guide =
let
src = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
./doc/dev
];
};
in
pkgs.runCommand "kantodb-developer-guide" { } ''
# TODO mdbook breaks when source is read-only <https://github.com/rust-lang/mdBook/issues/1015> #waiting #ecosystem/mdbook
cp --recursive --no-dereference --preserve=links --no-preserve=mode -- "${src}/doc/dev" /tmp/mdbook-build
"${pkgs.mdbook}/bin/mdbook" build --dest-dir "$out" "/tmp/mdbook-build"
'';
};
# `nix run`
apps = rec {
kantodb = flake-utils.lib.mkApp {
drv = crate-kanto-server;
};
default = kantodb;
};
# `nix flake check`
checks = {
inherit crate-kanto-server;
clippy = craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
});
rustdoc = craneLib.cargoDoc (commonArgs // {
inherit cargoArtifacts;
});
lint-rustfmt =
let
rustToolchain = (p: p.rust-bin.nightly.latest.default);
craneLibNightly = (inputs.crane.mkLib pkgs).overrideToolchain rustToolchain;
in
craneLibNightly.cargoFmt {
inherit src;
rustFmtExtraArgs = "--unstable-features --config-path=./rustfmt-unstable.toml";
};
lint-cargo-deny = craneLib.cargoDeny {
inherit src;
};
nextest = craneLib.cargoNextest (commonArgs // {
inherit cargoArtifacts;
partitions = 10;
partitionType = "hash";
});
# TODO nextest does not support `cargo test --doc`, so run it separately <https://github.com/nextest-rs/nextest/issues/16> #ecosystem
doctest = craneLib.cargoDocTest (individualCrateArgs // {
doCheck = true;
});
lint-toml-fmt = craneLib.taploFmt {
src = pkgs.lib.sources.sourceFilesBySuffices src [ ".toml" ];
taploExtraArgs = "--config ./taplo.toml --diff";
};
coverage-llvm = craneLib.cargoLlvmCov (commonArgs // {
inherit cargoArtifacts;
});
};
# `nix develop`
devShells.default = craneLib.devShell (commonEnv // {
inputsFrom = [ crate-kanto-server ];
packages = devShellPackages;
});
devShells.fuzz =
let
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain-fuzz.toml;
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rustToolchain;
in
craneLib.devShell (commonEnv // commonNightlyEnv // {
inputsFrom = [ crate-kanto-server ];
packages = devShellPackages ++ (with pkgs; [
cargo-fuzz
libllvm
]);
# TODO `cargo-fuzz` fails to build or is very slow with lto <https://github.com/rust-fuzz/cargo-fuzz/issues/384> #waiting #ecosystem/cargo-fuzz
CARGO_PROFILE_RELEASE_LTO = "false";
# TODO hopefully speed up `cargo fuzz build` <https://github.com/rust-lang/rust/issues/95240#issuecomment-2459752923> #waiting #ecosystem/cargo-fuzz
CARGO_INCREMENTAL = "0";
});
devShells.miri =
let
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain-miri.toml;
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rustToolchain;
in
craneLib.devShell (commonEnv // commonNightlyEnv // miriEnv // {
inputsFrom = [ crate-kanto-server ];
packages = with pkgs; [
cargo-nextest
];
});
});
}