aboutsummaryrefslogtreecommitdiffstats
path: root/xtask/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-07-27 18:24:37 +0200
committerGitHub <noreply@github.com>2026-07-27 18:24:37 +0200
commitea07e2d5b6bbc9ea6f9c765b0838b3e91156a58d (patch)
tree4a8fac8a9b27f2a8b32b3af61a3b5419b9937c81 /xtask/src
parentSwitch from the unmaintained daemonize crate to a maintained fork (#4512) (diff)
downloadsl0ppij-ea07e2d5b6bbc9ea6f9c765b0838b3e91156a58d.tar.gz
sl0ppij-ea07e2d5b6bbc9ea6f9c765b0838b3e91156a58d.tar.xz
sl0ppij-ea07e2d5b6bbc9ea6f9c765b0838b3e91156a58d.zip
Nested session handling (#5417)
* fix: theme query and updated pixel dimensions * add no-ui-fullscreen key/action/capability * protocol core * integration test harness * fix integration tests * fix flaky tests * nested ui (dimming) and directional focus initial implementation * integration tests for nested ui dimming and directional focus * initial full screen nesteed implementation * fix: keep hidden floating panes hidden across nested no-ui fullscreen * fix integration tests * no ui fullscreen integration tests * hardening behavior/tests * fix(nested): re-derive descend/dim on host tab switch and new-tab so clicking dimmed chrome ascends * initial modal implementation * initial ui improvements * fix integration tests * improve nested selection ui * nested session modal refactoring and tests * improve integration test speed somewhat * some ui adjustments * simplify full/auto nested session handling * hints in compact-bar * guest stdin leak fix * allow floating panes to be fullscreen * make nested session handling configurable * protocol reannounce * refactor: naming confusion * improve ux somewhat * rustfmt * merge fixes * improve integration test rate limiting (fix ci) * add pr
Diffstat (limited to 'xtask/src')
-rw-r--r--xtask/src/build.rs163
-rw-r--r--xtask/src/integration_test.rs2
2 files changed, 116 insertions, 49 deletions
diff --git a/xtask/src/build.rs b/xtask/src/build.rs
index d2469b59..210b8e4b 100644
--- a/xtask/src/build.rs
+++ b/xtask/src/build.rs
@@ -45,30 +45,14 @@ pub fn build(sh: &Shell, flags: flags::Build) -> anyhow::Result<()> {
crate::status(msg);
eprintln!("{}", msg);
- let mut base_cmd = cmd!(sh, "{cargo} build --target wasm32-wasip1");
- if flags.release {
- base_cmd = base_cmd.arg("--release");
- }
- for member in &plugin_members {
- let plugin_name = member
- .crate_name
- .rsplit_once('/')
- .context("Cannot determine plugin name from crate path")?
- .1;
- base_cmd = base_cmd.args(["-p", plugin_name]);
- }
- base_cmd.run().context("failed to build plugins")?;
-
if flags.release {
+ build_plugins_release_into_assets(sh, &plugin_members)?;
+ } else {
+ let mut base_cmd = cmd!(sh, "{cargo} build --target wasm32-wasip1");
for member in &plugin_members {
- let plugin_name = member
- .crate_name
- .rsplit_once('/')
- .context("Cannot determine plugin name from crate path")?
- .1;
- move_plugin_to_assets(sh, plugin_name)?;
+ base_cmd = base_cmd.args(["-p", plugin_name_of(member)?]);
}
- } else {
+ base_cmd.run().context("failed to build plugins")?;
write_plugin_stamp(sh);
}
}
@@ -126,40 +110,30 @@ fn plugins_force() -> bool {
std::env::var_os("ZELLIJ_FORCE_PLUGINS").is_some()
}
-fn plugin_stamp_path() -> PathBuf {
- PathBuf::from(
- std::env::var_os("CARGO_TARGET_DIR")
- .unwrap_or(crate::project_root().join("target").into_os_string()),
- )
- .join(".xtask-plugins-stamp")
-}
-
-fn write_plugin_stamp(sh: &Shell) {
- let _ = sh.write_file(plugin_stamp_path(), b"");
+fn plugin_asset_path(plugin_name: &str) -> PathBuf {
+ crate::asset_dir()
+ .join("plugins")
+ .join(plugin_name)
+ .with_extension("wasm")
}
-fn plugin_sources_changed() -> bool {
- let stamp_time = match std::fs::metadata(plugin_stamp_path()).and_then(|m| m.modified()) {
- Ok(stamp_time) => stamp_time,
- Err(_) => return true,
- };
+fn newest_plugin_source_time() -> Option<std::time::SystemTime> {
let root = crate::project_root();
["default-plugins", "zellij-tile", "zellij-tile-utils"]
.iter()
- .any(|dir| dir_changed_since(&root.join(dir), stamp_time))
+ .filter_map(|dir| newest_file_time(&root.join(dir)))
+ .max()
}
-fn dir_changed_since(dir: &Path, since: std::time::SystemTime) -> bool {
- let entries = match std::fs::read_dir(dir) {
- Ok(entries) => entries,
- Err(_) => return false,
- };
+fn newest_file_time(dir: &Path) -> Option<std::time::SystemTime> {
+ let entries = std::fs::read_dir(dir).ok()?;
+ let mut newest: Option<std::time::SystemTime> = None;
for entry in entries.flatten() {
+ let path = entry.path();
let file_type = match entry.file_type() {
Ok(file_type) => file_type,
Err(_) => continue,
};
- let path = entry.path();
if file_type.is_dir() {
if path
.file_name()
@@ -168,16 +142,102 @@ fn dir_changed_since(dir: &Path, since: std::time::SystemTime) -> bool {
{
continue;
}
- if dir_changed_since(&path, since) {
- return true;
+ if let Some(child) = newest_file_time(&path) {
+ newest = Some(newest.map_or(child, |current| current.max(child)));
}
} else if let Ok(modified) = entry.metadata().and_then(|m| m.modified()) {
- if modified > since {
- return true;
- }
+ newest = Some(newest.map_or(modified, |current| current.max(modified)));
}
}
- false
+ newest
+}
+
+pub fn ensure_plugin_assets(sh: &Shell) -> anyhow::Result<()> {
+ let plugin_members: Vec<&WorkspaceMember> = crate::workspace_members()
+ .iter()
+ .filter(|m| m.build && m.crate_name.contains("plugins"))
+ .collect();
+ if plugin_members.is_empty() {
+ return Ok(());
+ }
+
+ let newest_source = newest_plugin_source_time();
+ let stale = plugins_force()
+ || plugin_members.iter().any(|member| {
+ let plugin_name = match member.crate_name.rsplit_once('/') {
+ Some((_, name)) => name,
+ None => return true,
+ };
+ let asset_time = std::fs::metadata(plugin_asset_path(plugin_name))
+ .and_then(|m| m.modified())
+ .ok();
+ match (asset_time, newest_source) {
+ (Some(asset_time), Some(newest_source)) => asset_time < newest_source,
+ _ => true,
+ }
+ });
+
+ if !stale {
+ let msg = ">> Plugin assets up to date, skipping plugin build";
+ crate::status(msg);
+ eprintln!("{}", msg);
+ return Ok(());
+ }
+
+ let msg = ">> Building plugin assets (release)";
+ crate::status(msg);
+ eprintln!("{}", msg);
+
+ build_plugins_release_into_assets(sh, &plugin_members)
+}
+
+fn build_plugins_release_into_assets(
+ sh: &Shell,
+ plugin_members: &[&WorkspaceMember],
+) -> anyhow::Result<()> {
+ let cargo = crate::cargo()?;
+ let mut base_cmd = cmd!(sh, "{cargo} build --target wasm32-wasip1 --release");
+ for member in plugin_members {
+ let plugin_name = plugin_name_of(member)?;
+ base_cmd = base_cmd.args(["-p", plugin_name]);
+ }
+ base_cmd.run().context("failed to build plugin assets")?;
+
+ for member in plugin_members {
+ move_plugin_to_assets(sh, plugin_name_of(member)?)?;
+ }
+ Ok(())
+}
+
+fn plugin_name_of(member: &WorkspaceMember) -> anyhow::Result<&'static str> {
+ Ok(member
+ .crate_name
+ .rsplit_once('/')
+ .context("Cannot determine plugin name from crate path")?
+ .1)
+}
+
+fn plugin_stamp_path() -> PathBuf {
+ PathBuf::from(
+ std::env::var_os("CARGO_TARGET_DIR")
+ .unwrap_or(crate::project_root().join("target").into_os_string()),
+ )
+ .join(".xtask-plugins-stamp")
+}
+
+fn write_plugin_stamp(sh: &Shell) {
+ let _ = sh.write_file(plugin_stamp_path(), b"");
+}
+
+fn plugin_sources_changed() -> bool {
+ let stamp_time = match std::fs::metadata(plugin_stamp_path()).and_then(|m| m.modified()) {
+ Ok(stamp_time) => stamp_time,
+ Err(_) => return true,
+ };
+ match newest_plugin_source_time() {
+ Some(newest_source) => newest_source > stamp_time,
+ None => true,
+ }
}
pub fn proto(sh: &Shell) -> anyhow::Result<()> {
@@ -205,6 +265,11 @@ fn run_proto_codegen(sh: &Shell, force: bool) {
"src/web_server_contract",
"generated_web_server_api.rs",
),
+ (
+ "assets/prost_nested_session",
+ "src/nested_session_contract",
+ "generated_nested_session_api.rs",
+ ),
];
for (out_subdir, src_subdir, include_file) in specs {
diff --git a/xtask/src/integration_test.rs b/xtask/src/integration_test.rs
index 88eb1154..077ed53d 100644
--- a/xtask/src/integration_test.rs
+++ b/xtask/src/integration_test.rs
@@ -12,6 +12,8 @@ pub fn integration_test(sh: &Shell, flags: flags::IntegrationTest) -> anyhow::Re
crate::status(msg);
println!("{}", msg);
+ crate::build::ensure_plugin_assets(sh).context(err_context)?;
+
let profile = if flags.no_opt { "dev" } else { "dev-opt" };
let nextest_available = cmd!(sh, "{cargo} nextest --version")