build(nix): schemars-nixgen is built and checked by the flake, and in the dev shell

nix/nixgen has the package and the clippy and nextest checks (in the default check sets), from a
"nixgen" platform of nix/workspace-src.nix that is the tool alone; it is a stub in every other
platform's source, so an edit of it rebuilds none of theirs.
This commit is contained in:
LGUG2Z committed 2026-11-05 15:03:27 -08:00
1 parent 622646c3f7
commit c6d29a9268
6 files changed
+122 -134

No files matched your search

+1
View File
@@ -35,6 +35,7 @@
./nix/linux/flake-module.nix
./nix/macos/flake-module.nix
./nix/recorder/flake-module.nix
./nix/nixgen/flake-module.nix
];
};
}
+4
View File
@@ -55,6 +55,8 @@ let
"linux-nix-options-validation"
"linux-schema-fresh"
];
nixgen-lint = [ "nixgen-clippy" ];
nixgen-test = [ "nixgen-nextest" ];
recorder-lint = [ "recorder-clippy" ];
recorder-test = [ "recorder-nextest" ];
macos-lint = [ "macos-clippy" ];
@@ -98,6 +100,8 @@ let
"macos-options"
"recorder-lint"
"recorder-test"
"nixgen-lint"
"nixgen-test"
];
in
{
+2
View File
@@ -88,6 +88,8 @@ in
pkgs.cargo-deny
pkgs.cargo-nextest
pkgs.cargo-outdated
# writes the Nix options of the modules from the schemas (`just nixgen-linux`, `just nixgen-macos`)
config.packages.schemars-nixgen
# `komorebi-recorder frames` and `selftest` extract frames with ffmpeg; it is never used for
# capture and is not bundled into the packaged binary
pkgs.ffmpeg-headless
+57 -128
View File
@@ -1,137 +1,66 @@
# The crane derivations of schemars-nixgen, the tool that writes the Nix options of the modules from the JSON
# Schemas, from the one Cargo workspace (nix/workspace-src.nix, platform "nixgen": the tool and nothing
# else). It is pure Rust, so one build serves every system.
{ inputs, self }:
let
lib' = import ../lib.nix { inherit inputs; };
inherit (inputs) crane;
version =
(builtins.fromTOML (builtins.readFile ../../crates/schemars-nixgen/Cargo.toml)).package.version;
in
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-parts.url = "github:hercules-ci/flake-parts";
crane.url = "github:ipetkov/crane";
rust-overlay.url = "github:oxalica/rust-overlay";
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
treefmt-nix.url = "github:numtide/treefmt-nix";
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
git-hooks-nix.url = "github:cachix/git-hooks.nix";
git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs";
};
mkNixgenPackages =
{ pkgs }:
let
toolchain = pkgs.rust-bin.fromRustupToolchainFile ../../rust-toolchain.toml;
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
outputs =
inputs@{
nixpkgs,
flake-parts,
crane,
rust-overlay,
...
}:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
inputs.treefmt-nix.flakeModule
inputs.git-hooks-nix.flakeModule
];
inherit
(import ../workspace-src.nix {
inherit pkgs craneLib;
repoRoot = ../..;
platform = "nixgen";
})
src
;
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
lockFile = lib'.repoFile "Cargo.lock";
tomlFile = lib'.repoFile "Cargo.toml";
perSystem =
{
config,
system,
...
}:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
commonArgs = {
pname = "schemars-nixgen";
inherit version src;
cargoExtraArgs = "--locked -p schemars-nixgen";
# the lock and the root manifest as files of their own: a path inside the filtered source
# would put all of it into the context of every derivation, and an edit of any file
# would then change the dependencies
cargoLock = lockFile;
cargoToml = tomlFile;
cargoVendorDir = craneLib.vendorCargoDeps { cargoLock = lockFile; };
strictDeps = true;
};
# the dummy source is of the manifests alone (nix/lib.nix): the dependencies are the same
# derivations for every source file and every stub, and nothing is built at evaluation
cargoArtifacts = craneLib.buildDepsOnly (
builtins.removeAttrs commonArgs [ "src" ]
// {
dummySrc = craneLib.mkDummySrc {
src = lib'.manifestSource pkgs.lib;
cargoLock = lockFile;
};
}
);
rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
nightlyRustfmt = pkgs.rust-bin.nightly.latest.rustfmt;
rustToolchainWithNightlyRustfmt = pkgs.symlinkJoin {
name = "rust-toolchain-with-nightly-rustfmt";
paths = [
nightlyRustfmt
rustToolchain
];
};
individualCrateArgs = commonArgs // {
inherit cargoArtifacts;
doCheck = false;
doDoc = false;
};
nightlyToolchain = pkgs.rust-bin.nightly.latest.default;
cargo-udeps = pkgs.writeShellScriptBin "cargo-udeps" ''
export PATH="${nightlyToolchain}/bin:$PATH"
exec ${pkgs.cargo-udeps}/bin/cargo-udeps "$@"
'';
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;
src = pkgs.lib.cleanSourceWith {
src = ./.;
filter = craneLib.filterCargoSources;
};
commonArgs = {
inherit src;
strictDeps = true;
};
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
schemars-nixgen = craneLib.buildPackage (
commonArgs
// {
inherit cargoArtifacts;
}
);
in
{
checks = {
clippy = craneLib.cargoClippy (
commonArgs
// {
inherit cargoArtifacts;
}
);
tests = craneLib.cargoTest (
commonArgs
// {
inherit cargoArtifacts;
}
);
};
packages = {
inherit schemars-nixgen;
default = schemars-nixgen;
};
devShells.default = pkgs.mkShell {
inputsFrom = [ schemars-nixgen ];
packages = [
rustToolchainWithNightlyRustfmt
cargo-udeps
pkgs.cargo-outdated
pkgs.bacon
];
};
pre-commit = {
check.enable = true;
settings.hooks.treefmt = {
enable = true;
package = config.treefmt.build.wrapper;
pass_filenames = false;
};
};
treefmt = {
projectRootFile = "flake.nix";
programs = {
rustfmt = {
enable = true;
package = nightlyRustfmt;
};
taplo.enable = true;
nixfmt.enable = true;
deadnix.enable = true;
};
};
};
schemars-nixgen = craneLib.buildPackage individualCrateArgs;
in
{
inherit craneLib src individualCrateArgs schemars-nixgen;
};
}
+42
View File
@@ -0,0 +1,42 @@
# schemars-nixgen: the package of the tool that writes the Nix options (`just nixgen-linux`,
# `just nixgen-macos`), and its checks. It is a development tool: nothing of a release has it.
{
inputs,
self,
lib,
...
}:
let
lib' = import ../lib.nix { inherit inputs; };
nixgen = import ./build.nix { inherit inputs self; };
in
{
perSystem =
{ pkgs, system, ... }:
let
build = nixgen.mkNixgenPackages { inherit pkgs; };
in
lib.optionalAttrs (builtins.elem system (lib'.macosSystems ++ lib'.linuxSystems)) {
allChecks = {
# the format, the TOML and the licenses of the tool are checked with those of the rest of
# the workspace (`windows-fmt`, `windows-toml-fmt`, `cargo deny` over the workspace)
nixgen-clippy = build.craneLib.cargoClippy (
build.individualCrateArgs
// {
cargoClippyExtraArgs = "--all-targets -- -D warnings";
}
);
nixgen-nextest = build.craneLib.cargoNextest (build.individualCrateArgs // { doCheck = true; });
};
packages = {
inherit (build) schemars-nixgen;
};
apps.schemars-nixgen = {
type = "app";
program = "${build.schemars-nixgen}/bin/schemars-nixgen";
};
};
}
+16 -6
View File
@@ -1,6 +1,6 @@
# The source of a build of one platform, cut from the one Cargo workspace of this repository.
#
# import ./workspace-src.nix { pkgs; craneLib; repoRoot; platform = "windows" | "linux" | "macos" | "recorder"; }
# import ./workspace-src.nix { pkgs; craneLib; repoRoot; platform = "windows" | "linux" | "macos" | "recorder" | "nixgen"; }
#
# Cargo has to load every member of the workspace (the root manifest lists the members of all three
# platforms), but a build of one platform needs the sources of that platform's crates only. The result:
@@ -17,6 +17,9 @@
# indexes the log statements of the daemons of all three platforms (komorebi-recorder/build.rs), so it
# has their sources, whole, and nothing else; the Windows build has the recorder as one of its members.
#
# The platform "nixgen" is the source of schemars-nixgen's own builds: the tool and nothing else. It is a
# stub in every other platform, so that an edit of it changes none of their derivations.
#
# An edit under one platform therefore changes nothing in the derivations of the others, except where
# the edit is in a crate they share or in the root manifest, lock or toolchain files.
{
@@ -44,6 +47,9 @@ let
];
macosOnly = [ "komorebi-macos" ];
# the development tool that writes the Nix options: built by its own checks (nix/nixgen)
toolOnly = [ "crates/schemars-nixgen" ];
# the recorder and the crates whose source its build script indexes (komorebi-recorder/build.rs)
recorderMembers = [
"komorebi-recorder"
@@ -58,8 +64,9 @@ let
membersOf = {
recorder = recorderMembers;
# everything but the other two platforms' daemons
windows = builtins.filter (m: !(builtins.elem m (linuxOnly ++ macosOnly))) allMembers;
nixgen = toolOnly;
# everything but the other two platforms' daemons and the tool
windows = builtins.filter (m: !(builtins.elem m (linuxOnly ++ macosOnly ++ toolOnly))) allMembers;
linux = linuxOnly ++ linuxShared;
macos =
macosOnly
@@ -72,7 +79,7 @@ let
"komorebi-scrolling"
"komorebi-themes"
]
++ builtins.filter (m: lib.hasPrefix "crates/" m) allMembers;
++ builtins.filter (m: lib.hasPrefix "crates/" m && !(builtins.elem m toolOnly)) allMembers;
};
members = builtins.filter (m: builtins.elem m membersOf.${platform}) allMembers;
@@ -95,7 +102,7 @@ let
macos = "(src/macos(\\.rs|/.*)|tests/macos_.*)";
};
# the recorder indexes every platform's files
otherMarkers = if platform == "recorder" then [ ] else builtins.attrValues (removeAttrs markers [ platform ]);
otherMarkers = if platform == "recorder" || platform == "nixgen" then [ ] else builtins.attrValues (removeAttrs markers [ platform ]);
ofOtherPlatform =
rel:
builtins.any (
@@ -111,7 +118,9 @@ let
members
++ lib.optional (platform == "windows") "wix"
++ (
if platform == "recorder" then
if platform == "nixgen" then
[ ".cargo" ]
else if platform == "recorder" then
[
".cargo"
# the installer, which a test of the recorder checks for its binaries
@@ -178,6 +187,7 @@ let
|| lib.hasPrefix "komorebic/fixtures/" rel;
# the guide and the icon the recorder embeds, and the installer
recorder = lib.hasPrefix "komorebi-recorder/" rel || lib.hasPrefix "wix/" rel;
nixgen = false;
}
.${platform};