Files
project-templates/rust.nix
T

174 lines
5.6 KiB
Nix

{
flake-parts-lib,
inputs,
...
}: {
flake = {
templates = {
rust = {
path = ./rust;
description = "A rust flake with crane and templates for command args and configs";
};
};
flakeModules.rust = {
imports = [
inputs.treefmt-nix.flakeModule
];
options.perSystem = flake-parts-lib.mkPerSystemOption ({
lib,
config,
pkgs,
...
}: let
cfg = config.krantz.rust;
craneLib = inputs.crane.mkLib pkgs;
src = craneLib.cleanCargoSource cfg.src;
manifest = (lib.importTOML "${src}/Cargo.toml").package;
buildInputs = cfg.runtimeDeps;
# build dependencies
nativeBuildInputs = cfg.buildDeps;
# Build *just* the cargo dependencies, so we can reuse
# all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib.buildDepsOnly {
inherit src buildInputs nativeBuildInputs;
};
in {
options.krantz.rust = {
enable = lib.mkEnableOption "building a cargo project with crane";
src = lib.mkOption {
description = "The path to the root of the crate.";
type = lib.types.path;
example = lib.literalExpression "./.";
};
srcFiltered = lib.mkOption {
description = "A path to the filtered directory of the root of the crate.";
type = lib.types.path;
default = craneLib.cleanCargoSource cfg.src;
defaultText = lib.literalExpression "config.krantz.rust.craneLib cfg.src";
example = lib.literalExpression "./.";
};
runtimeDeps = lib.mkOption {
description = "Packages needed for the app to run.";
type = lib.types.listOf lib.types.package;
default = [];
example = with pkgs; [
openssl
];
};
buildDeps = lib.mkOption {
description = "Packages needed for the app to build.";
type = lib.types.listOf lib.types.package;
default = [];
example = with pkgs; [
pkg-config
rustPlatform.bindgenHook
];
};
devDeps = lib.mkOption {
description = "Packages to include only in the devShell.";
type = lib.types.listOf lib.types.package;
default = with pkgs; [
rust-analyzer
];
};
devShell = {
enable = lib.mkEnableOption "a rust development environment" // {default = true;};
name = lib.mkOption {
description = "The name of the attribute in devShells to configure";
type = lib.types.str;
default = "default";
example = "rust";
};
extraAttrs = lib.mkOption {
description = "Extra attributes to merge into the devshell. See https://crane.dev/API.html#cranelibdevshell";
type = lib.types.attrs;
default = {};
example = {
shellHook = ''
export DEBUG=1
'';
};
};
};
package = {
enable = lib.mkEnableOption "the compiled cargo project" // {default = true;};
name = lib.mkOption {
description = "The name of the attribute in packages to configure";
type = lib.types.str;
default = "default";
example = "lib";
};
extraAttr = lib.mkOption {
description = "Extra attributes to merge into the package. See https://crane.dev/API.html#cranelibbuildpackage";
type = lib.types.attrs;
default = {};
example = {
doCheck = false;
};
};
};
craneLib = lib.mkOption {
description = "The crane lib instance this module is using. Useful for overriding options";
default = craneLib;
defaultText = lib.literalExpression "crane.mkLib pkgs";
readOnly = true;
};
};
config = lib.mkIf cfg.enable rec {
# Dev Shell that lets you enter an environment with all the necessary utilites
# Available through 'nix develop'
# Also can be activated automatically if direnv is installed on the system with 'direnv allow'
devShells.${cfg.devShell.name} = lib.mkIf cfg.devShell.enable (craneLib.devShell {
inherit checks;
# extra tooling dependencies
packages = cfg.devDeps;
inputsFrom = [packages.default];
}
// cfg.devShell.extraAttr);
# Formatter for nix files, available through 'nix fmt'
treefmt = {
programs.alejandra.enable = lib.mkDefault true;
programs.rustfmt = {
enable = true;
edition = manifest.edition;
};
};
# Your custom packages
# Accessible through 'nix build', 'nix shell', 'nix run', etc
packages.${cfg.package.name} = lib.mkIf cfg.package.enable (craneLib.buildPackage {
inherit src buildInputs nativeBuildInputs cargoArtifacts;
}
// cfg.package.extraAttr);
checks = {
clippy = craneLib.cargoClippy {
inherit src buildInputs nativeBuildInputs cargoArtifacts;
cargoClippyExtraArgs = "-- --deny warnings";
};
};
};
});
};
};
}