komorebi.json is described as a JSON Schema, made from the Rust types that read it: komorebic prints the schema of komorebi.json, of an applications.json, of a notification and of a message, and the daemon answers the same four questions on its socket. schema.json and schema.asc.json are committed (just jsonschema). The module's config option is typed from the schema: schemars-nixgen makes nix/komorebi-options.nix from schema.json (just nixgen), so a layout komorebi does not have, or a value of the wrong kind, does not evaluate. The module writes config as a komorebi.json and gives it to the daemon with --config. configFile and the file the module writes are checked against the schema when the system is built. applicationSpecificConfiguration takes files from GitHub, and there are none by default, since no community file for Plasma is known. Two checks keep the generated files honest without the tools that make them. schema-fresh compares the schemas with what komorebic prints, and the hash on the first line of the options with the schema. nix-options-validation evaluates the options against the example configuration, written in Nix and in JSON. nixos-module-eval also evaluates the module with the sources turned off: with applicationSpecificConfiguration.enable = false the sources are left out of the config that is written, and with no config either there is nothing to write and the unit passes no --config. ARCHITECTURE has the guarantee row that names the two checks.
6.2 KiB
Contributing to the Project
The project is a collection of contributions from both the project leaders and community members. There are many ways to contribute, this can include content in the project repositories, as well as contributing in public and private conversation, assisting users, writing blog posts, and many other ways.
How contributions are made
Contributions to the project primarily happen in the project source repositories, but may also occur in other places, such as discussion forums and public and private discourse.
Contributing content to the Project
In order for the project leaders to manage sustained progress toward the project goals and maintain project velocity, focus and quality, the project may adjust the license terms over time.
Content contributed to the project must therefore be provided under sufficiently liberal terms to allow these operations to proceed unimpeded. As such contributions are accepted with the following understanding:
- Contributed content is licensed under the terms of the 0-BSD license
- Contributors accept the terms of the project license at the time of contribution
By making a contribution, you accept both the current project license terms, and that all contributions that you have made are provided under the terms of the 0-BSD license.
Working on the code
nix develop (or direnv, through the .envrc)
provides the Rust toolchain, a nightly rustfmt and the tools the checks use.
rustfmt.toml uses an unstable option, which is why the
formatter is a nightly one.
just check runs everything a change has to pass before it is pushed: the
formatting check, clippy with warnings denied, the tests, rustdoc with warnings
denied, and the checks of the bridge. just fmt formats the Rust sources, and nix fmt every file
type the repository has. nix flake check builds the same checks, plus
cargo deny, as derivations; on Linux it also boots every VM test, which needs
KVM.
The bridge
bridge.js, the script komorebi loads into
KWin, is JavaScript that KWin runs as it is: there is no package.json and no
build step. Its types are JSDoc comments, which tsc checks against
kwin-api.d.ts, the part of KWin's
scripting API the bridge uses; something the bridge starts to use is declared
there first. Its tests, bridge.test.js,
run under node --test against a fake KWin. just check-js runs both, with the
tsc and node of the dev shell.
The messages between the bridge and the daemon are in
komorebi/src/kwin/fixtures, which the tests of
both sides read. A change to a message changes the fixture, the bridge and the
daemon in the same commit.
The NixOS module
nix/nixos-module.nix is services.komorebi, which the
flake exports as nixosModules.default with its overlay. A change to it comes
with a scenario in nix/tests/nixos-module.nix,
the nixos-module-eval check: each scenario is a real NixOS system that is
evaluated and never built, and its checks read the assertions, the unit and
the options it evaluates to. It runs on a Mac too, with nix build .#checks.aarch64-darwin.nixos-module-eval. A change to what the unit does in a
session also changes the VM suite module, which logs in to Plasma on a machine
with the module and checks the daemon the unit runs. Every other VM suite runs
on machines built with the module too.
Three files are generated from the Rust types and committed: schema.json and
schema.asc.json (just jsonschema), and nix/komorebi-options.nix, which types the
module's config (just nixgen, which needs schemars-nixgen, cargo install schemars-nixgen). A change to what komorebi.json or an applications.json can
say regenerates them in the same commit, and the check schema-fresh fails when
it does not. The first line of the options file is the hash of the schema it was
made from, which is how the check tells without running schemars-nixgen.
VM tests
A change that needs a real KWin to be checked comes with a VM test, next to
the Rust test that covers the same behavior against the fake desktop.
docs/dev/vm-tests.md says how they are laid out, how
to run one (just vm NAME) and how to add one.
Continuous integration
ci.yaml runs on every pull request and on every
push to master, feature/* and hotfix/*, in this repository only. The
lint job builds every check that needs no virtual machine and runs the
repository's own lint rules, cargo-deny checks licenses and advisories, and
the VM tests run on KVM in two jobs: vm-fast on every pull request and
vm-slow on master, every week, and on pull requests labeled ci:vm-slow. A weekly
workflow opens a pull request that
moves flake.lock, and the same jobs run on it.
Commits
Commit messages follow the
Conventional Commits specification:
type(scope): description. The scope is the Rust module the change is in
(wm, kwin, layouts), repo for repository files and markdown, nix for
the flake and github for workflows. Every line of a message, the header
included, is at most 80 columns, and the body says why the change is made.
Documentation lands in the commit that changes the behavior it describes, not
in a later one. A change to a komorebic subcommand regenerates its page in
docs/cli with just docgen.
Zero-Clause BSD
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.