From 33f966de407cd59b103f0aeb10eb79fe781128a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Mon, 23 Feb 2026 18:39:20 -0800 Subject: [PATCH 1/5] chore: check `cargoNextest` --- checks/default.nix | 1 + checks/nextest/Cargo.lock | 7 ++++++ checks/nextest/Cargo.toml | 12 +++++++++++ checks/nextest/crate/Cargo.toml | 4 ++++ checks/nextest/crate/src/lib.rs | 4 ++++ checks/nextest/default.nix | 38 +++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+) create mode 100644 checks/nextest/Cargo.lock create mode 100644 checks/nextest/Cargo.toml create mode 100644 checks/nextest/crate/Cargo.toml create mode 100644 checks/nextest/crate/src/lib.rs create mode 100644 checks/nextest/default.nix diff --git a/checks/default.nix b/checks/default.nix index bc48bbc..c2b8faf 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -19,6 +19,7 @@ onlyDrvs ( workspaceSanity = callPackage ./workspace-sanity { }; workspaceCross = callPackage ./workspace-cross-compile { inherit full; }; customStdenv = callPackage ./custom-stdenv { }; + nextest = callPackage ./nextest { }; } ) ) diff --git a/checks/nextest/Cargo.lock b/checks/nextest/Cargo.lock new file mode 100644 index 0000000..2418b72 --- /dev/null +++ b/checks/nextest/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "nextest-check" +version = "0.1.0" diff --git a/checks/nextest/Cargo.toml b/checks/nextest/Cargo.toml new file mode 100644 index 0000000..9699c6b --- /dev/null +++ b/checks/nextest/Cargo.toml @@ -0,0 +1,12 @@ +[workspace] +members = ["crate"] +resolver = "2" + +[workspace.package] +edition = "2021" + +[profile.ci] +debug = "line-tables-only" +inherits = "dev" +incremental = false +lto = "off" diff --git a/checks/nextest/crate/Cargo.toml b/checks/nextest/crate/Cargo.toml new file mode 100644 index 0000000..0919c58 --- /dev/null +++ b/checks/nextest/crate/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "nextest-check" +version = "0.1.0" +edition = { workspace = true } diff --git a/checks/nextest/crate/src/lib.rs b/checks/nextest/crate/src/lib.rs new file mode 100644 index 0000000..2837a57 --- /dev/null +++ b/checks/nextest/crate/src/lib.rs @@ -0,0 +1,4 @@ +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} diff --git a/checks/nextest/default.nix b/checks/nextest/default.nix new file mode 100644 index 0000000..2a0772a --- /dev/null +++ b/checks/nextest/default.nix @@ -0,0 +1,38 @@ +{ pkgs, flakeboxLib }: +let + rootDir = builtins.path { + name = "nextest"; + path = ./.; + }; + + buildPaths = [ + "Cargo.toml" + "Cargo.lock" + "crate" + ]; + + multiOutput = (flakeboxLib.craneMultiBuild { }) ( + craneLib': + let + src = flakeboxLib.filterSubPaths { + root = rootDir; + paths = buildPaths; + }; + + craneLib = craneLib'.overrideArgs { + pname = "nextest-check"; + version = "0.0.1"; + inherit src; + }; + in + { + workspaceDeps = craneLib.buildWorkspaceDepsOnly { }; + nextest = craneLib.cargoNextest { + cargoArtifacts = craneLib.buildWorkspaceDepsOnly { }; + }; + } + ); +in +pkgs.linkFarmFromDrvs "nextest" [ + multiOutput.ci.nextest +] From 085c2746399ebe54386e2ab839786068772ddd87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Mon, 23 Feb 2026 18:44:59 -0800 Subject: [PATCH 2/5] chore: new checks --- checks/default.nix | 1 + checks/mergeArgs-tests.nix | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 checks/mergeArgs-tests.nix diff --git a/checks/default.nix b/checks/default.nix index c2b8faf..8becd51 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -20,6 +20,7 @@ onlyDrvs ( workspaceCross = callPackage ./workspace-cross-compile { inherit full; }; customStdenv = callPackage ./custom-stdenv { }; nextest = callPackage ./nextest { }; + mergeArgsTests = callPackage ./mergeArgs-tests.nix { }; } ) ) diff --git a/checks/mergeArgs-tests.nix b/checks/mergeArgs-tests.nix new file mode 100644 index 0000000..69ba139 --- /dev/null +++ b/checks/mergeArgs-tests.nix @@ -0,0 +1,36 @@ +{ pkgs, flakeboxLib }: +let + inherit (pkgs) lib; + mergeArgs = flakeboxLib.mergeArgs; + + assertEq = + name: actual: expected: + lib.assertMsg (actual == expected) "${name}: expected ${builtins.toJSON expected}, got ${builtins.toJSON actual}"; + + r1 = mergeArgs { buildInputs = [ 1 ]; } { buildInputs = [ 2 ]; }; + r2 = mergeArgs { nativeBuildInputs = [ 1 ]; } { nativeBuildInputs = [ 2 ]; }; + r3 = mergeArgs { packages = [ 1 ]; } { packages = [ 2 ]; }; + r4 = mergeArgs { env = { A = "1"; }; } { env = { B = "2"; }; }; + r5 = mergeArgs { env = { A = "1"; }; } { env = { A = "2"; }; }; + r6 = mergeArgs { } { buildInputs = [ 1 ]; }; + r7 = mergeArgs { buildInputs = [ 1 ]; } { }; + r8 = mergeArgs { } { env = { A = "1"; }; }; + r9 = mergeArgs { env = { A = "1"; }; } { }; + r10 = mergeArgs { foo = "left"; } { bar = "right"; }; + r11 = mergeArgs { foo = "left"; } { foo = "right"; }; +in + +assert assertEq "buildInputs merges both sides" r1.buildInputs [ 1 2 ]; +assert assertEq "nativeBuildInputs merges both sides" r2.nativeBuildInputs [ 1 2 ]; +assert assertEq "packages merges both sides" r3.packages [ 1 2 ]; +assert assertEq "env merges both sides" r4.env { A = "1"; B = "2"; }; +assert assertEq "env right overrides left" r5.env { A = "2"; }; +assert assertEq "buildInputs left missing" r6.buildInputs [ 1 ]; +assert assertEq "buildInputs right missing" r7.buildInputs [ 1 ]; +assert assertEq "env left missing" r8.env { A = "1"; }; +assert assertEq "env right missing" r9.env { A = "1"; }; +assert assertEq "plain attrs from both sides" r10.foo "left"; +assert assertEq "plain attrs from both sides (bar)" r10.bar "right"; +assert assertEq "plain attrs right overrides left" r11.foo "right"; + +pkgs.runCommand "mergeArgs-tests" { } "touch $out" From a8c3b7a49936ad65e174fbeece9ef026b79f5fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Mon, 23 Feb 2026 18:47:20 -0800 Subject: [PATCH 3/5] chore: introduce selfci --- .config/selfci/.gitignore | 1 + .config/selfci/ci.sh | 31 +++++++++++++++++++ .config/selfci/ci.yaml | 7 +++++ checks/mergeArgs-tests.nix | 62 ++++++++++++++++++++++++++++++++------ 4 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 .config/selfci/.gitignore create mode 100755 .config/selfci/ci.sh create mode 100644 .config/selfci/ci.yaml diff --git a/.config/selfci/.gitignore b/.config/selfci/.gitignore new file mode 100644 index 0000000..bd5d334 --- /dev/null +++ b/.config/selfci/.gitignore @@ -0,0 +1 @@ +local.yaml diff --git a/.config/selfci/ci.sh b/.config/selfci/ci.sh new file mode 100755 index 0000000..5afcf23 --- /dev/null +++ b/.config/selfci/ci.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -eou pipefail + +function job_lint() { + selfci step start "treefmt" + if ! treefmt --ci ; then + selfci step fail + fi +} + +function job_checks() { + selfci step start "flake check" + nix flake check -L +} + +case "$SELFCI_JOB_NAME" in + main) + selfci job start "lint" + selfci job start "checks" + ;; + checks) + job_checks + ;; + lint) + export -f job_lint + nix develop -c bash -c "job_lint" + ;; + *) + echo "Unknown job: $SELFCI_JOB_NAME" + exit 1 +esac diff --git a/.config/selfci/ci.yaml b/.config/selfci/ci.yaml new file mode 100644 index 0000000..8867188 --- /dev/null +++ b/.config/selfci/ci.yaml @@ -0,0 +1,7 @@ +job: + clone-mode: partial + command: ./.config/selfci/ci.sh + +mq: + base-branch: master + merge-style: rebase diff --git a/checks/mergeArgs-tests.nix b/checks/mergeArgs-tests.nix index 69ba139..8b2471d 100644 --- a/checks/mergeArgs-tests.nix +++ b/checks/mergeArgs-tests.nix @@ -5,25 +5,69 @@ let assertEq = name: actual: expected: - lib.assertMsg (actual == expected) "${name}: expected ${builtins.toJSON expected}, got ${builtins.toJSON actual}"; + lib.assertMsg ( + actual == expected + ) "${name}: expected ${builtins.toJSON expected}, got ${builtins.toJSON actual}"; r1 = mergeArgs { buildInputs = [ 1 ]; } { buildInputs = [ 2 ]; }; r2 = mergeArgs { nativeBuildInputs = [ 1 ]; } { nativeBuildInputs = [ 2 ]; }; r3 = mergeArgs { packages = [ 1 ]; } { packages = [ 2 ]; }; - r4 = mergeArgs { env = { A = "1"; }; } { env = { B = "2"; }; }; - r5 = mergeArgs { env = { A = "1"; }; } { env = { A = "2"; }; }; + r4 = + mergeArgs + { + env = { + A = "1"; + }; + } + { + env = { + B = "2"; + }; + }; + r5 = + mergeArgs + { + env = { + A = "1"; + }; + } + { + env = { + A = "2"; + }; + }; r6 = mergeArgs { } { buildInputs = [ 1 ]; }; r7 = mergeArgs { buildInputs = [ 1 ]; } { }; - r8 = mergeArgs { } { env = { A = "1"; }; }; - r9 = mergeArgs { env = { A = "1"; }; } { }; + r8 = mergeArgs { } { + env = { + A = "1"; + }; + }; + r9 = mergeArgs { + env = { + A = "1"; + }; + } { }; r10 = mergeArgs { foo = "left"; } { bar = "right"; }; r11 = mergeArgs { foo = "left"; } { foo = "right"; }; in -assert assertEq "buildInputs merges both sides" r1.buildInputs [ 1 2 ]; -assert assertEq "nativeBuildInputs merges both sides" r2.nativeBuildInputs [ 1 2 ]; -assert assertEq "packages merges both sides" r3.packages [ 1 2 ]; -assert assertEq "env merges both sides" r4.env { A = "1"; B = "2"; }; +assert assertEq "buildInputs merges both sides" r1.buildInputs [ + 1 + 2 +]; +assert assertEq "nativeBuildInputs merges both sides" r2.nativeBuildInputs [ + 1 + 2 +]; +assert assertEq "packages merges both sides" r3.packages [ + 1 + 2 +]; +assert assertEq "env merges both sides" r4.env { + A = "1"; + B = "2"; +}; assert assertEq "env right overrides left" r5.env { A = "2"; }; assert assertEq "buildInputs left missing" r6.buildInputs [ 1 ]; assert assertEq "buildInputs right missing" r7.buildInputs [ 1 ]; From ac95b2b87108e45ae34044e7ec3dc8a6337948eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Mon, 23 Feb 2026 18:56:52 -0800 Subject: [PATCH 4/5] chore: update inputs --- flake.lock | 66 +++++++++--------------------------------- flake.nix | 9 ++---- lib/modules/github.nix | 2 +- 3 files changed, 17 insertions(+), 60 deletions(-) diff --git a/flake.lock b/flake.lock index efdc4b6..d8e51a6 100644 --- a/flake.lock +++ b/flake.lock @@ -25,31 +25,16 @@ }, "crane": { "locked": { - "lastModified": 1758758545, - "narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=", + "lastModified": 1771121070, + "narHash": "sha256-aIlv7FRXF9q70DNJPI237dEDAznSKaXmL5lfK/Id/bI=", "owner": "ipetkov", "repo": "crane", - "rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "ref": "v0.21.1", - "repo": "crane", - "type": "github" - } - }, - "crane_2": { - "locked": { - "lastModified": 1755993354, - "narHash": "sha256-FCRRAzSaL/+umLIm3RU3O/+fJ2ssaPHseI2SSFL8yZU=", - "owner": "ipetkov", - "repo": "crane", - "rev": "25bd41b24426c7734278c2ff02e53258851db914", + "rev": "a2812c19f1ed2e5ed5ce2ef7109798b575c180e1", "type": "github" }, "original": { "owner": "ipetkov", + "ref": "v0.23.1", "repo": "crane", "type": "github" } @@ -83,11 +68,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1767941162, - "narHash": "sha256-7qJDycrXto4xrQWHbj5BkrRWt/hcfZtjlCstEJTyfJ8=", + "lastModified": 1771743970, + "narHash": "sha256-eri4eY0fUouYxBgWxJAJzG+xTGXVI7VeNJGcJrqpEt0=", "owner": "nix-community", "repo": "fenix", - "rev": "80b1a19a713e2558c411f3259fecb1edd4b5b327", + "rev": "2af8ae8bbe91833a54bd3b9cc24c326b66972a8e", "type": "github" }, "original": { @@ -136,11 +121,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1767799921, - "narHash": "sha256-r4GVX+FToWVE2My8VVZH4V0pTIpnu2ZE8/Z4uxGEMBE=", + "lastModified": 1771714954, + "narHash": "sha256-nhZJPnBavtu40/L2aqpljrfUNb2rxmWTmSjK2c9UKds=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d351d0653aeb7877273920cd3e823994e7579b0b", + "rev": "afbbf774e2087c3d734266c22f96fca2e78d3620", "type": "github" }, "original": { @@ -157,18 +142,17 @@ "fenix": "fenix", "flake-utils": "flake-utils_2", "nixpkgs": "nixpkgs", - "systems": "systems_2", - "wild": "wild" + "systems": "systems_2" } }, "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1767905519, - "narHash": "sha256-mRU9VEhGQE9dnOU3pu1Rx3dZO4NpZO+cnC0rPMFcCqE=", + "lastModified": 1771639390, + "narHash": "sha256-igbphgls7JmrblWCIbgBGcL/ZWj0Iv+InySvuhLC5Ew=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "ff9a2e88b14907562294838f83963e5966f717de", + "rev": "af68fc6e782f218c262a8e7e5718ce7276f697a2", "type": "github" }, "original": { @@ -207,28 +191,6 @@ "repo": "default", "type": "github" } - }, - "wild": { - "inputs": { - "crane": "crane_2", - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1762215977, - "narHash": "sha256-x0IZuWjj0LRMj4pu2FVaD8SENm/UVtE1e4rl0EOZZZM=", - "owner": "davidlattimore", - "repo": "wild", - "rev": "7daaf0c89f7b4b9c9ded36e7b3c72aa6512537a1", - "type": "github" - }, - "original": { - "owner": "davidlattimore", - "ref": "0.7.0", - "repo": "wild", - "type": "github" - } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ebdcbb7..e338e54 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,7 @@ flake-utils.inputs.systems.follows = "systems"; crane = { - url = "github:ipetkov/crane/v0.21.1"; + url = "github:ipetkov/crane/v0.23.1"; }; fenix = { @@ -17,11 +17,6 @@ inputs.nixpkgs.follows = "nixpkgs"; }; - wild = { - url = "github:davidlattimore/wild/0.7.0"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - android-nixpkgs = { url = "github:tadfisher/android-nixpkgs?rev=d3cbdd2a82b3d054b4e283d28ba27548186a88e7"; # stable channel https://github.com/tadfisher/android-nixpkgs/tree/stable inputs.nixpkgs.follows = "nixpkgs"; @@ -64,7 +59,7 @@ // flake-utils.lib.eachDefaultSystem ( system: let - pkgs = nixpkgs.legacyPackages.${system}.extend (import inputs.wild); + pkgs = nixpkgs.legacyPackages.${system}; flakeboxLib = mkLib pkgs { config = { diff --git a/lib/modules/github.nix b/lib/modules/github.nix index 5856c4e..779be3a 100644 --- a/lib/modules/github.nix +++ b/lib/modules/github.nix @@ -196,7 +196,7 @@ in uses = "actions/cache@v3"; "with" = { path = "~/.cargo"; - key = ''''${{ runner.os }}-''${{ hashFiles('Cargo.lock') }}''; + key = "\${{ runner.os }}-\${{ hashFiles('Cargo.lock') }}"; }; } From d4f37f5d9508b85cd020e3f7d3aa966725457a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Tue, 24 Feb 2026 10:55:49 -0800 Subject: [PATCH 5/5] fix: old api used in examples --- bin/bootstrap.flake.nix | 3 ++- docs/building-new-project.md | 32 +++++++++++++++++++------------- docs/getting-started.md | 4 +++- docs/native-toolchains.md | 2 +- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/bin/bootstrap.flake.nix b/bin/bootstrap.flake.nix index 5f5a032..e16907d 100644 --- a/bin/bootstrap.flake.nix +++ b/bin/bootstrap.flake.nix @@ -18,7 +18,8 @@ flake-utils.lib.eachDefaultSystem ( system: let - flakeboxLib = flakebox.lib.${system} { }; + pkgs = nixpkgs.legacyPackages.${system}; + flakeboxLib = flakebox.lib.mkLib pkgs { }; in { devShells = { diff --git a/docs/building-new-project.md b/docs/building-new-project.md index 9d6c5fa..0eccba6 100644 --- a/docs/building-new-project.md +++ b/docs/building-new-project.md @@ -145,7 +145,8 @@ index 615d404..860927a 100644 + outputs = { self, nixpkgs, flakebox, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let -+ flakeboxLib = flakebox.lib.${system} { }; ++ pkgs = nixpkgs.legacyPackages.${system}; ++ flakeboxLib = flakebox.lib.mkLib pkgs { }; + in + { + devShells = flakeboxLib.mkShells { @@ -179,7 +180,8 @@ Since that's a bit handful, let me paste the whole content: outputs = { self, nixpkgs, flakebox, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let - flakeboxLib = flakebox.lib.${system} { }; + pkgs = nixpkgs.legacyPackages.${system}; + flakeboxLib = flakebox.lib.mkLib pkgs { }; in { devShells = flakeboxLib.mkShells { @@ -316,7 +318,8 @@ index cb41316..08c8f65 100644 @@ -16,8 +16,38 @@ flake-utils.lib.eachDefaultSystem (system: let - flakeboxLib = flakebox.lib.${system} { }; ++ pkgs = nixpkgs.legacyPackages.${system}; + flakeboxLib = flakebox.lib.mkLib pkgs { }; + + rustSrc = flakeboxLib.filterSubPaths { + root = builtins.path { @@ -407,19 +410,24 @@ Skipping semgrep check: .config/semgrep.yaml empty Let's discuss each part of the code: ``` - flakeboxLib = flakebox.lib.${system} { }; + pkgs = nixpkgs.legacyPackages.${system}; + flakeboxLib = flakebox.lib.mkLib pkgs { }; ``` `let ... in ` in Nix is used to bind values to names, that can later be used in `` following in. -Our first name binding is `flakeboxLib` which exposes all +Our first name binding is `pkgs` which is the standard way to +get the nixpkgs package set for the current `system`. + +Next is `flakeboxLib` which exposes all Flakebox APIs. `flakebox` is the name of the input -defined in the flake, `flakebox.lib.${system}` is -the library output it exposes for the current `system`. -`flakebox.lib.${system} { }` is a function call, where -`{ }` are the arguments (empty set, defaults). +defined in the flake, `flakebox.lib.mkLib` is +the function used to initialize the library. +`flakebox.lib.mkLib pkgs { }` is a function call, where +`pkgs` is the nixpkgs package set and `{ }` are the +configuration arguments (empty set, defaults). This is where you can enable/disable/configure various features of flakebox. A list of config options can be found [here](./nixos-options.md) @@ -714,11 +722,9 @@ index a65ba7a..f4c64d7 100644 flake-utils.lib.eachDefaultSystem (system: let + -+ pkgs = import nixpkgs { -+ inherit system; -+ }; ++ pkgs = nixpkgs.legacyPackages.${system}; + - flakeboxLib = flakebox.lib.${system} { }; + flakeboxLib = flakebox.lib.mkLib pkgs { }; rustSrc = flakeboxLib.filterSubPaths { @@ -36,6 +41,10 @@ diff --git a/docs/getting-started.md b/docs/getting-started.md index 39211a8..5783b89 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -48,8 +48,10 @@ Following modifications to `flake.nix` are needed: # Set project name projectName = "my-project"; + pkgs = nixpkgs.legacyPackages.${system}; + # Set up the flakebox lib for your system - flakeboxLib = flakebox.lib.${system} { + flakeboxLib = flakebox.lib.mkLib pkgs { # customizations go here config = { typos.pre-commit.enable = false; diff --git a/docs/native-toolchains.md b/docs/native-toolchains.md index c77ad97..cb2ab2d 100644 --- a/docs/native-toolchains.md +++ b/docs/native-toolchains.md @@ -11,7 +11,7 @@ These toolchains are meant to be native target toolchains. To change the default toolchain channel to nightly use: ```nix -flakeboxLib = flakebox.lib.${system} { +flakeboxLib = flakebox.lib.mkLib pkgs { config = { toolchain.channel = "complete"; # or "latest", see https://github.com/nix-community/fenix for details };