Skip to content

Commit 9dc66e4

Browse files
committed
Fix exclusions in build.watch getting applied to all components
Signed-off-by: itowlson <[email protected]>
1 parent 13a133f commit 9dc66e4

File tree

1 file changed

+57
-40
lines changed

1 file changed

+57
-40
lines changed

src/commands/watch/filters.rs

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use anyhow::Context;
77
use async_trait::async_trait;
88
use spin_common::ui::quoted_path;
99
use spin_manifest::schema::v2;
10+
use watchexec::filter::Filterer;
1011

1112
#[async_trait]
1213
pub(crate) trait FilterFactory: Send + Sync {
@@ -15,7 +16,7 @@ pub(crate) trait FilterFactory: Send + Sync {
1516
manifest_file: &Path,
1617
manifest_dir: &Path,
1718
manifest: &v2::AppManifest,
18-
) -> anyhow::Result<Arc<watchexec_filterer_globset::GlobsetFilterer>>;
19+
) -> anyhow::Result<Arc<dyn Filterer>>;
1920
}
2021

2122
pub(crate) struct ArtifactFilterFactory {
@@ -33,7 +34,7 @@ impl FilterFactory for ArtifactFilterFactory {
3334
manifest_file: &Path,
3435
manifest_dir: &Path,
3536
manifest: &v2::AppManifest,
36-
) -> anyhow::Result<Arc<watchexec_filterer_globset::GlobsetFilterer>> {
37+
) -> anyhow::Result<Arc<dyn Filterer>> {
3738
let manifest_glob = if self.skip_build {
3839
vec![manifest_path_to_watch(manifest_file)?]
3940
} else {
@@ -63,17 +64,9 @@ impl FilterFactory for ArtifactFilterFactory {
6364
.into_iter()
6465
.chain(wasm_globs)
6566
.chain(asset_globs)
66-
.map(|s| (s, None))
6767
.collect::<Vec<_>>();
6868

69-
let filterer = watchexec_filterer_globset::GlobsetFilterer::new(
70-
manifest_dir,
71-
artifact_globs,
72-
standard_ignores(),
73-
[],
74-
[],
75-
)
76-
.await?;
69+
let filterer = globset_filter(manifest_dir, artifact_globs).await?;
7770

7871
Ok(Arc::new(filterer))
7972
}
@@ -95,28 +88,22 @@ impl FilterFactory for BuildFilterFactory {
9588
manifest_file: &Path,
9689
manifest_dir: &Path,
9790
manifest: &v2::AppManifest,
98-
) -> anyhow::Result<Arc<watchexec_filterer_globset::GlobsetFilterer>> {
99-
let manifest_glob = vec![manifest_path_to_watch(manifest_file)?];
100-
let src_globs = manifest
101-
.components
102-
.iter()
103-
.flat_map(|(cid, c)| create_source_globs(cid.as_ref(), c))
104-
.collect::<Vec<_>>();
91+
) -> anyhow::Result<Arc<dyn Filterer>> {
92+
let mut filterers: Vec<Box<dyn Filterer>> =
93+
Vec::with_capacity(manifest.components.len() + 1);
10594

106-
let build_globs = manifest_glob
107-
.into_iter()
108-
.chain(src_globs)
109-
.map(|s| (s, None))
110-
.collect::<Vec<_>>();
95+
let manifest_globs = vec![manifest_path_to_watch(manifest_file)?];
96+
let manifest_filterer = globset_filter(manifest_dir, manifest_globs).await?;
11197

112-
let filterer = watchexec_filterer_globset::GlobsetFilterer::new(
113-
manifest_dir,
114-
build_globs,
115-
standard_ignores(),
116-
[],
117-
[],
118-
)
119-
.await?;
98+
filterers.push(Box::new(manifest_filterer));
99+
100+
for (cid, c) in &manifest.components {
101+
let build_globs = create_source_globs(cid.as_ref(), c);
102+
let build_filterer = globset_filter(manifest_dir, build_globs).await?;
103+
filterers.push(Box::new(build_filterer));
104+
}
105+
106+
let filterer = CompositeFilterer { filterers };
120107

121108
Ok(Arc::new(filterer))
122109
}
@@ -152,22 +139,31 @@ impl FilterFactory for ManifestFilterFactory {
152139
manifest_file: &Path,
153140
manifest_dir: &Path,
154141
_: &v2::AppManifest,
155-
) -> anyhow::Result<Arc<watchexec_filterer_globset::GlobsetFilterer>> {
142+
) -> anyhow::Result<Arc<dyn Filterer>> {
156143
let manifest_glob = manifest_path_to_watch(manifest_file)?;
157144

158-
let filterer = watchexec_filterer_globset::GlobsetFilterer::new(
159-
manifest_dir,
160-
vec![(manifest_glob, None)],
161-
standard_ignores(),
162-
[],
163-
[],
164-
)
165-
.await?;
145+
let filterer = globset_filter(manifest_dir, [manifest_glob]).await?;
166146

167147
Ok(Arc::new(filterer))
168148
}
169149
}
170150

151+
async fn globset_filter(
152+
manifest_dir: &Path,
153+
globs: impl IntoIterator<Item = String>,
154+
) -> anyhow::Result<watchexec_filterer_globset::GlobsetFilterer> {
155+
let filterer = watchexec_filterer_globset::GlobsetFilterer::new(
156+
manifest_dir,
157+
globs.into_iter().map(|s| (s, None)),
158+
standard_ignores(),
159+
[],
160+
[],
161+
)
162+
.await?;
163+
164+
Ok(filterer)
165+
}
166+
171167
// Although manifest dir must be absolute, and most things are safer with abs
172168
// file paths, the manifest _path_ for the watchers must be relative to manifest dir
173169
fn manifest_path_to_watch(path: &Path) -> anyhow::Result<String> {
@@ -185,3 +181,24 @@ fn standard_ignores() -> Vec<(String, Option<PathBuf>)> {
185181
.map(|pat| (pat.to_owned(), None))
186182
.collect()
187183
}
184+
185+
#[derive(Debug)]
186+
struct CompositeFilterer {
187+
filterers: Vec<Box<dyn watchexec::filter::Filterer>>,
188+
}
189+
190+
impl watchexec::filter::Filterer for CompositeFilterer {
191+
fn check_event(
192+
&self,
193+
event: &watchexec::event::Event,
194+
priority: watchexec::event::Priority,
195+
) -> Result<bool, watchexec::error::RuntimeError> {
196+
// We are interested in a change if _any_ component is interested in it
197+
for f in &self.filterers {
198+
if f.check_event(event, priority)? {
199+
return Ok(true);
200+
}
201+
}
202+
Ok(false)
203+
}
204+
}

0 commit comments

Comments
 (0)