Skip to content

Commit 43272f3

Browse files
committed
basic test for filesystem probing (#301)
1 parent a3714ef commit 43272f3

File tree

4 files changed

+42
-28
lines changed

4 files changed

+42
-28
lines changed

git-worktree/src/fs.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::path::Path;
2+
13
/// Common knowledge about the worktree that is needed across most interactions with the work tree
24
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
35
#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)]
@@ -20,45 +22,40 @@ pub struct Context {
2022
}
2123

2224
impl Context {
23-
/// try to determine all values in this context by probing them in the current working directory, which should be on the file system
24-
/// the git repository is located on.
25+
/// try to determine all values in this context by probing them in the given `directory`, which
26+
/// should be on the file system the git repository is located on.
2527
///
2628
/// All errors are ignored and interpreted on top of the default for the platform the binary is compiled for.
27-
pub fn from_probing_cwd() -> Self {
29+
pub fn probe(directory: impl AsRef<std::path::Path>) -> Self {
30+
let root = directory.as_ref();
2831
let ctx = Context::default();
2932
Context {
30-
symlink: Self::probe_symlink().unwrap_or(ctx.symlink),
33+
symlink: Self::probe_symlink(root).unwrap_or(ctx.symlink),
3134
..ctx
3235
}
3336
}
3437

35-
fn probe_symlink() -> Option<bool> {
36-
let src_path = "__link_src_file";
37-
std::fs::File::options()
38-
.create_new(true)
39-
.write(true)
40-
.open(src_path)
41-
.ok()?;
42-
let link_path = "__file_link";
43-
if symlink::symlink_file(src_path, link_path).is_err() {
44-
std::fs::remove_file(src_path).ok();
45-
return None;
38+
fn probe_symlink(root: &Path) -> std::io::Result<bool> {
39+
let src_path = root.join("__link_src_file");
40+
std::fs::File::options().create_new(true).write(true).open(&src_path)?;
41+
let link_path = root.join("__file_link");
42+
if symlink::symlink_file(&src_path, &link_path).is_err() {
43+
std::fs::remove_file(&src_path)?;
44+
return Ok(false);
4645
}
4746
let cleanup_all = || {
48-
std::fs::remove_file(src_path).ok();
49-
symlink::remove_symlink_file(link_path)
50-
.or_else(|_| std::fs::remove_file(link_path))
51-
.ok();
47+
let res = std::fs::remove_file(&src_path);
48+
symlink::remove_symlink_file(&link_path)
49+
.or_else(|_| std::fs::remove_file(&link_path))
50+
.and(res)
5251
};
5352

54-
let res = Some(
55-
std::fs::symlink_metadata(link_path)
56-
.map_err(|_| cleanup_all())
57-
.ok()?
58-
.is_symlink(),
59-
);
60-
cleanup_all();
61-
res
53+
let res = std::fs::symlink_metadata(&link_path)
54+
.or_else(|err| cleanup_all().and(Err(err)))?
55+
.is_symlink();
56+
57+
cleanup_all()?;
58+
Ok(res)
6259
}
6360
}
6461

git-worktree/tests/fs/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#[test]
2+
fn from_probing_cwd() {
3+
let dir = tempfile::tempdir().unwrap();
4+
let _ctx = git_worktree::fs::Context::probe(dir.path());
5+
let entries: Vec<_> = std::fs::read_dir(dir.path())
6+
.unwrap()
7+
.filter_map(Result::ok)
8+
.map(|e| e.path().to_owned())
9+
.collect();
10+
assert_eq!(
11+
entries.len(),
12+
0,
13+
"there should be no left-over files after probing, found {:?}",
14+
entries
15+
);
16+
}

git-worktree/tests/index/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ mod checkout {
1717
#[test]
1818
fn allow_symlinks() -> crate::Result {
1919
let opts = opts_with_symlink(true);
20-
if !git_worktree::fs::Context::from_probing_cwd().symlink {
20+
if !git_worktree::fs::Context::probe(std::env::current_dir()?).symlink {
2121
eprintln!("IGNORING symlink test on file system without symlink support");
2222
// skip if symlinks aren't supported anyway.
2323
return Ok(());

git-worktree/tests/worktree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::path::{Path, PathBuf};
22

3+
mod fs;
34
mod index;
45

56
type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>;

0 commit comments

Comments
 (0)