leptos-template/flake.nix

276 lines
8 KiB
Nix
Raw Normal View History

2024-09-01 14:19:38 +02:00
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
crane = {
url = "github:ipetkov/crane";
};
cargo-leptos-src = {
url = "github:leptos-rs/cargo-leptos";
flake = false;
};
nix-filter.url = "github:numtide/nix-filter";
};
outputs =
{
self,
nixpkgs,
rust-overlay,
crane,
cargo-leptos-src,
nix-filter,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
# set up `pkgs` with rust-overlay
overlays = [ (import rust-overlay) ];
pkgs = (import nixpkgs) {
inherit system overlays;
};
# filter the source to reduce cache misses
# add a path here if you need other files, e.g. bc of `include_str!()`
src = nix-filter {
root = ./.;
include = [
(nix-filter.lib.matchExt "toml")
./Cargo.lock
./crates
];
};
# set up the rust toolchain, including the wasm target
# these are separated because rust-analyzer is useless in CI, so the
# dev toolchain is only used in the dev shell
toolchain = pkgs.rust-bin.selectLatestNightlyWith (
toolchain:
toolchain.minimal.override {
targets = [ "wasm32-unknown-unknown" ];
}
);
dev-toolchain = pkgs.rust-bin.selectLatestNightlyWith (
toolchain:
toolchain.default.override {
extensions = [
"rust-src"
"rust-analyzer"
"rustfmt-preview"
];
targets = [ "wasm32-unknown-unknown" ];
}
);
# read leptos options from `Cargo.toml`
leptos-options = builtins.elemAt (builtins.fromTOML (builtins.readFile ./Cargo.toml))
.workspace.metadata.leptos 0;
# configure crane to use our toolchain
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
# build cargo-leptos from source
cargo-leptos = (import ./nix/cargo-leptos.nix) {
inherit pkgs craneLib;
cargo-leptos = cargo-leptos-src;
};
# crane build configuration used by multiple builds
common-args = {
inherit src;
# use the name defined in the `Cargo.toml` leptos options
pname = leptos-options.name;
version = "0.1.0";
doCheck = false;
nativeBuildInputs =
[
pkgs.binaryen # provides wasm-opt
]
++ pkgs.lib.optionals (system == "x86_64-linux") [
pkgs.nasm # wasm compiler only for x86_64-linux
]
++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv # character encoding lib needed by darwin
];
buildInputs = [
pkgs.pkg-config # used by many crates for finding system packages
pkgs.openssl # needed for many http libraries
];
};
# build the deps for the frontend bundle, and export the target folder
site-frontend-deps = craneLib.mkCargoDerivation (
common-args
// {
pname = "site-frontend-deps";
src = craneLib.mkDummySrc common-args;
cargoArtifacts = null;
doInstallCargoArtifacts = true;
buildPhaseCargoCommand = ''
cargo build \
--package=${leptos-options.lib-package or leptos-options.output-name} \
--lib \
--target-dir=/build/source/target/front \
--target=wasm32-unknown-unknown \
--no-default-features \
--profile=${leptos-options.lib-profile-release}
'';
}
);
# build the deps for the server binary, and export the target folder
site-server-deps = craneLib.mkCargoDerivation (
common-args
// {
pname = "site-server-deps";
src = craneLib.mkDummySrc common-args;
cargoArtifacts = site-frontend-deps;
doInstallCargoArtifacts = true;
buildPhaseCargoCommand = ''
cargo build \
--package=${leptos-options.bin-package or leptos-options.name} \
--no-default-features \
--release
'';
}
);
# build the binary and bundle using cargo leptos
site-server = craneLib.buildPackage (
common-args
// {
# add inputs needed for leptos build
nativeBuildInputs = common-args.nativeBuildInputs ++ [
cargo-leptos
# used by cargo-leptos for styling
pkgs.dart-sass
pkgs.tailwindcss
];
# enable hash_files again
buildPhaseCargoCommand = ''
# export LEPTOS_HASH_FILES=true
cargo leptos build --release -vvv
'';
installPhaseCommand = ''
mkdir -p $out/bin
cp target/release/site-server $out/bin/
# cp target/release/hash.txt $out/bin/
cp -r target/site $out/bin/
'';
doCheck = false;
cargoArtifacts = site-server-deps;
}
);
in
{
checks = {
# lint packages
app-hydrate-clippy = craneLib.cargoClippy (
common-args
// {
cargoArtifacts = site-server-deps;
cargoClippyExtraArgs = "-p site-app --features hydrate -- --deny warnings";
}
);
app-ssr-clippy = craneLib.cargoClippy (
common-args
// {
cargoArtifacts = site-server-deps;
cargoClippyExtraArgs = "-p site-app --features ssr -- --deny warnings";
}
);
site-server-clippy = craneLib.cargoClippy (
common-args
// {
cargoArtifacts = site-server-deps;
cargoClippyExtraArgs = "-p site-server -- --deny warnings";
}
);
site-frontend-clippy = craneLib.cargoClippy (
common-args
// {
cargoArtifacts = site-server-deps;
cargoClippyExtraArgs = "-p site-frontend -- --deny warnings";
}
);
# make sure the docs build
site-server-doc = craneLib.cargoDoc (
common-args
// {
cargoArtifacts = site-server-deps;
}
);
# check formatting
site-server-fmt = craneLib.cargoFmt {
pname = common-args.pname;
version = common-args.version;
inherit src;
};
# # audit licenses
# site-server-deny = craneLib.cargoDeny {
# pname = common_args.pname;
# version = common_args.version;
# inherit src;
# };
# run tests
site-server-nextest = craneLib.cargoNextest (
common-args
// {
cargoArtifacts = site-server-deps;
partitions = 1;
partitionType = "count";
}
);
};
packages = {
default = site-server;
server = site-server;
};
formatter = pkgs.nixfmt-rfc-style;
devShells.default = pkgs.mkShell {
nativeBuildInputs =
(with pkgs; [
self.formatter.${system}
dev-toolchain # rust toolchain
cargo-leptos # main leptos build tool
bacon # cargo check w/ hot reload
cargo-deny # license checking
# styling
dart-sass
])
++ common-args.buildInputs
++ common-args.nativeBuildInputs
++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
pkgs.darwin.Security
];
};
}
);
}