chore(repo): a workspace of two crates

komorebi for KDE is built up as a Cargo workspace with one crate per concern,
the way komorebi and komorebi for Mac are. The first two crates are the
`komorebi` daemon, which does nothing yet but report its version, and `version`,
which owns the string every binary of the workspace reports.

`version` reads the commit from git when HEAD is on a branch, and from
COMMIT_HASH otherwise. A jj workspace leaves HEAD detached, so
`.cargo/config.toml` defaults the variable to `unknown` (nix will set the real
commit), and a plain `cargo build` in a jj checkout compiles.

The tooling files come from komorebi for Mac: the licence, deny.toml (trimmed to
the licences in use), rustfmt.toml and the toolchain file. `just check` runs the
formatting check, clippy and rustdoc with warnings denied, and the tests.
rustfmt.toml uses an unstable option, so formatting needs a nightly rustfmt. The
`rg` calls in `just lint` name a path because rg reads stdin when it is given
none and stdin is not a terminal.

The README and CONTRIBUTING.md say how to run, check and commit.
This commit is contained in:
LGUG2Z committed 2026-10-27 09:11:36 -07:00
commit 426409fcfc
17 files changed
+1443

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
[env]
# The version crate reads the commit from git when HEAD is on a branch, and from
# this variable otherwise (a detached HEAD, which jj leaves, or a build with no
# .git directory). Nix sets the real commit, which takes precedence over this.
COMMIT_HASH = "unknown"
+4
View File
@@ -0,0 +1,4 @@
/target
/result*
/.direnv
/.vm
+64
View File
@@ -0,0 +1,64 @@
# 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
`just check` runs everything a change has to pass before it is pushed: the
formatting check, clippy with warnings denied, the tests, and rustdoc with
warnings denied. Formatting needs a nightly `rustfmt`, because
[`rustfmt.toml`](rustfmt.toml) uses an unstable option; `just fmt` applies it.
## Commits
Commit messages follow the
[Conventional Commits](https://www.conventionalcommits.org/) 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.
## Zero-Clause BSD
```text
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.
```
Generated
+1025
View File
File diff suppressed because it is too large. Load diff
+14
View File
@@ -0,0 +1,14 @@
[workspace]
resolver = "2"
members = ["komorebi", "version"]
[workspace.package]
version = "0.1.0"
[workspace.dependencies]
clap = { version = "4", features = ["derive", "wrap_help"] }
shadow-rs = "1"
[workspace.metadata.crane]
name = "komorebi-workspace"
+108
View File
@@ -0,0 +1,108 @@
# Komorebi License
Version 2.0.0
## Acceptance
In order to get any license under these terms, you must agree
to them as both strict obligations and conditions to all
your licenses.
## Copyright License
The licensor grants you a copyright license for the software
to do everything you might do with the software that would
otherwise infringe the licensor's copyright in it for any
permitted purpose. However, you may only distribute the source
code of the software according to the [Distribution License](
#distribution-license), you may only make changes according
to the [Changes License](#changes-license), and you may not
otherwise distribute the software or new works based on the
software.
## Distribution License
The licensor grants you an additional copyright license to
distribute copies of the source code of the software. Your
license to distribute covers distributing the source code of
the software with changes permitted by the [Changes License](
#changes-license).
## Changes License
The licensor grants you an additional copyright license to
make changes for any permitted purpose.
## Patent License
The licensor grants you a patent license for the software that
covers patent claims the licensor can license, or becomes able
to license, that you would infringe by using the software.
## Personal Uses
Personal use for research, experiment, and testing for
the benefit of public knowledge, personal study, private
entertainment, hobby projects, amateur pursuits, or religious
observance, without any anticipated commercial application,
is use for a permitted purpose.
## Fair Use
You may have "fair use" rights for the software under the
law. These terms do not limit them.
## No Other Rights
These terms do not allow you to sublicense or transfer any of
your licenses to anyone else, or prevent the licensor from
granting licenses to anyone else. These terms do not imply
any other licenses.
## Patent Defense
If you make any written claim that the software infringes or
contributes to infringement of any patent, your patent license
for the software granted under these terms ends immediately. If
your company makes such a claim, your patent license ends
immediately for work on behalf of your company.
## Violations
The first time you are notified in writing that you have
violated any of these terms, or done anything with the software
not covered by your licenses, your licenses can nonetheless
continue if you come into full compliance with these terms,
and take practical steps to correct past violations, within
32 days of receiving notice. Otherwise, all your licenses
end immediately.
## No Liability
***As far as the law allows, the software comes as is, without
any warranty or condition, and the licensor will not be liable
to you for any damages arising out of these terms or the use
or nature of the software, under any kind of legal claim.***
## Definitions
The **licensor** is the individual or entity offering these
terms, and the **software** is the software the licensor makes
available under these terms.
**You** refers to the individual or entity agreeing to these
terms.
**Your company** is any legal entity, sole proprietorship,
or other kind of organization that you work for, plus all
organizations that have control over, are under the control of,
or are under common control with that organization. **Control**
means ownership of substantially all the assets of an entity,
or the power to direct its management and policies by vote,
contract, or otherwise. Control can be direct or indirect.
**Your licenses** are all the licenses granted to you for the
software under these terms.
**Use** means anything you do with the software requiring one
of your licenses.
+36
View File
@@ -0,0 +1,36 @@
# komorebi for KDE
A tiling window manager for KDE Plasma on Wayland, in the family of
[komorebi](https://github.com/LGUG2Z/komorebi) for Windows and
[komorebi for Mac](https://github.com/LGUG2Z/komorebi-for-mac). The daemon
decides where each window goes, and KWin, the window manager of Plasma, does the
moving and the drawing.
## Running it locally
```sh
cargo run --bin komorebi --locked -- --version
```
The `rust-toolchain.toml` at the root selects the Rust toolchain.
## Crates
- [`komorebi`](komorebi): the daemon.
- [`version`](version): the version string every binary reports.
## Checks
`just check` runs the formatting check, clippy with warnings denied, the tests
and rustdoc with warnings denied. Formatting needs a nightly `rustfmt`, because
[`rustfmt.toml`](rustfmt.toml) uses an unstable option.
## Documentation
`cargo doc --workspace --no-deps --open` builds the API documentation.
[`CONTRIBUTING.md`](CONTRIBUTING.md) says how to work on the code.
## License
komorebi for KDE is under the [Komorebi License](LICENSE.md). Contributions
are accepted under the terms in [`CONTRIBUTING.md`](CONTRIBUTING.md).
+37
View File
@@ -0,0 +1,37 @@
[graph]
targets = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"aarch64-apple-darwin",
]
all-features = false
no-default-features = false
[output]
feature-depth = 1
[licenses]
allow = ["Apache-2.0", "MIT", "Unicode-3.0", "Zlib", "LicenseRef-Komorebi-2.0"]
confidence-threshold = 0.8
[[licenses.clarify]]
crate = "komorebi"
expression = "LicenseRef-Komorebi-2.0"
license-files = []
[[licenses.clarify]]
crate = "version"
expression = "LicenseRef-Komorebi-2.0"
license-files = []
[bans]
multiple-versions = "allow"
wildcards = "allow"
highlight = "all"
workspace-default-features = "allow"
external-default-features = "allow"
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
+21
View File
@@ -0,0 +1,21 @@
export RUST_BACKTRACE := "full"
# format the Rust sources (needs a nightly rustfmt: rustfmt.toml uses unstable options)
fmt:
cargo fmt
# everything a change has to pass before it is pushed
check: lint
cargo fmt --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --locked
# the macros the codebase has agreed not to use
lint:
test -z "$(rg 'eyre!' --type rust .)" || (echo "eyre! macro not allowed"; false)
test -z "$(rg 'dbg!' --type rust .)" || (echo "dbg! macro not allowed"; false)
test -z "$(rg 'println!' --type rust ./komorebi/src)" || (echo "println! macro not allowed"; false)
run target *args:
cargo run --bin {{ target }} --locked -- {{ args }}
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "komorebi"
version.workspace = true
description = "A tiling window manager for KDE Plasma"
edition = "2024"
[dependencies]
version = { path = "../version" }
clap = { workspace = true }
+15
View File
@@ -0,0 +1,15 @@
//! The komorebi daemon: a tiling window manager for KDE Plasma.
//!
//! The daemon owns the layout of every window and asks KWin, the window
//! manager of Plasma, to put each one where the layout says.
use clap::Parser;
/// A tiling window manager for KDE Plasma.
#[derive(Parser)]
#[clap(author, about, version = version::LONG_VERSION)]
struct Opts {}
fn main() {
Opts::parse();
}
+18
View File
@@ -0,0 +1,18 @@
//! `komorebi --version` reports the workspace version.
use std::process::Command;
#[test]
fn reports_the_package_version() {
let output = Command::new(env!("CARGO_BIN_EXE_komorebi"))
.arg("--version")
.output()
.expect("komorebi runs");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).expect("utf-8 output");
let expected = format!("komorebi {}", env!("CARGO_PKG_VERSION"));
assert_eq!(stdout.lines().next(), Some(expected.as_str()));
}
+2
View File
@@ -0,0 +1,2 @@
[toolchain]
channel = "stable"
+1
View File
@@ -0,0 +1 @@
imports_granularity = "Item"
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "version"
edition = "2024"
version.workspace = true
[dependencies]
shadow-rs = { workspace = true }
[build-dependencies]
shadow-rs = { workspace = true }
+40
View File
@@ -0,0 +1,40 @@
use std::fs::File;
use std::io::Write;
use shadow_rs::SdResult;
use shadow_rs::ShadowBuilder;
fn main() {
let shadow_build = ShadowBuilder::builder().hook(raw_hook).build().unwrap();
let is_flake_build = shadow_build
.map
.get("BRANCH")
.map_or_else(|| true, |entry| entry.v.is_empty());
if is_flake_build {
ShadowBuilder::builder().hook(flake_hook).build().unwrap();
}
}
const RAW_VERSION_CONST: &str = r##"pub const LONG_VERSION:&str = shadow_rs::formatcp!(r#"{}
branch:{}
commit_hash:{}
build_env:{},{}"#,PKG_VERSION, BRANCH, COMMIT_HASH, RUST_VERSION, RUST_CHANNEL
);
"##;
fn raw_hook(mut file: &File) -> SdResult<()> {
writeln!(file, "{RAW_VERSION_CONST}")?;
Ok(())
}
const FLAKE_VERSION_CONST: &str = r##"pub const LONG_VERSION:&str = shadow_rs::formatcp!(r#"{}
commit_hash:{}
build_env:{},{}"#,PKG_VERSION, env!("COMMIT_HASH"), RUST_VERSION, RUST_CHANNEL
);"##;
fn flake_hook(mut file: &File) -> SdResult<()> {
writeln!(file, "{FLAKE_VERSION_CONST}")?;
Ok(())
}
+33
View File
@@ -0,0 +1,33 @@
//! The version string every komorebi binary reports.
//!
//! [`LONG_VERSION`] is the package version followed by the commit the binary
//! was built from and the Rust toolchain that built it. The binaries pass it to
//! their command line parsers, so `komorebi --version` and
//! `komorebic --version` report the same thing.
//!
//! # Where the commit comes from
//!
//! A build from a git checkout whose `HEAD` is on a branch asks git for the
//! branch and the commit. Any other build has nothing to ask: a detached `HEAD`
//! (which is what a jj workspace leaves), a source tree with no `.git`
//! directory, or a sandboxed nix build. Such a build reads the commit from the
//! `COMMIT_HASH` environment variable, and does not compile without it.
//! [`.cargo/config.toml`](https://github.com/LGUG2Z/komorebi-for-kde/blob/master/.cargo/config.toml)
//! defaults the variable to `unknown`, and nix sets it to the real commit.
shadow_rs::shadow!(build);
/// The package version, the commit and the toolchain of this build, one per
/// line.
///
/// The first line is the package version, which every crate in the workspace
/// shares.
///
/// # Example
///
/// ```rust
/// let first_line = version::LONG_VERSION.lines().next();
///
/// assert_eq!(first_line, Some(env!("CARGO_PKG_VERSION")));
/// ```
pub use build::LONG_VERSION;