Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ jobs:
- name: unit tests
run: cargo test --all --lib

- name: doc tests
run: cargo test --all --doc

integration-tests:
strategy:
matrix:
Expand Down
22 changes: 6 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ edition = "2024"

[dependencies]
dirs = "6.0.0"
rand = "0.9.1"
rand = "0.9.2"
serde = { version = "1.0.103", features = ["derive"] }
serde-saphyr = "0.0.6"
serde-saphyr = "0.0.7"

[dev-dependencies]
serde_test = "1.0.177"
[dev-dependencies]
16 changes: 7 additions & 9 deletions common/src/project_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,28 @@ pub fn homedir() -> Option<PathBuf> {
/// Return the temp dir as the users home dir during testing.
#[cfg(any(test, doctest))]
pub fn homedir() -> Option<PathBuf> {
Some(PathBuf::from("/tmp"))
Some(std::env::temp_dir())
}

#[cfg(test)]
mod test {
use super::*;
use std::env::temp_dir;

#[test]
fn expects_tmp_as_default_homedir() {
let args: Args = Default::default();
let project_paths = ProjectPaths::try_from(&args).unwrap();

assert_eq!(project_paths.home_directory, PathBuf::from("/tmp"))
assert_eq!(project_paths.home_directory, temp_dir())
}

#[test]
fn expects_muxed_as_default_project_dir() {
let args: Args = Default::default();
let project_paths = ProjectPaths::try_from(&args).unwrap();

assert_eq!(
project_paths.project_directory,
PathBuf::from("/tmp/.muxed")
)
assert_eq!(project_paths.project_directory, temp_dir().join(".muxed"))
}

#[test]
Expand All @@ -154,7 +152,7 @@ mod test {

assert_eq!(
project_paths.template_file,
PathBuf::from("/tmp/.muxed/.template.yml")
temp_dir().join(".muxed/.template.yml")
)
}

Expand All @@ -179,7 +177,7 @@ mod test {

assert_eq!(
project_paths.project_file,
PathBuf::from("/tmp/.muxed/projectname.yml")
temp_dir().join(".muxed/projectname.yml")
)
}

Expand All @@ -193,7 +191,7 @@ mod test {

assert_eq!(
project_paths.template_file,
PathBuf::from("/tmp/.muxed/custom_template.yml")
temp_dir().join(".muxed/custom_template.yml")
)
}
}
9 changes: 8 additions & 1 deletion common/src/rand_names.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::project_paths::CONFIG_EXTENSION;
use rand::random;
use std::env::temp_dir;
use std::path::PathBuf;

pub fn project_path_name() -> String {
format!("/tmp/.muxed-test-{}/", random::<u16>())
let tmp = std::env::temp_dir().join(format!(".muxed-test-{}", random::<u16>()));
tmp.to_str().unwrap().to_string()
}

pub fn template_path_name() -> String {
Expand Down Expand Up @@ -37,3 +39,8 @@ pub fn project_file_with_dir(dir: &str) -> PathBuf {
let project_file = PathBuf::from(project_file_name()).with_extension(CONFIG_EXTENSION);
PathBuf::from(dir).join(project_file)
}

pub fn project_file_in_tmp_dir() -> PathBuf {
let project_file = PathBuf::from(project_file_name()).with_extension(CONFIG_EXTENSION);
temp_dir().join(project_file)
}
4 changes: 2 additions & 2 deletions common/src/tmux/pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ impl<'de> Deserialize<'de> for Pane {
/// # Examples (YAML)
///
/// As a string:
/// ```
/// ```yaml
/// "htop"
/// ```
///
/// As a map:
/// ```
/// ```yaml
/// active: true
/// command: ls
/// path: /tmp
Expand Down
3 changes: 3 additions & 0 deletions common/src/tmux/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ pub enum NodeMut<'a> {
window_index: usize,
pane_index: usize,
pane: &'a mut Pane,
window_path: Option<PathBuf>,
},
}

Expand Down Expand Up @@ -167,6 +168,7 @@ impl<'a> Iterator for SessionIterMut<'a> {

// currently iterating panes
if let Some(pane_idx) = self.pane_index {
let window_path = session.windows[self.window_index].path.clone();
let num_panes = session.windows[self.window_index].panes.len();

if pane_idx < num_panes {
Expand All @@ -176,6 +178,7 @@ impl<'a> Iterator for SessionIterMut<'a> {
window_index: self.window_index,
pane_index: pane_idx,
pane,
window_path,
});
} else {
// finished panes for this window
Expand Down
15 changes: 12 additions & 3 deletions common/src/tmux/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,25 @@ use serde::Deserialize;
///
/// # Examples
/// Creating targets for different granularities:
/// ```
/// ```rust
/// use common::tmux::Target;
///
/// let session = Target::new("mysession", None, None); // "mysession"
/// let window = Target::new("mysession", Some(2), None); // "mysession:2"
/// let pane = Target::new("mysession", Some(2), Some(1)); // "mysession:2.1"
/// ```
///
/// You can also extend a session-only target to include window or pane:
/// ```
/// ```rust
/// use common::tmux::Target;
///
/// let t = Target::new("s", None, None);
/// let t = t.extend(1)?; // Now session "s", window 1
/// let t = t.extend(1).unwrap(); // Now session "s", window 1
/// assert_eq!(t.combined, "s:1");
///
/// let t = t.extend(2).unwrap(); // Now session "s", window 1, pane 2
/// assert_eq!(t.combined, "s:1.2");
///
/// ```
#[derive(Debug, Deserialize, Clone)]
pub struct Target {
Expand Down
2 changes: 1 addition & 1 deletion common/src/tmux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<'de> Deserialize<'de> for Window {
/// - An object with fields `layout`, `panes`, `active`, `path`, and/or `command`
///
/// Examples of supported YAML representations:
/// ```
/// ```yaml
/// # As a string:
/// windows: [vim]
///
Expand Down
4 changes: 2 additions & 2 deletions load/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ common = { path = "../common" }
dirs = "6.0.0"
libc = "0.2.66"
yaml-rust = { version = "0.4.5", default-features = false }
serde-saphyr = "0.0.6"
serde-saphyr = "0.0.7"

[dev-dependencies]
rand = "0.9.1"
rand = "0.9.2"
snapshot = { path = "../snapshot" }
retry_test = { path = "../retry_test" }
65 changes: 64 additions & 1 deletion load/src/interpreter/enrichment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn enrich(session: &mut Session, project_name: String, daemonize: bool, conf
match node {
NodeMut::Pane {
window_index,
window_path,
pane_index,
pane,
} => {
Expand All @@ -53,7 +54,10 @@ pub fn enrich(session: &mut Session, project_name: String, daemonize: bool, conf

pane.path = match pane.path.as_ref() {
Some(path) => expand_path(path),
None => root.clone(),
None => match window_path.as_ref() {
Some(path) => expand_path(path),
None => root.clone(),
},
};

pane.target = Some(Target::new(
Expand Down Expand Up @@ -299,6 +303,65 @@ mod test {
assert_eq!(sess.root, orig.root);
}

#[test]
fn pane_path_inherits_from_window_if_none() {
// Session with root, one window, two panes
// Only window.path is set
let window_path = PathBuf::from("/tmp/from-window");
let mut sess = Session {
name: None,
windows: vec![Window {
name: "w".to_string(),
panes: vec![
Pane {
path: None,
..Default::default()
}, // will inherit from window
Pane {
path: None,
..Default::default()
}, // will inherit from window
],
path: Some(window_path.clone()),
..Default::default()
}],
root: Some(PathBuf::from("/tmp/not-used")),
..Default::default()
};

enrich(&mut sess, "proj".into(), false, Config::default());

for pane in sess.windows[0].panes.iter() {
assert_eq!(pane.path, Some(window_path.clone()));
}
}

#[test]
fn pane_path_inherits_from_root_if_pane_and_window_none() {
// Session with root, but window.path and pane.path are None
let root_path = PathBuf::from("/tmp/fallback-root");
let mut sess = Session {
name: None,
windows: vec![Window {
name: "w".to_string(),
panes: vec![
Pane {
path: None,
..Default::default()
}, // will inherit from root
],
path: None,
..Default::default()
}],
root: Some(root_path.clone()),
..Default::default()
};

enrich(&mut sess, "demo".into(), false, Config::default());

assert_eq!(sess.windows[0].panes[0].path, Some(root_path));
}

#[cfg(test)]
mod expand_path_tests {
use super::*;
Expand Down
3 changes: 2 additions & 1 deletion load/src/interpreter/to_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ impl ToCommand for common::tmux::Window {

if ctx.first {
commands.push(
crate::command::Session::new(session_name, &self.name, self.path.clone()).into(),
crate::command::Session::new(session_name, &self.name, ctx.session.root.clone())
.into(),
);
} else {
commands.push(Window::new(&self.name, target.clone(), self.path.clone()).into());
Expand Down
Loading
Loading