mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-15 21:32:26 +01:00
On NixOS, running komorebi should take one flake input and one module line. The flake exports `services.komorebi` as nixosModules.default (and .komorebi). It adds the flake's overlay, which gains komorebi-full, installs komorebi and komorebic, and runs the daemon in every Plasma session as a systemd user unit, wanted by plasma-workspace.target and ordered after plasma-core.target, which Plasma orders after KWin. systemd starts a daemon that fails again; the exit status of a SIGTERM (130) counts as success, so a stopped unit is not failed. The unit's PATH is the one a terminal in the session has, instead of the few store paths NixOS gives a unit. The options are enable, package, logLevel and a read-only execStart, the command line the unit runs. There is no configFile: the daemon reads no configuration file yet, and an option that linked one would do nothing. nixos-module-eval evaluates seven scenarios as real NixOS systems and checks their assertions, the unit and execStart, with builtins.tryEval for the two that must not evaluate. Nothing in it builds a Linux package, so it runs on a Mac as well. The VM nodes import the module, so every suite runs komorebi as the module installs it. The headless node's komorebi@NAME runs execStart, which has --log-level, so the nodes set logLevel to debug and the suites stop passing it; latency, which times the daemon, keeps the default level. The session node starts the module's unit at login; render-smoke turns it off, since a tiled terminal would cover the desktop it looks at. A new fast suite, vm-module, logs in to Plasma and checks that the unit runs the daemon with the module's log level and PATH, that a window opened in the session is tiled, that a killed daemon is started again, and that a stop is not a failure. docs/installation.md covers NixOS first, and building from source on other distributions. There is no binary cache: the Komorebi license does not allow third parties to redistribute binaries.
328 lines
11 KiB
Nix
328 lines
11 KiB
Nix
{
|
|
description = "komorebi for KDE Plasma";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-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";
|
|
};
|
|
|
|
outputs =
|
|
inputs@{
|
|
self,
|
|
nixpkgs,
|
|
flake-parts,
|
|
crane,
|
|
rust-overlay,
|
|
...
|
|
}:
|
|
let
|
|
mkPkgs =
|
|
system:
|
|
import nixpkgs {
|
|
inherit system;
|
|
overlays = [ (import rust-overlay) ];
|
|
};
|
|
|
|
mkKomorebiPackages =
|
|
{ pkgs }:
|
|
let
|
|
toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
|
|
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
|
|
# rustfmt.toml uses options only a nightly rustfmt knows
|
|
craneLibFmt = (crane.mkLib pkgs).overrideToolchain (
|
|
pkgs.rust-bin.nightly.latest.minimal.override { extensions = [ "rustfmt" ]; }
|
|
);
|
|
|
|
src = pkgs.lib.cleanSourceWith {
|
|
src = ./.;
|
|
filter =
|
|
path: type:
|
|
(craneLib.filterCargoSources path type)
|
|
# the script komorebi loads into KWin, which the daemon includes
|
|
|| (pkgs.lib.hasSuffix ".js" path)
|
|
# the messages the tests of the bridge and of the daemon share
|
|
|| (pkgs.lib.hasSuffix ".json" path);
|
|
};
|
|
|
|
commonArgs = {
|
|
inherit src;
|
|
pname = "komorebi-workspace";
|
|
version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).workspace.package.version;
|
|
strictDeps = true;
|
|
# The version crate wants a commit at compile time. It is a constant here, so that the
|
|
# dependencies and every check are the same derivations for every commit; only the final
|
|
# build below knows the real one.
|
|
COMMIT_HASH = "nix-check";
|
|
};
|
|
|
|
cargoArtifacts = craneLib.buildDepsOnly commonArgs;
|
|
|
|
individualCrateArgs = commonArgs // {
|
|
inherit cargoArtifacts;
|
|
doCheck = false;
|
|
doDoc = false;
|
|
};
|
|
|
|
fullBuild = craneLib.buildPackage (
|
|
individualCrateArgs
|
|
// {
|
|
COMMIT_HASH = self.rev or (pkgs.lib.removeSuffix "-dirty" self.dirtyRev);
|
|
}
|
|
);
|
|
|
|
extractBinary =
|
|
binaryName:
|
|
pkgs.runCommand "komorebi-${binaryName}" { meta = fullBuild.meta // { }; } ''
|
|
mkdir -p $out/bin
|
|
cp ${fullBuild}/bin/${binaryName} $out/bin/
|
|
'';
|
|
in
|
|
{
|
|
inherit
|
|
craneLib
|
|
craneLibFmt
|
|
src
|
|
commonArgs
|
|
individualCrateArgs
|
|
fullBuild
|
|
;
|
|
komorebi = extractBinary "komorebi";
|
|
komorebic = extractBinary "komorebic";
|
|
};
|
|
in
|
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
|
# Linux is what komorebi runs on. An Apple silicon Mac gets the dev shell, the formatter and the
|
|
# checks, which run the same tests against the fake desktop. nixpkgs dropped x86_64-darwin in
|
|
# 26.11.
|
|
systems = [
|
|
"aarch64-linux"
|
|
"x86_64-linux"
|
|
"aarch64-darwin"
|
|
];
|
|
|
|
imports = [
|
|
inputs.treefmt-nix.flakeModule
|
|
inputs.git-hooks-nix.flakeModule
|
|
];
|
|
|
|
perSystem =
|
|
{
|
|
config,
|
|
lib,
|
|
system,
|
|
...
|
|
}:
|
|
let
|
|
pkgs = mkPkgs system;
|
|
build = mkKomorebiPackages { inherit pkgs; };
|
|
isLinux = pkgs.stdenv.hostPlatform.isLinux;
|
|
# the guests install komorebi through the module, as a NixOS user does
|
|
komorebiModule = self.nixosModules.default;
|
|
# a Mac runs the guests under HVF, which is slower than KVM
|
|
vm = import ./nix/tests/vm {
|
|
hostPkgs = pkgs;
|
|
inherit komorebiModule;
|
|
scale = if isLinux then 1 else 1.5;
|
|
};
|
|
nightlyRustfmt = pkgs.rust-bin.nightly.latest.rustfmt;
|
|
nightlyToolchain = pkgs.rust-bin.nightly.latest.default;
|
|
rustToolchainWithNightlyRustfmt = pkgs.symlinkJoin {
|
|
name = "rust-toolchain-with-nightly-rustfmt";
|
|
paths = [
|
|
nightlyRustfmt
|
|
(pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml)
|
|
];
|
|
};
|
|
# cargo-udeps needs a nightly compiler
|
|
cargo-udeps = pkgs.writeShellScriptBin "cargo-udeps" ''
|
|
export PATH="${nightlyToolchain}/bin:$PATH"
|
|
exec ${pkgs.cargo-udeps}/bin/cargo-udeps "$@"
|
|
'';
|
|
in
|
|
{
|
|
treefmt = {
|
|
projectRootFile = "flake.nix";
|
|
programs = {
|
|
deadnix.enable = true;
|
|
just.enable = true;
|
|
nixfmt.enable = true;
|
|
taplo.enable = true;
|
|
rustfmt = {
|
|
enable = true;
|
|
package = nightlyRustfmt;
|
|
};
|
|
};
|
|
};
|
|
|
|
checks = {
|
|
komorebi-workspace-fmt = build.craneLibFmt.cargoFmt { inherit (build) src; };
|
|
|
|
komorebi-workspace-clippy = build.craneLib.cargoClippy (
|
|
build.individualCrateArgs
|
|
// {
|
|
cargoClippyExtraArgs = "--workspace --all-targets -- -D warnings";
|
|
}
|
|
);
|
|
|
|
komorebi-workspace-doc = build.craneLib.cargoDoc (
|
|
build.individualCrateArgs
|
|
// {
|
|
cargoDocExtraArgs = "--workspace --no-deps";
|
|
env.RUSTDOCFLAGS = "-D warnings";
|
|
}
|
|
);
|
|
|
|
komorebi-workspace-toml-fmt = build.craneLib.taploFmt {
|
|
src = lib.sources.sourceFilesBySuffices build.src [ ".toml" ];
|
|
};
|
|
|
|
komorebi-workspace-deny = build.craneLib.cargoDeny { inherit (build) src; };
|
|
|
|
komorebi-workspace-nextest = build.craneLib.cargoNextest (
|
|
build.individualCrateArgs // { doCheck = true; }
|
|
);
|
|
|
|
# The bridge is not Rust: tsc checks its types from its JSDoc comments, and node runs
|
|
# its tests against a fake KWin. No package.json and no build step.
|
|
komorebi-bridge-js =
|
|
pkgs.runCommand "komorebi-bridge-js"
|
|
{
|
|
nativeBuildInputs = [
|
|
pkgs.nodejs
|
|
pkgs.typescript
|
|
];
|
|
src = lib.fileset.toSource {
|
|
root = ./komorebi/src/kwin;
|
|
fileset = lib.fileset.fileFilter (file: !file.hasExt "rs") ./komorebi/src/kwin;
|
|
};
|
|
}
|
|
''
|
|
cd $src
|
|
tsc -p tsconfig.json
|
|
node --test bridge.test.js
|
|
touch $out
|
|
'';
|
|
|
|
vm-lib = vm.lib;
|
|
|
|
# The NixOS module in real NixOS systems, evaluated and never built, so a Mac checks it
|
|
# too. A VM suite, `vm-module`, runs it.
|
|
nixos-module-eval = import ./nix/tests/nixos-module.nix {
|
|
inherit pkgs;
|
|
inherit (nixpkgs.lib) nixosSystem;
|
|
module = self.nixosModules.default;
|
|
komorebiFor = guestSystem: self.packages.${guestSystem}.komorebi-full;
|
|
};
|
|
}
|
|
# The VM tests need QEMU with KVM, so only Linux checks them. A Mac runs the same tests
|
|
# through legacyPackages.<system>.vm, see docs/dev/vm-tests.md.
|
|
// lib.optionalAttrs isLinux (
|
|
lib.mapAttrs' (name: test: lib.nameValuePair "vm-${name}" test) vm.suites
|
|
);
|
|
|
|
legacyPackages = {
|
|
# every suite, as a test with a `driver`, on every system
|
|
vm = vm.suites;
|
|
# the suites of each tier, for the CI matrix
|
|
vmTiers = vm.tiers;
|
|
# the guests of every suite, to build on a Linux builder when the host is a Mac
|
|
vmGuests = vm.guests;
|
|
}
|
|
// lib.optionalAttrs isLinux {
|
|
# the same suites on a machine with no KVM, which is slow but works anywhere
|
|
vmTcg =
|
|
(import ./nix/tests/vm {
|
|
hostPkgs = pkgs;
|
|
inherit komorebiModule;
|
|
scale = 8;
|
|
}).suites;
|
|
};
|
|
|
|
packages = lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
|
inherit (build) komorebi komorebic;
|
|
komorebi-full = build.fullBuild;
|
|
default = build.fullBuild;
|
|
};
|
|
|
|
apps = lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux {
|
|
komorebi = {
|
|
type = "app";
|
|
program = "${build.komorebi}/bin/komorebi";
|
|
meta.description = "The komorebi daemon";
|
|
};
|
|
komorebic = {
|
|
type = "app";
|
|
program = "${build.komorebic}/bin/komorebic";
|
|
meta.description = "The command line interface of komorebi";
|
|
};
|
|
default = config.apps.komorebi;
|
|
};
|
|
|
|
devShells.default = pkgs.mkShell {
|
|
name = "komorebi";
|
|
|
|
RUST_BACKTRACE = "full";
|
|
|
|
inputsFrom = [ build.fullBuild ];
|
|
|
|
packages = [
|
|
rustToolchainWithNightlyRustfmt
|
|
cargo-udeps
|
|
|
|
pkgs.cargo-deny
|
|
pkgs.cargo-nextest
|
|
pkgs.jq
|
|
pkgs.just
|
|
pkgs.ripgrep
|
|
|
|
# the bridge's type check and tests (`just check-js`)
|
|
pkgs.nodejs
|
|
pkgs.typescript
|
|
|
|
# the VM test library
|
|
pkgs.ruff
|
|
pkgs.ty
|
|
(pkgs.python3.withPackages (ps: [ ps.pytest ]))
|
|
];
|
|
};
|
|
|
|
pre-commit = {
|
|
check.enable = true;
|
|
settings.hooks.treefmt = {
|
|
enable = true;
|
|
package = config.treefmt.build.wrapper;
|
|
pass_filenames = false;
|
|
};
|
|
};
|
|
};
|
|
|
|
flake = {
|
|
overlays.default =
|
|
final: _:
|
|
let
|
|
build = mkKomorebiPackages { pkgs = mkPkgs final.stdenv.hostPlatform.system; };
|
|
in
|
|
{
|
|
inherit (build) komorebi komorebic;
|
|
komorebi-full = build.fullBuild;
|
|
};
|
|
overlays.komorebi = self.overlays.default;
|
|
|
|
# `services.komorebi`, with the overlay that provides its package, so that a NixOS
|
|
# configuration needs this flake as an input and one module line (docs/installation.md)
|
|
nixosModules.default = {
|
|
imports = [ ./nix/nixos-module.nix ];
|
|
nixpkgs.overlays = [ self.overlays.default ];
|
|
};
|
|
nixosModules.komorebi = self.nixosModules.default;
|
|
};
|
|
};
|
|
}
|