build(nix): do crane EZA style

This is essentailly taken from the work of 9glenda
https://github.com/eza-community/eza/pull/462

Signed-off-by: Christina Sørensen <christina@cafkafk.com>
This commit is contained in:
Christina Sørensen 2023-10-06 16:16:56 +02:00
parent 4f4cd5b7cb
commit 03b5a617c6
Signed by: cafkafk
GPG key ID: 26C542FD97F965CE
8 changed files with 373 additions and 236 deletions

3
.envrc Normal file
View file

@ -0,0 +1,3 @@
if has nix; then
use flake .
fi

View file

@ -3,7 +3,7 @@ name = "seidr"
version = "0.2.0" version = "0.2.0"
authors = ["Christina Sørensen"] authors = ["Christina Sørensen"]
edition = "2021" edition = "2021"
rust-version = "1.69.0" rust-version = "1.70.0"
description = "A Rust GitOps/symlinkfarm orchestrator inspired by GNU Stow." description = "A Rust GitOps/symlinkfarm orchestrator inspired by GNU Stow."
documentation = "https://github.com/cafkafk/seidr" documentation = "https://github.com/cafkafk/seidr"
readme = "./README.org" readme = "./README.org"

View file

@ -1,6 +1,6 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{black_box, criterion_group, criterion_main, Criterion};
use seidr::git::Config;
use relative_path::RelativePath; use relative_path::RelativePath;
use seidr::git::Config;
pub fn criterion_benchmark(c: &mut Criterion) { pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("config loading time", |b| { c.bench_function("config loading time", |b| {

View file

@ -1,81 +1,5 @@
{ {
"nodes": { "nodes": {
"advisory-db": {
"flake": false,
"locked": {
"lastModified": 1695296241,
"narHash": "sha256-t3SBLTqXyMlloAC0qSTHRAlWweiww6rmp0gSotDy1yo=",
"owner": "rustsec",
"repo": "advisory-db",
"rev": "81594d9fd5b32c3eaa199812475498b47fc98742",
"type": "github"
},
"original": {
"owner": "rustsec",
"repo": "advisory-db",
"type": "github"
}
},
"crane": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1695511445,
"narHash": "sha256-mnE14re43v3/Jc50Jv0BKPMtEk7FEtDSligP6B5HwlI=",
"owner": "ipetkov",
"repo": "crane",
"rev": "3de322e06fc88ada5e3589dc8a375b73e749f512",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"fenix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"rust-analyzer-src": []
},
"locked": {
"lastModified": 1695622936,
"narHash": "sha256-3bnz0FxC/x3K2/E2b2OBG+Iexyh/Fcpq2hZU+lxtLdA=",
"owner": "nix-community",
"repo": "fenix",
"rev": "4fa09c7203bef57254bb1cb1d4bab76fdae34dd5",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "fenix",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1673956053,
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
@ -99,11 +23,11 @@
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1694529238, "lastModified": 1681202837,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384", "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -112,13 +36,44 @@
"type": "github" "type": "github"
} }
}, },
"naersk": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1694081375,
"narHash": "sha256-vzJXOUnmkMCm3xw8yfPP5m8kypQ3BhAIRe4RRCWpzy8=",
"owner": "nix-community",
"repo": "naersk",
"rev": "3f976d822b7b37fc6fb8e6f157c2dd05e7e94e89",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "naersk",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1695318763, "lastModified": 1696019113,
"narHash": "sha256-FHVPDRP2AfvsxAdc+AsgFJevMz5VBmnZglFUMlxBkcY=", "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=",
"path": "/nix/store/r88zkfh22shcgj0c4zh9jj2q5r1z9wjn-source",
"rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1696419054,
"narHash": "sha256-EdR+dIKCfqL3voZUDYwcvgRDOektQB9KbhBVcE0/3Mo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "e12483116b3b51a185a33a272bf351e357ba9a99", "rev": "7131f3c223a2d799568e4b278380cd9dac2b8579",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -128,32 +83,58 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_3": {
"locked": {
"lastModified": 1681358109,
"narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1695644571,
"narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "6500b4580c2a1f3d0f980d32d285739d8e156d92",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"advisory-db": "advisory-db", "flake-utils": "flake-utils",
"crane": "crane", "naersk": "naersk",
"fenix": "fenix", "nixpkgs": "nixpkgs_2",
"flake-utils": "flake-utils_2", "rust-overlay": "rust-overlay",
"nixpkgs": "nixpkgs" "treefmt-nix": "treefmt-nix"
} }
}, },
"rust-overlay": { "rust-overlay": {
"inputs": { "inputs": {
"flake-utils": [ "flake-utils": "flake-utils_2",
"crane", "nixpkgs": "nixpkgs_3"
"flake-utils"
],
"nixpkgs": [
"crane",
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1695003086, "lastModified": 1696558324,
"narHash": "sha256-d1/ZKuBRpxifmUf7FaedCqhy0lyVbqj44Oc2s+P5bdA=", "narHash": "sha256-TnnP4LGwDB8ZGE7h2n4nA9Faee8xPkMdNcyrzJ57cbw=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "b87a14abea512d956f0b89d0d8a1e9b41f3e20ff", "rev": "fdb37574a04df04aaa8cf7708f94a9309caebe2b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -191,6 +172,24 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"treefmt-nix": {
"inputs": {
"nixpkgs": "nixpkgs_4"
},
"locked": {
"lastModified": 1695822946,
"narHash": "sha256-IQU3fYo0H+oGlqX5YrgZU3VRhbt2Oqe6KmslQKUO4II=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "720bd006d855b08e60664e4683ccddb7a9ff614a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

227
flake.nix
View file

@ -1,154 +1,113 @@
{ {
description = "Build a cargo project"; description = "Hon hafði um sik hnjóskulinda, ok var þar á skjóðupungr mikill, ok varðveitti hon þar í töfr sín, þau er hon þurfti til fróðleiks at hafa.";
inputs = { inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane = {
url = "github:ipetkov/crane";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.rust-analyzer-src.follows = "";
};
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
naersk.url = "github:nix-community/naersk";
advisory-db = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
url = "github:rustsec/advisory-db"; treefmt-nix.url = "github:numtide/treefmt-nix";
flake = false; rust-overlay.url = "github:oxalica/rust-overlay";
};
}; };
outputs = { self, nixpkgs, crane, fenix, flake-utils, advisory-db, ... }: outputs = {
flake-utils.lib.eachDefaultSystem (system: self,
let flake-utils,
pkgs = import nixpkgs { naersk,
inherit system; nixpkgs,
treefmt-nix,
rust-overlay,
}:
flake-utils.lib.eachDefaultSystem (
system: let
overlays = [(import rust-overlay)];
pkgs = (import nixpkgs) {
inherit system overlays;
}; };
inherit (pkgs) lib; toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
craneLib = crane.lib.${system}; naersk' = pkgs.callPackage naersk {
cargo = toolchain;
# When filtering sources, we want to allow assets other than .rs files rustc = toolchain;
src = lib.cleanSourceWith { clippy = toolchain;
src = ./.; # The original, unfiltered source
filter = path: type:
(lib.hasSuffix "\.yaml" path) ||
# (lib.hasSuffix "\.scss" path) ||
# Example of a folder for images, icons, etc
#(lib.hasInfix "test" path) ||
# Default filter from crane (allow .rs files)
(craneLib.filterCargoSources path type)
;
}; };
# Common arguments can be set here to avoid repeating them later treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
commonArgs = { buildInputs = with pkgs; [zlib] ++ lib.optionals stdenv.isDarwin [libiconv darwin.apple_sdk.frameworks.Security];
inherit src; in rec {
# For `nix fmt`
buildInputs = [ formatter = treefmtEval.config.build.wrapper;
# test-directory
# Add additional build inputs here
] ++ lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
];
# Additional environment variables can be set directly
# MY_CUSTOM_VAR = "some value";
RUST_BACKTRACE = 1;
};
craneLibLLvmTools = craneLib.overrideToolchain
(fenix.packages.${system}.complete.withComponents [
"cargo"
"llvm-tools"
"rustc"
]);
# Build *just* the cargo dependencies, so we can reuse
# all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
# Build the actual crate itself, reusing the dependency
# artifacts from above.
my-crate = craneLib.buildPackage (commonArgs // {
inherit cargoArtifacts;
});
in
{
checks = {
# Build the crate as part of `nix flake check` for convenience
inherit my-crate;
# Run clippy (and deny all warnings) on the crate source,
# again, resuing 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.
my-crate-clippy = craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
});
my-crate-doc = craneLib.cargoDoc (commonArgs // {
inherit cargoArtifacts;
});
# Check formatting
my-crate-fmt = craneLib.cargoFmt {
inherit src;
};
# Audit dependencies
my-crate-audit = craneLib.cargoAudit {
inherit src advisory-db;
};
# Run tests with cargo-nextest
# Consider setting `doCheck = false` on `my-crate` if you do not want
# the tests to run twice
my-crate-nextest = craneLib.cargoNextest (commonArgs // {
inherit cargoArtifacts;
partitions = 1;
partitionType = "count";
});
} // lib.optionalAttrs (system == "x86_64-linux") {
# NB: cargo-tarpaulin only supports x86_64 systems
# Check code coverage (note: this will not upload coverage anywhere)
# my-crate-coverage = craneLib.cargoTarpaulin (commonArgs // {
# inherit cargoArtifacts;
# });
};
packages = { packages = {
default = my-crate; # For `nix build` `nix run`, & `nix profile install`:
my-crate-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // { default = naersk'.buildPackage rec {
inherit cargoArtifacts; pname = "seidr";
}); version = "git";
src = ./.;
doCheck = true; # run `cargo test` on build
inherit buildInputs;
nativeBuildInputs = with pkgs; [cmake pkg-config installShellFiles];
# buildNoDefaultFeatures = true;
# buildFeatures = "git";
# outputs = [ "out" "man" ];
meta = with pkgs.lib; {
description = "A Rust GitOps/symlinkfarm orchestrator inspired by GNU Stow";
longDescription = ''
A Rust GitOps/symlinkfarm orchestrator inspired by GNU Stow.
Useful for dealing with "dotfiles", and with git support as a
first class feature. Configuration is done through a single yaml
file, giving it a paradigm that should bring joy to those that
use declarative operating systems and package managers.
'';
homepage = "https://github.com/cafkafk/seidr";
license = licenses.gpl3;
mainProgram = "seidr";
maintainers = with maintainers; [cafkafk];
};
}; };
apps.default = flake-utils.lib.mkApp { # Run `nix build .#check` to check code
drv = my-crate; check = naersk'.buildPackage {
src = ./.;
mode = "check";
inherit buildInputs;
}; };
# Run `nix build .#test` to run tests
test = naersk'.buildPackage {
src = ./.;
mode = "test";
inherit buildInputs;
};
# Run `nix build .#clippy` to lint code
clippy = naersk'.buildPackage {
src = ./.;
mode = "clippy";
inherit buildInputs;
};
};
# For `nix develop`:
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
inputsFrom = builtins.attrValues self.checks.${system}; nativeBuildInputs = with pkgs; [rustup toolchain just convco];
# Additional dev-shell environment variables can be set directly
# MY_CUSTOM_DEVELOPMENT_VAR = "something else";
# Extra inputs can be added here
nativeBuildInputs = with pkgs; [
cargo
rustc
];
}; };
});
# For `nix flake check`
checks = {
formatting = treefmtEval.config.build.check self;
build = packages.check;
default = packages.default;
test = packages.test;
lint = packages.clippy;
};
}
);
} }

