diff options
Diffstat (limited to 'src/worktree.rs')
| -rw-r--r-- | src/worktree.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/worktree.rs b/src/worktree.rs index 72cdb3d2..17f560a4 100644 --- a/src/worktree.rs +++ b/src/worktree.rs @@ -495,6 +495,8 @@ pub(crate) fn list_existing_worktrees( repo_root: &Path, trust_repository: bool, ) -> Result<Vec<ExistingWorktree>, String> { + #[cfg(test)] + test_list_gate::wait(repo_root); let output = repository_git_command(repo_root, trust_repository) .args(["worktree", "list", "--porcelain"]) .output() @@ -513,6 +515,47 @@ pub(crate) fn list_existing_worktrees( }) } +#[cfg(test)] +pub(crate) mod test_list_gate { + use std::path::{Path, PathBuf}; + use std::sync::{mpsc, Mutex}; + + struct Gate { + path: PathBuf, + entered: mpsc::Sender<()>, + release: mpsc::Receiver<()>, + } + + static GATES: Mutex<Vec<Gate>> = Mutex::new(Vec::new()); + + pub(crate) fn block(path: &Path) -> (mpsc::Receiver<()>, mpsc::Sender<()>) { + let (entered, entry_rx) = mpsc::channel(); + let (release_tx, release) = mpsc::channel(); + GATES.lock().unwrap().push(Gate { + path: super::canonical_or_original(path), + entered, + release, + }); + (entry_rx, release_tx) + } + + pub(super) fn wait(path: &Path) { + let gate = { + let mut gates = GATES.lock().unwrap(); + gates + .iter() + .position(|gate| gate.path == super::canonical_or_original(path)) + .map(|index| gates.remove(index)) + }; + if let Some(gate) = gate { + gate.entered.send(()).unwrap(); + gate.release + .recv_timeout(std::time::Duration::from_secs(10)) + .expect("test must release worktree discovery without blocking the server loop"); + } + } +} + fn worktree_list_contains_path( repo_root: &Path, path: &Path, |
