mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-13 12:23:38 +01:00
feat(catalog): index the komorebi source in this repository, not a checkout of each komorebi
The recorder is a member of the repository it indexes: each flavor is built from the directory of its own daemon (komorebi-macos, komorebi-windows, komorebi-linux) and the shared crates that log. The statements of the container, workspace and monitor moved into komorebi-core, so the targets of the real log sample in the fixture are komorebi_core's. KOMOREBI_SRC and KOMOREBI_COMMIT replace the three KOMOREBI_*_SRC variables, for a build that is not in a checkout.
This commit is contained in:
1 parent
9854f90db7
commit
170a6f51c0
9 files changed
+151
-120
No files matched your search
+46
-36
@@ -8,18 +8,18 @@
|
||||
//! `komorebi-recorder code` can answer "which line wrote this?" and say when the answer may be
|
||||
//! about a different version of komorebi than the one that was recorded.
|
||||
//!
|
||||
//! There is one catalog per flavor, because komorebi for Mac and komorebi for Windows are different
|
||||
//! programs with different logs. Each is built from a checkout named by an environment variable:
|
||||
//! There is one catalog per flavor, because komorebi for Windows, macOS and KDE Plasma are different
|
||||
//! daemons with different logs. All of them are in this repository, so each is built from the
|
||||
//! directories of its own daemon and of the crates it shares, in the checkout this crate is in:
|
||||
//!
|
||||
//! | flavor | variable | when it is not set |
|
||||
//! |---|---|---|
|
||||
//! | macOS | `KOMOREBI_MAC_SRC` | an empty catalog, which says so |
|
||||
//! | Windows | `KOMOREBI_WINDOWS_SRC` | an empty catalog, which says so |
|
||||
//! | flavor | directories indexed |
|
||||
//! |---|---|
|
||||
//! | macOS | `komorebi-macos/src`, the shared crates |
|
||||
//! | Windows | `komorebi-windows/src`, the shared crates |
|
||||
//! | KDE | `komorebi-linux/src`, the shared crates |
|
||||
//!
|
||||
//! The commit of each comes from git, or else from `KOMOREBI_MAC_COMMIT` /
|
||||
//! `KOMOREBI_WINDOWS_COMMIT` for a build outside a checkout (nix).
|
||||
//!
|
||||
//! If a source is not there the catalog is empty and says so.
|
||||
//! `KOMOREBI_SRC` names another checkout of the repository to index instead, and `KOMOREBI_COMMIT` the
|
||||
//! commit of the source when it is not a git checkout (nix). The commit otherwise comes from git.
|
||||
//!
|
||||
//! The script also gives the Windows executables their icon, which Explorer reads from a resource in the file: see
|
||||
//! [`embed_icon`].
|
||||
@@ -38,40 +38,47 @@ use syn::visit::Visit;
|
||||
struct Flavor {
|
||||
/// The name of its catalog in the generated code.
|
||||
name: &'static str,
|
||||
/// The variable naming a checkout of it.
|
||||
source_env: &'static str,
|
||||
/// The variable giving the commit when the checkout is not a git repository.
|
||||
commit_env: &'static [&'static str],
|
||||
/// The source trees to index: their directory under the checkout, and their Rust crate name.
|
||||
crates: &'static [(&'static str, &'static str)],
|
||||
}
|
||||
|
||||
/// The crates of every flavor that write log statements: the daemons call into them.
|
||||
const SHARED: &[(&str, &str)] = &[
|
||||
("komorebi-client/src", "komorebi_client"),
|
||||
("komorebi-layouts/src", "komorebi_layouts"),
|
||||
("crates/komorebi-core/src", "komorebi_core"),
|
||||
("crates/komorebi-transport/src", "komorebi_transport"),
|
||||
];
|
||||
|
||||
const FLAVORS: &[Flavor] = &[
|
||||
Flavor {
|
||||
name: "MAC",
|
||||
source_env: "KOMOREBI_MAC_SRC",
|
||||
commit_env: &["KOMOREBI_MAC_COMMIT"],
|
||||
crates: &[
|
||||
("komorebi/src", "komorebi"),
|
||||
("komorebi-client/src", "komorebi_client"),
|
||||
("komorebi-macos/src", "komorebi"),
|
||||
SHARED[0],
|
||||
SHARED[1],
|
||||
SHARED[2],
|
||||
SHARED[3],
|
||||
],
|
||||
},
|
||||
Flavor {
|
||||
name: "WINDOWS",
|
||||
source_env: "KOMOREBI_WINDOWS_SRC",
|
||||
commit_env: &["KOMOREBI_WINDOWS_COMMIT"],
|
||||
crates: &[
|
||||
("komorebi/src", "komorebi"),
|
||||
("komorebi-layouts/src", "komorebi_layouts"),
|
||||
("komorebi-windows/src", "komorebi"),
|
||||
SHARED[0],
|
||||
SHARED[1],
|
||||
SHARED[2],
|
||||
SHARED[3],
|
||||
],
|
||||
},
|
||||
Flavor {
|
||||
name: "KDE",
|
||||
source_env: "KOMOREBI_KDE_SRC",
|
||||
commit_env: &["KOMOREBI_KDE_COMMIT"],
|
||||
crates: &[
|
||||
("komorebi/src", "komorebi"),
|
||||
("komorebi-client/src", "komorebi_client"),
|
||||
("komorebi-linux/src", "komorebi"),
|
||||
SHARED[0],
|
||||
SHARED[1],
|
||||
SHARED[2],
|
||||
SHARED[3],
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -359,14 +366,18 @@ fn key(path: &Path, repo: &Path) -> String {
|
||||
|
||||
/// The generated code for one flavor's catalog.
|
||||
fn index(flavor: &Flavor) -> String {
|
||||
println!("cargo:rerun-if-env-changed={}", flavor.source_env);
|
||||
for variable in flavor.commit_env {
|
||||
println!("cargo:rerun-if-env-changed={variable}");
|
||||
}
|
||||
println!("cargo:rerun-if-env-changed=KOMOREBI_SRC");
|
||||
println!("cargo:rerun-if-env-changed=KOMOREBI_COMMIT");
|
||||
|
||||
let repo = env::var_os(flavor.source_env)
|
||||
// this crate is a member of the repository it indexes
|
||||
let repo = env::var_os("KOMOREBI_SRC")
|
||||
.map(PathBuf::from)
|
||||
.filter(|path| !path.as_os_str().is_empty());
|
||||
.filter(|path| !path.as_os_str().is_empty())
|
||||
.or_else(|| {
|
||||
env::var_os("CARGO_MANIFEST_DIR")
|
||||
.map(PathBuf::from)
|
||||
.and_then(|manifest| manifest.parent().map(Path::to_path_buf))
|
||||
});
|
||||
|
||||
let mut logs = Vec::new();
|
||||
let mut spans = Vec::new();
|
||||
@@ -432,10 +443,9 @@ fn index(flavor: &Flavor) -> String {
|
||||
.and_then(|repo| git(repo, &["rev-parse", "HEAD"]));
|
||||
let commit = from_git
|
||||
.or_else(|| {
|
||||
flavor
|
||||
.commit_env
|
||||
.iter()
|
||||
.find_map(|variable| env::var(variable).ok().filter(|hash| !hash.is_empty()))
|
||||
env::var("KOMOREBI_COMMIT")
|
||||
.ok()
|
||||
.filter(|hash| !hash.is_empty())
|
||||
})
|
||||
.unwrap_or_default();
|
||||
if let Some(repo) = &repo {
|
||||
|
||||
@@ -19,18 +19,11 @@
|
||||
//! programs with different logs, and [`of`] picks the one for the flavor a session recorded (see
|
||||
//! [`Analysis::catalog`](super::Analysis::catalog)): a session recorded on Windows is mapped to
|
||||
//! komorebi for Windows' source even when it is investigated on a Mac. Each is built from a
|
||||
//! checkout of that komorebi named by an environment variable when the recorder is compiled:
|
||||
//! source tree of this repository when the recorder is compiled: the daemon of the flavor and the crates
|
||||
//! it shares (see `build.rs` for the directories). `KOMOREBI_SRC` and `KOMOREBI_COMMIT` index another checkout
|
||||
//! instead, and name the commit when the source is not a git checkout (nix).
|
||||
//!
|
||||
//! | flavor | checkout | its commit, outside a git checkout | directories indexed |
|
||||
//! |---|---|---|---|
|
||||
//! | [`Flavor::Macos`] | `KOMOREBI_MAC_SRC` | `KOMOREBI_MAC_COMMIT` | `komorebi/src`, `komorebi-client/src` |
|
||||
//! | [`Flavor::Windows`] | `KOMOREBI_WINDOWS_SRC` | `KOMOREBI_WINDOWS_COMMIT` | `komorebi/src`, `komorebi-layouts/src` |
|
||||
//!
|
||||
//! `nix develop` sets all four. A flavor whose variable is not set (or whose checkout has no Rust
|
||||
//! files in those directories) gets an **empty** catalog: nothing is found in it,
|
||||
//! [`Catalog::is_empty`] is `true`, and [`skew`] tells the reader which variable to set. `build.rs`
|
||||
//! prints a cargo warning if a checkout is named but nothing in it could be read, or if a file
|
||||
//! fails to parse.
|
||||
//! `build.rs` prints a cargo warning if nothing in the source could be read, or if a file fails to parse.
|
||||
//!
|
||||
//! What is indexed, for each Rust file of those directories:
|
||||
//!
|
||||
@@ -152,8 +145,8 @@ pub fn of(flavor: Flavor) -> &'static Catalog {
|
||||
|
||||
impl Catalog {
|
||||
/// Returns the commit of the source that was indexed, or `None` if the checkout was not a git
|
||||
/// repository and the build was not told the commit either (`KOMOREBI_MAC_COMMIT` or
|
||||
/// `KOMOREBI_WINDOWS_COMMIT`), as is the case for an empty catalog.
|
||||
/// repository and the build was not told the commit either (`KOMOREBI_COMMIT`), as is the case
|
||||
/// for an empty catalog.
|
||||
#[must_use]
|
||||
pub fn commit(&self) -> Option<&'static str> {
|
||||
(!self.commit.is_empty()).then_some(self.commit)
|
||||
@@ -258,12 +251,12 @@ impl Statement {
|
||||
/// level: "INFO".to_string(),
|
||||
/// target: "komorebi::process_event".to_string(),
|
||||
/// template: "processing event: {} for process {} with notification {}".to_string(),
|
||||
/// file: "komorebi/src/process_event.rs".to_string(),
|
||||
/// file: "komorebi-macos/src/process_event.rs".to_string(),
|
||||
/// line: 120,
|
||||
/// function: "process_event".to_string(),
|
||||
/// owner: "WindowManager".to_string(),
|
||||
/// };
|
||||
/// assert_eq!(statement.location(), "komorebi/src/process_event.rs:120");
|
||||
/// assert_eq!(statement.location(), "komorebi-macos/src/process_event.rs:120");
|
||||
/// assert_eq!(statement.qualified_function(), "WindowManager::process_event");
|
||||
///
|
||||
/// // outside any `impl`, the function stands alone
|
||||
@@ -381,12 +374,12 @@ impl Catalog {
|
||||
/// use komorebi_recorder::analysis::logparse::Level;
|
||||
///
|
||||
/// let catalog = catalog::of(Flavor::Macos);
|
||||
/// # if catalog.is_empty() { return; } // built without KOMOREBI_MAC_SRC: nothing is indexed
|
||||
/// # if catalog.is_empty() { return; } // built without the source: nothing is indexed
|
||||
///
|
||||
/// let found = catalog
|
||||
/// .find("komorebi::reaper", Level::Info, "reaping window: 4711")
|
||||
/// .expect("the reaper logs this");
|
||||
/// assert_eq!(found.statement.file, "komorebi/src/reaper.rs");
|
||||
/// assert_eq!(found.statement.file, "komorebi-macos/src/reaper.rs");
|
||||
/// assert!(found.statement.template.starts_with("reaping window"));
|
||||
///
|
||||
/// // no statement could have written this
|
||||
@@ -753,7 +746,7 @@ pub fn skew_between(
|
||||
/// `root` (see [`crate::annotations::default_code_root`]) to say which files differ.
|
||||
///
|
||||
/// If the flavor's catalog is empty the warning is replaced by one saying that nothing is indexed
|
||||
/// and which variable to build with (`KOMOREBI_MAC_SRC` or `KOMOREBI_WINDOWS_SRC`); the verdict is
|
||||
/// and which variable to build with (`KOMOREBI_SRC`); the verdict is
|
||||
/// left as [`skew_between`] decided it. [`Analysis::skew`](super::Analysis::skew) calls this with
|
||||
/// the session's flavor and recorded versions.
|
||||
///
|
||||
@@ -772,13 +765,8 @@ pub fn skew(flavor: Flavor, versions: &[KomorebiVersion], root: Option<&std::pat
|
||||
if catalog.is_empty() {
|
||||
skew.warning = Some(format!(
|
||||
"this build of komorebi-recorder has no source indexed for komorebi for {flavor}, so \
|
||||
log lines cannot be mapped to code; build it with {} pointing at a checkout of \
|
||||
komorebi for {flavor}",
|
||||
match flavor {
|
||||
Flavor::Macos => "KOMOREBI_MAC_SRC",
|
||||
Flavor::Windows => "KOMOREBI_WINDOWS_SRC",
|
||||
Flavor::Kde => "KOMOREBI_KDE_SRC",
|
||||
}
|
||||
log lines cannot be mapped to code; build it with KOMOREBI_SRC pointing at a checkout of \
|
||||
komorebi for {flavor}"
|
||||
));
|
||||
}
|
||||
|
||||
@@ -795,7 +783,13 @@ mod tests {
|
||||
}
|
||||
|
||||
/// The directories of the Mac checkout that its catalog indexes.
|
||||
const MAC_PATHS: &[&str] = &["komorebi/src", "komorebi-client/src"];
|
||||
const MAC_PATHS: &[&str] = &[
|
||||
"komorebi-macos/src",
|
||||
"komorebi-client/src",
|
||||
"komorebi-layouts/src",
|
||||
"crates/komorebi-core/src",
|
||||
"crates/komorebi-transport/src",
|
||||
];
|
||||
|
||||
fn commit() -> Option<&'static str> {
|
||||
mac().commit()
|
||||
@@ -856,7 +850,7 @@ mod tests {
|
||||
)
|
||||
.expect("the header statement");
|
||||
|
||||
assert_eq!(found.statement.file, "komorebi/src/process_event.rs");
|
||||
assert_eq!(found.statement.file, "komorebi-macos/src/process_event.rs");
|
||||
assert_eq!(found.statement.function, "process_event");
|
||||
assert_eq!(found.statement.owner, "WindowManager");
|
||||
assert_eq!(found.confidence, Confidence::Likely);
|
||||
@@ -1001,7 +995,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(skew.verdict, "same");
|
||||
assert!(skew.warning.is_none());
|
||||
assert!(!skew.file_changed("komorebi/src/window.rs"));
|
||||
assert!(!skew.file_changed("komorebi-macos/src/window.rs"));
|
||||
|
||||
// but not if the source had uncommitted changes when indexed
|
||||
let dirty = skew_between(
|
||||
@@ -1032,15 +1026,17 @@ mod tests {
|
||||
.contains("cannot say how they differ")
|
||||
);
|
||||
// when it cannot be told, nothing is vouched for
|
||||
assert!(skew.file_changed("komorebi/src/window.rs"));
|
||||
assert!(skew.file_changed("komorebi-macos/src/window.rs"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_older_commit_differs_in_exactly_the_files_git_says() {
|
||||
let Some(indexed) = commit() else { return };
|
||||
// the commit before the latest change to komorebi's source
|
||||
let Some(history) = git(&repo(), &["log", "-2", "--format=%H", "--", "komorebi/src"])
|
||||
else {
|
||||
let Some(history) = git(
|
||||
&repo(),
|
||||
&["log", "-2", "--format=%H", "--", "komorebi-macos/src"],
|
||||
) else {
|
||||
return;
|
||||
};
|
||||
let Some(older) = history.lines().nth(1) else {
|
||||
@@ -1062,8 +1058,11 @@ mod tests {
|
||||
older,
|
||||
indexed,
|
||||
"--",
|
||||
"komorebi/src",
|
||||
"komorebi-macos/src",
|
||||
"komorebi-client/src",
|
||||
"komorebi-layouts/src",
|
||||
"crates/komorebi-core/src",
|
||||
"crates/komorebi-transport/src",
|
||||
],
|
||||
)
|
||||
.expect("git diff");
|
||||
@@ -1079,7 +1078,7 @@ mod tests {
|
||||
for file in expected.lines() {
|
||||
assert!(skew.file_changed(file));
|
||||
}
|
||||
assert!(!skew.file_changed("komorebi/src/a_file_that_never_changed.rs"));
|
||||
assert!(!skew.file_changed("komorebi-macos/src/a_file_that_never_changed.rs"));
|
||||
}
|
||||
|
||||
fn rust_files(directory: &std::path::Path, found: &mut Vec<std::path::PathBuf>) {
|
||||
@@ -1099,7 +1098,7 @@ mod tests {
|
||||
#[test]
|
||||
fn every_log_statement_in_komorebis_source_is_indexed() {
|
||||
crate::skip_without_komorebi_mac_source!();
|
||||
let root = crate::testkit::komorebi_mac_src().join("komorebi/src");
|
||||
let root = crate::testkit::komorebi_mac_src().join("komorebi-macos/src");
|
||||
let mut files = Vec::new();
|
||||
rust_files(&root, &mut files);
|
||||
|
||||
@@ -1119,7 +1118,7 @@ mod tests {
|
||||
let indexed = mac()
|
||||
.entries
|
||||
.iter()
|
||||
.filter(|entry| entry.file.starts_with("komorebi/src/"))
|
||||
.filter(|entry| entry.file.starts_with("komorebi-macos/src/"))
|
||||
.count();
|
||||
assert_eq!(
|
||||
indexed, in_source,
|
||||
@@ -1129,8 +1128,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn each_flavor_has_a_catalog_of_its_own_source() {
|
||||
// the Windows catalog is built only when KOMOREBI_WINDOWS_SRC names a checkout; where it
|
||||
// is, its statements are komorebi for Windows's, not the Mac's
|
||||
// the Windows catalog is of the Windows daemon's source, not the Mac's
|
||||
let windows = of(Flavor::Windows);
|
||||
if windows.is_empty() {
|
||||
assert_eq!(windows.files_scanned(), 0);
|
||||
@@ -1167,7 +1165,7 @@ mod tests {
|
||||
let skew = skew(Flavor::Windows, &[], None);
|
||||
if of(Flavor::Windows).is_empty() {
|
||||
let warning = skew.warning.expect("a warning");
|
||||
assert!(warning.contains("KOMOREBI_WINDOWS_SRC"), "{warning}");
|
||||
assert!(warning.contains("KOMOREBI_SRC"), "{warning}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,13 +292,13 @@ impl Analysis {
|
||||
///
|
||||
/// let (session, _) = SessionBuilder::new("doc-code-search").build();
|
||||
/// let analysis = Analysis::open(&session.dir)?;
|
||||
/// # if analysis.catalog().is_empty() { return Ok(()); } // built without KOMOREBI_MAC_SRC
|
||||
/// # if analysis.catalog().is_empty() { return Ok(()); } // built without the source
|
||||
///
|
||||
/// let found = analysis.code_search("Reaping WINDOW");
|
||||
/// assert_eq!(found.about, "grep Reaping WINDOW");
|
||||
/// assert!(found.lines.is_empty());
|
||||
/// assert!(!found.statements.is_empty());
|
||||
/// assert!(found.statements.iter().any(|statement| statement.file == "komorebi/src/reaper.rs"));
|
||||
/// assert!(found.statements.iter().any(|statement| statement.file == "komorebi-macos/src/reaper.rs"));
|
||||
/// # Ok::<(), Box<dyn std::error::Error>>(())
|
||||
/// ```
|
||||
///
|
||||
|
||||
@@ -195,6 +195,25 @@ pub enum Flavor {
|
||||
}
|
||||
|
||||
impl Flavor {
|
||||
/// Returns the directory of this flavor's daemon source in the komorebi repository, which is
|
||||
/// where [`Ref::Code`](crate::annotations::Ref::Code) paths for it start.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use komorebi_recorder::analysis::flavor::Flavor;
|
||||
///
|
||||
/// assert_eq!(Flavor::Macos.daemon_source(), "komorebi-macos/src");
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub const fn daemon_source(self) -> &'static str {
|
||||
match self {
|
||||
Flavor::Macos => "komorebi-macos/src",
|
||||
Flavor::Windows => "komorebi-windows/src",
|
||||
Flavor::Kde => "komorebi-linux/src",
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the flavor of the komorebi that runs on this machine: there is one per OS, and a
|
||||
/// recorder watches the one on its own host.
|
||||
///
|
||||
|
||||
@@ -1152,11 +1152,11 @@ pub fn delete(dir: &Path, id: &str) -> eyre::Result<()> {
|
||||
/// 1. the flavor's own environment variable: `KOMOREBI_MAC_SRC` for komorebi for Mac,
|
||||
/// `KOMOREBI_WINDOWS_SRC` for komorebi for Windows;
|
||||
/// 2. `KOMOREBI_SOURCE`, which serves either flavor;
|
||||
/// 3. the checkout this recorder was built against, if it was built with one for this flavor (the
|
||||
/// `KOMOREBI_MAC_ROOT` or `KOMOREBI_WINDOWS_ROOT` that its build script sets) and that
|
||||
/// directory is still on disk.
|
||||
/// 3. the checkout this recorder was built in (the `KOMOREBI_MAC_ROOT`, `KOMOREBI_WINDOWS_ROOT` or
|
||||
/// `KOMOREBI_KDE_ROOT` that its build script sets), if that directory is still on disk.
|
||||
///
|
||||
/// The first candidate that has a `komorebi/src` directory is returned. A candidate that does not
|
||||
/// The first candidate that has the flavor's daemon source directory (see
|
||||
/// [`Flavor::daemon_source`]) is returned. A candidate that does not
|
||||
/// have one is skipped, not reported, so a variable that is set but wrong falls through to the
|
||||
/// next. `None` means no candidate qualified; [`validate_refs`] then cannot check [`Ref::Code`]
|
||||
/// and reports it in a warning.
|
||||
@@ -1187,7 +1187,7 @@ pub fn default_code_root(flavor: Flavor) -> Option<PathBuf> {
|
||||
.filter_map(std::env::var_os)
|
||||
.map(PathBuf::from)
|
||||
.chain(built_from)
|
||||
.find(|root| root.join("komorebi/src").is_dir())
|
||||
.find(|root| root.join(flavor.daemon_source()).is_dir())
|
||||
}
|
||||
|
||||
fn count_lines(path: &Path) -> std::io::Result<u64> {
|
||||
|
||||
@@ -725,39 +725,37 @@ pub fn numbered_frame_index(bgra: &[u8], width: u32, height: u32) -> u32 {
|
||||
index
|
||||
}
|
||||
|
||||
/// The checkout of komorebi for Mac that the tests which read komorebi's source read it from.
|
||||
/// The checkout of komorebi that the tests which read komorebi's source read it from.
|
||||
///
|
||||
/// That is the catalog and `code`. It is the checkout `KOMOREBI_MAC_SRC` names, which `nix develop`
|
||||
/// sets to the revision pinned in `flake.lock`.
|
||||
/// That is the catalog and `code`. It is the repository this crate is in, or the checkout
|
||||
/// `KOMOREBI_SRC` names (nix builds the tests from a copy of the source).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics, naming the variable, when it is not set: those tests have nothing to check without a
|
||||
/// tree.
|
||||
/// Panics when the directory above the manifest cannot be found.
|
||||
#[must_use]
|
||||
pub fn komorebi_mac_src() -> PathBuf {
|
||||
std::env::var_os("KOMOREBI_MAC_SRC")
|
||||
std::env::var_os("KOMOREBI_SRC")
|
||||
.map(PathBuf::from)
|
||||
.filter(|path| !path.as_os_str().is_empty())
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"KOMOREBI_MAC_SRC is not set: it names the checkout of komorebi for Mac that these \
|
||||
tests read (`nix develop` sets it)"
|
||||
)
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
.expect("the repository above the crate")
|
||||
.to_path_buf()
|
||||
})
|
||||
}
|
||||
|
||||
/// Whether the tests that read komorebi for Mac's source can run: `KOMOREBI_MAC_SRC` names a
|
||||
/// checkout, and this build indexed it (an empty catalog means it was built without one).
|
||||
/// Whether the tests that read komorebi for Mac's source can run: this build indexed the source
|
||||
/// (an empty catalog means it was built from a tree without it).
|
||||
///
|
||||
/// A machine that has neither (Windows, or a Mac outside `nix develop`) has nothing for those
|
||||
/// tests to check, which is not a failure: they use
|
||||
/// A build from a tree that has no komorebi source around it has nothing for those tests to
|
||||
/// check, which is not a failure: they use
|
||||
/// [`skip_without_komorebi_mac_source!`](crate::skip_without_komorebi_mac_source) to say so and
|
||||
/// stop, as the tests that need `ffmpeg` do.
|
||||
#[must_use]
|
||||
pub fn komorebi_mac_source_available() -> bool {
|
||||
std::env::var_os("KOMOREBI_MAC_SRC").is_some_and(|path| !path.is_empty())
|
||||
&& !crate::analysis::catalog::of(crate::analysis::flavor::Flavor::Macos).is_empty()
|
||||
!crate::analysis::catalog::of(crate::analysis::flavor::Flavor::Macos).is_empty()
|
||||
}
|
||||
|
||||
/// Ends the test that uses it, saying why, on a machine that has no komorebi for Mac source to
|
||||
@@ -767,7 +765,7 @@ macro_rules! skip_without_komorebi_mac_source {
|
||||
() => {
|
||||
if !$crate::testkit::komorebi_mac_source_available() {
|
||||
eprintln!(
|
||||
"skipped: KOMOREBI_MAC_SRC is not set, or this build was made without it \
|
||||
"skipped: this build indexed no komorebi source \
|
||||
(`nix develop` sets it)"
|
||||
);
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,7 @@ fn session(name: &str, commit: Option<&str>) -> String {
|
||||
None,
|
||||
)
|
||||
.log(2.0, "INFO", "process_event: komorebi::process_event: processing event: FocusChange for process 7 with notification AXApplicationActivated")
|
||||
.log(2.1, "INFO", "process_event:focus_window{idx=0}: komorebi::container: focusing window")
|
||||
.log(2.1, "INFO", "process_event:focus_window{idx=0}: komorebi_core::container: focusing window")
|
||||
.log(2.2, "INFO", "komorebi::reaper: reaping window: 4711")
|
||||
.log(2.25, "INFO", "komorebi::border_manager: invalidating border observer");
|
||||
if let Some(commit) = commit {
|
||||
@@ -57,7 +57,7 @@ fn a_log_line_is_traced_to_the_statement_that_wrote_it() {
|
||||
assert_eq!(line["target"], "komorebi::reaper");
|
||||
assert_eq!(line["message"], "reaping window: 4711");
|
||||
let source = &line["source"]["statement"];
|
||||
assert_eq!(source["file"], "komorebi/src/reaper.rs");
|
||||
assert_eq!(source["file"], "komorebi-macos/src/reaper.rs");
|
||||
assert!(
|
||||
source["template"]
|
||||
.as_str()
|
||||
@@ -149,7 +149,7 @@ fn git(args: &[&str]) -> Option<String> {
|
||||
#[test]
|
||||
fn only_the_files_that_changed_since_the_recorded_commit_are_doubted() {
|
||||
komorebi_recorder::skip_without_komorebi_mac_source!();
|
||||
let Some(history) = git(&["log", "-2", "--format=%H", "--", "komorebi/src"]) else {
|
||||
let Some(history) = git(&["log", "-2", "--format=%H", "--", "komorebi-macos/src"]) else {
|
||||
return;
|
||||
};
|
||||
let Some(older) = history.lines().nth(1) else {
|
||||
@@ -164,8 +164,11 @@ fn only_the_files_that_changed_since_the_recorded_commit_are_doubted() {
|
||||
older,
|
||||
indexed,
|
||||
"--",
|
||||
"komorebi/src",
|
||||
"komorebi-macos/src",
|
||||
"komorebi-client/src",
|
||||
"komorebi-layouts/src",
|
||||
"crates/komorebi-core/src",
|
||||
"crates/komorebi-transport/src",
|
||||
]) else {
|
||||
return;
|
||||
};
|
||||
@@ -237,7 +240,7 @@ fn statements_can_be_searched_by_their_text() {
|
||||
let statements = answer["data"]["statements"].as_array().expect("statements");
|
||||
let in_reaper = statements
|
||||
.iter()
|
||||
.filter(|statement| statement["file"] == "komorebi/src/reaper.rs")
|
||||
.filter(|statement| statement["file"] == "komorebi-macos/src/reaper.rs")
|
||||
.count();
|
||||
assert_eq!(in_reaper, 3, "{statements:#?}");
|
||||
}
|
||||
+15
-15
@@ -1,7 +1,7 @@
|
||||
2026-10-26T03:17:17.188982Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T03:17:17.188982Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T03:17:17.214014Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 20934 with notification AXApplicationActivated
|
||||
2026-10-26T03:17:17.216855Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T03:17:17.216865Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T03:17:17.216855Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T03:17:17.216865Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T03:37:19.703632Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 681 with notification AXApplicationActivated
|
||||
2026-10-26T03:37:19.781106Z ERROR process_event:update_focused_workspace{[3mfollow_focus[0m[2m=[0mtrue [3mtrigger_focus[0m[2m=[0mfalse}:update_focused_workspace:window_rect: komorebi::macos_api: failed to get window position: AXError::InvalidUIElement
|
||||
2026-10-26T03:37:19.783788Z WARN process_event:update_focused_workspace{[3mfollow_focus[0m[2m=[0mtrue [3mtrigger_focus[0m[2m=[0mfalse}:update_focused_workspace: komorebi::workspace: failed to set window position: AXError::InvalidUIElement
|
||||
@@ -25,15 +25,15 @@ thread 'main' panicked at komorebi/src/example.rs:1:1:
|
||||
2026-10-26T23:09:16.653486Z INFO process_event: komorebi::process_event: processing event: MoveEnd for process 96328 with notification AXWindowMoved
|
||||
2026-10-26T23:09:16.664319Z INFO process_event: komorebi::process_event: processing event: MoveEnd for process 47907 with notification AXWindowMoved
|
||||
2026-10-26T23:09:16.685293Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 79469 with notification NSWorkspaceDidActivateApplicationNotification
|
||||
2026-10-26T23:09:16.688494Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:16.688514Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T23:09:16.688494Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:16.688514Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T23:09:16.698081Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 79469 with notification AXApplicationActivated
|
||||
2026-10-26T23:09:16.700732Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:16.700745Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T23:09:16.700732Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:16.700745Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T23:09:17.733307Z INFO process_command: komorebi::process_command: processing command: FocusWorkspaceNumber
|
||||
2026-10-26T23:09:17.733352Z INFO process_command:focus_workspace{[3midx[0m[2m=[0m0}: komorebi::window_manager: focusing workspace
|
||||
2026-10-26T23:09:17.733359Z INFO process_command:focus_workspace{[3midx[0m[2m=[0m0}:focus_workspace{[3midx[0m[2m=[0m0}: komorebi::monitor: focusing workspace
|
||||
2026-10-26T23:09:17.756767Z INFO process_command:focus_workspace{[3midx[0m[2m=[0m0}:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:17.733359Z INFO process_command:focus_workspace{[3midx[0m[2m=[0m0}:focus_workspace{[3midx[0m[2m=[0m0}: komorebi_core::monitor: focusing workspace
|
||||
2026-10-26T23:09:17.756767Z INFO process_command:focus_workspace{[3midx[0m[2m=[0m0}:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:17.887836Z INFO process_command: komorebi::process_command: processed command: FocusWorkspaceNumber
|
||||
2026-10-26T23:09:17.889498Z INFO process_event: komorebi::process_event: processing event: MoveEnd for process 79469 with notification AXWindowMoved
|
||||
2026-10-26T23:09:17.901710Z INFO komorebi::border_manager: invalidating border observer
|
||||
@@ -45,11 +45,11 @@ thread 'main' panicked at komorebi/src/example.rs:1:1:
|
||||
2026-10-26T23:09:17.960135Z INFO process_event: komorebi::process_event: processing event: MoveEnd for process 1942 with notification AXWindowMoved
|
||||
2026-10-26T23:09:17.969092Z INFO process_event: komorebi::process_event: processing event: MoveEnd for process 72441 with notification AXWindowMoved
|
||||
2026-10-26T23:09:18.001875Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 20934 with notification NSWorkspaceDidActivateApplicationNotification
|
||||
2026-10-26T23:09:18.008861Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:18.008881Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T23:09:18.008861Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:18.008881Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T23:09:18.018616Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 20934 with notification AXMainWindowChanged
|
||||
2026-10-26T23:09:18.026372Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:18.026387Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T23:09:18.026372Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:18.026387Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
2026-10-26T23:09:18.048765Z INFO process_event: komorebi::process_event: processing event: FocusChange for process 20934 with notification AXApplicationActivated
|
||||
2026-10-26T23:09:18.052082Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi::container: focusing window
|
||||
2026-10-26T23:09:18.052094Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi::workspace: focusing container
|
||||
2026-10-26T23:09:18.052082Z INFO process_event:focus_window{[3midx[0m[2m=[0m0}: komorebi_core::container: focusing window
|
||||
2026-10-26T23:09:18.052094Z INFO process_event:focus_container{[3midx[0m[2m=[0m0}: komorebi_core::workspace: focusing container
|
||||
@@ -85,7 +85,7 @@ fn session(name: &str) -> String {
|
||||
.log(3.5, "INFO", "komorebi::reaper: reaping window: 2")
|
||||
.log(3.6, "INFO", "komorebi::border_manager: invalidating border observer")
|
||||
.log(3.9, "INFO", "process_event: komorebi::process_event: processing event: FocusChange for process 7 with notification AXApplicationActivated")
|
||||
.log(3.95, "INFO", "process_event:focus_container{idx=0}: komorebi::workspace: focusing container")
|
||||
.log(3.95, "INFO", "process_event:focus_container{idx=0}: komorebi_core::workspace: focusing container")
|
||||
.log(5.9, "INFO", "process_event: komorebi::process_event: processing event: Show for process 7 with notification AXWindowCreated")
|
||||
.build();
|
||||
session.dir.display().to_string()
|
||||
@@ -158,7 +158,10 @@ fn the_text_trace_reads_top_to_bottom() {
|
||||
assert!(handler < ambient && ambient < changed, "{text}");
|
||||
assert!(text.contains("reaper (high)"), "{text}");
|
||||
assert!(text.contains("evidence: log:2"), "{text}");
|
||||
assert!(text.contains("from komorebi/src/workspace.rs"), "{text}");
|
||||
assert!(
|
||||
text.contains("from crates/komorebi-core/src/workspace.rs"),
|
||||
"{text}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user