Skip to content

Commit 7488bee

Browse files
authored
Merge pull request #2836 from itowlson/fix-watch-workdir-windows
Fix `watch` with workdir not working on Windows
2 parents 602a557 + 7c0e464 commit 7488bee

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

src/commands/watch/filters.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ fn create_source_globs(cid: &str, c: &v2::Component) -> Option<Vec<String>> {
125125
build
126126
.watch
127127
.iter()
128-
.filter_map(|w| Path::new(workdir).join(w).to_str().map(String::from))
128+
.map(|w| concatenate_glob_friendly(workdir, w))
129129
.collect()
130130
})
131131
.unwrap_or_else(|| build.watch.clone());
@@ -137,6 +137,20 @@ fn create_source_globs(cid: &str, c: &v2::Component) -> Option<Vec<String>> {
137137
}
138138
}
139139

140+
/// Using Path::join on Windows correctly joins with a backslash. But the watchexec glob
141+
/// engines hates backslashes. So we must always use forward slashes in glob expressions,
142+
/// and in workdirs, and for concatenating the two. (We could use Path::join on Unix but
143+
/// the signature ends up a bit different because to_str returns an Option, so...)
144+
fn concatenate_glob_friendly(workdir: &str, watch_glob: &str) -> String {
145+
if PathBuf::from(watch_glob).is_absolute() {
146+
watch_glob.to_string()
147+
} else if workdir.ends_with('/') {
148+
format!("{workdir}{watch_glob}")
149+
} else {
150+
format!("{workdir}/{watch_glob}")
151+
}
152+
}
153+
140154
#[async_trait]
141155
impl FilterFactory for ManifestFilterFactory {
142156
async fn build_filter(
@@ -207,3 +221,31 @@ impl watchexec::filter::Filterer for CompositeFilterer {
207221
Ok(false)
208222
}
209223
}
224+
225+
#[cfg(test)]
226+
mod tests {
227+
use super::*;
228+
229+
#[test]
230+
fn joining_workdir_always_uses_forward_slash() {
231+
assert_eq!(
232+
"work/src/**/*.rs",
233+
concatenate_glob_friendly("work", "src/**/*.rs")
234+
);
235+
assert_eq!(
236+
"work/src/**/*.rs",
237+
concatenate_glob_friendly("work/", "src/**/*.rs")
238+
);
239+
240+
#[cfg(not(target_os = "windows"))]
241+
assert_eq!(
242+
"/global/src/**/*.rs",
243+
concatenate_glob_friendly("work", "/global/src/**/*.rs")
244+
);
245+
#[cfg(target_os = "windows")]
246+
assert_eq!(
247+
"D:/global/src/**/*.rs",
248+
concatenate_glob_friendly("work", "D:/global/src/**/*.rs")
249+
);
250+
}
251+
}

0 commit comments

Comments
 (0)