mirror of
https://github.com/PR0M3TH3AN/Marlin.git
synced 2025-09-08 23:28:44 +00:00
Canonicalize test paths
This commit is contained in:
@@ -45,12 +45,18 @@ pub fn determine_scan_root(pattern: &str) -> PathBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Canonicalize a path, falling back to the original on error.
|
||||||
|
pub fn canonicalize_lossy<P: AsRef<Path>>(p: P) -> PathBuf {
|
||||||
|
std::fs::canonicalize(&p).unwrap_or_else(|_| p.as_ref().to_path_buf())
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert a filesystem path to a normalized database path.
|
/// Convert a filesystem path to a normalized database path.
|
||||||
///
|
///
|
||||||
/// On Windows this replaces backslashes with forward slashes so that paths
|
/// On Windows this replaces backslashes with forward slashes so that paths
|
||||||
/// stored in the database are consistent across platforms.
|
/// stored in the database are consistent across platforms.
|
||||||
pub fn to_db_path<P: AsRef<Path>>(p: P) -> String {
|
pub fn to_db_path<P: AsRef<Path>>(p: P) -> String {
|
||||||
let s = p.as_ref().to_string_lossy();
|
let canonical = canonicalize_lossy(p);
|
||||||
|
let s = canonical.to_string_lossy();
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
s.replace('\\', "/")
|
s.replace('\\', "/")
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
//! watcher can be paused, resumed and shut down cleanly.
|
//! watcher can be paused, resumed and shut down cleanly.
|
||||||
|
|
||||||
use crate::db::{self, Database};
|
use crate::db::{self, Database};
|
||||||
use crate::utils::to_db_path;
|
use crate::utils::{canonicalize_lossy, to_db_path};
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use crossbeam_channel::{bounded, Receiver};
|
use crossbeam_channel::{bounded, Receiver};
|
||||||
use notify::{
|
use notify::{
|
||||||
@@ -256,13 +256,20 @@ impl FileWatcher {
|
|||||||
// ── start actual OS watcher ───────────────────────────────────────────
|
// ── start actual OS watcher ───────────────────────────────────────────
|
||||||
let event_tx = tx.clone();
|
let event_tx = tx.clone();
|
||||||
let mut actual_watcher = RecommendedWatcher::new(
|
let mut actual_watcher = RecommendedWatcher::new(
|
||||||
move |ev| {
|
move |ev: Result<Event, notify::Error>| {
|
||||||
|
let ev = ev.map(|mut e| {
|
||||||
|
for p in &mut e.paths {
|
||||||
|
*p = canonicalize_lossy(&*p);
|
||||||
|
}
|
||||||
|
e
|
||||||
|
});
|
||||||
let _ = event_tx.send(ev);
|
let _ = event_tx.send(ev);
|
||||||
},
|
},
|
||||||
notify::Config::default(),
|
notify::Config::default(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for p in &paths {
|
let canonical_paths: Vec<PathBuf> = paths.iter().map(canonicalize_lossy).collect();
|
||||||
|
for p in &canonical_paths {
|
||||||
actual_watcher
|
actual_watcher
|
||||||
.watch(p, RecursiveMode::Recursive)
|
.watch(p, RecursiveMode::Recursive)
|
||||||
.with_context(|| format!("Failed to watch path {}", p.display()))?;
|
.with_context(|| format!("Failed to watch path {}", p.display()))?;
|
||||||
@@ -532,7 +539,7 @@ impl FileWatcher {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
state,
|
state,
|
||||||
_config: config,
|
_config: config,
|
||||||
watched_paths: paths,
|
watched_paths: canonical_paths,
|
||||||
_event_receiver: rx,
|
_event_receiver: rx,
|
||||||
_watcher: actual_watcher,
|
_watcher: actual_watcher,
|
||||||
processor_thread: Some(processor_thread),
|
processor_thread: Some(processor_thread),
|
||||||
|
@@ -25,12 +25,13 @@ mod tests {
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
) {
|
) {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
let target = std::fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf());
|
||||||
loop {
|
loop {
|
||||||
let count: i64 = marlin
|
let count: i64 = marlin
|
||||||
.conn()
|
.conn()
|
||||||
.query_row(
|
.query_row(
|
||||||
"SELECT COUNT(*) FROM files WHERE path = ?1",
|
"SELECT COUNT(*) FROM files WHERE path = ?1",
|
||||||
[to_db_path(path)],
|
[to_db_path(&target)],
|
||||||
|r| r.get(0),
|
|r| r.get(0),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -201,7 +202,8 @@ mod tests {
|
|||||||
thread::sleep(Duration::from_millis(100));
|
thread::sleep(Duration::from_millis(100));
|
||||||
let new_file = dir.join("b.txt");
|
let new_file = dir.join("b.txt");
|
||||||
fs::rename(&file, &new_file).unwrap();
|
fs::rename(&file, &new_file).unwrap();
|
||||||
wait_for_row_count(&marlin, &new_file, 1, Duration::from_secs(10));
|
let canon_new_file = std::fs::canonicalize(&new_file).unwrap_or(new_file.clone());
|
||||||
|
wait_for_row_count(&marlin, &canon_new_file, 1, Duration::from_secs(10));
|
||||||
watcher.stop().unwrap();
|
watcher.stop().unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
watcher.status().unwrap().events_processed > 0,
|
watcher.status().unwrap().events_processed > 0,
|
||||||
@@ -249,7 +251,8 @@ mod tests {
|
|||||||
fs::rename(&sub, &new).unwrap();
|
fs::rename(&sub, &new).unwrap();
|
||||||
for fname in ["one.txt", "two.txt"] {
|
for fname in ["one.txt", "two.txt"] {
|
||||||
let p = new.join(fname);
|
let p = new.join(fname);
|
||||||
wait_for_row_count(&marlin, &p, 1, Duration::from_secs(10));
|
let canon_p = std::fs::canonicalize(&p).unwrap_or(p.clone());
|
||||||
|
wait_for_row_count(&marlin, &canon_p, 1, Duration::from_secs(10));
|
||||||
}
|
}
|
||||||
watcher.stop().unwrap();
|
watcher.stop().unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
|
Reference in New Issue
Block a user