154
flake.nix.old Normal file
View file

@ -0,0 +1,154 @@
{
description = "Build a cargo project";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane = {
url = "github:ipetkov/crane";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
inputs.rust-analyzer-src.follows = "";
};
flake-utils.url = "github:numtide/flake-utils";
advisory-db = {
url = "github:rustsec/advisory-db";
flake = false;
};
};
outputs = { self, nixpkgs, crane, fenix, flake-utils, advisory-db, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
};
inherit (pkgs) lib;
craneLib = crane.lib.${system};
# When filtering sources, we want to allow assets other than .rs files
src = lib.cleanSourceWith {
src = ./.; # The original, unfiltered source
filter = path: type:
(lib.hasSuffix "\.yaml" path) ||
# (lib.hasSuffix "\.scss" path) ||
# Example of a folder for images, icons, etc
#(lib.hasInfix "test" path) ||
# Default filter from crane (allow .rs files)
(craneLib.filterCargoSources path type)
;
};
# Common arguments can be set here to avoid repeating them later
commonArgs = {
inherit src;
buildInputs = [
# test-directory
# Add additional build inputs here
] ++ lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
];
# Additional environment variables can be set directly
# MY_CUSTOM_VAR = "some value";
RUST_BACKTRACE = 1;
};
craneLibLLvmTools = craneLib.overrideToolchain
(fenix.packages.${system}.complete.withComponents [
"cargo"
"llvm-tools"
"rustc"
]);
# Build *just* the cargo dependencies, so we can reuse
# all of that work (e.g. via cachix) when running in CI
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
# Build the actual crate itself, reusing the dependency
# artifacts from above.
my-crate = craneLib.buildPackage (commonArgs // {
inherit cargoArtifacts;
});
in
{
checks = {
# Build the crate as part of `nix flake check` for convenience
inherit my-crate;
# Run clippy (and deny all warnings) on the crate source,
# again, resuing 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.
my-crate-clippy = craneLib.cargoClippy (commonArgs // {
inherit cargoArtifacts;
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
});
my-crate-doc = craneLib.cargoDoc (commonArgs // {
inherit cargoArtifacts;
});
# Check formatting
my-crate-fmt = craneLib.cargoFmt {
inherit src;
};
# Audit dependencies
my-crate-audit = craneLib.cargoAudit {
inherit src advisory-db;
};
# Run tests with cargo-nextest
# Consider setting `doCheck = false` on `my-crate` if you do not want
# the tests to run twice
my-crate-nextest = craneLib.cargoNextest (commonArgs // {
inherit cargoArtifacts;
partitions = 1;
partitionType = "count";
});
} // lib.optionalAttrs (system == "x86_64-linux") {
# NB: cargo-tarpaulin only supports x86_64 systems
# Check code coverage (note: this will not upload coverage anywhere)
# my-crate-coverage = craneLib.cargoTarpaulin (commonArgs // {
# inherit cargoArtifacts;
# });
};
packages = {
default = my-crate;
my-crate-llvm-coverage = craneLibLLvmTools.cargoLlvmCov (commonArgs // {
inherit cargoArtifacts;
});
};
apps.default = flake-utils.lib.mkApp {
drv = my-crate;
};
devShells.default = pkgs.mkShell {
inputsFrom = builtins.attrValues self.checks.${system};
# Additional dev-shell environment variables can be set directly
# MY_CUSTOM_DEVELOPMENT_VAR = "something else";
# Extra inputs can be added here
nativeBuildInputs = with pkgs; [
cargo
rustc
];
};
});
}

11
rust-toolchain.toml Normal file
View file

@ -0,0 +1,11 @@
[toolchain]
channel = "1.70"
components = [
"rustfmt",
"rustc",
"rust-src",
"rust-analyzer",
"cargo",
"clippy",
]
profile = "minimal"

11
treefmt.nix Normal file
View file

@ -0,0 +1,11 @@
{
projectRootFile = "Cargo.toml";
programs = {
alejandra.enable = true; # nix
rustfmt.enable = true; # rust
shellcheck.enable = true; # bash/shell
deadnix.enable = true; # find dead nix code
taplo.enable = true; # toml
yamlfmt.enable = true; # yaml
};
}