From 97b7d342f889cc04252134bf523951f1a04032be Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 12 Aug 2026 21:02:54 +0200 Subject: [PATCH] re-add `External` --- crates/oxide/src/scanner/mod.rs | 15 +++---- crates/oxide/src/scanner/sources.rs | 70 ++++++++++------------------- 2 files changed, 30 insertions(+), 55 deletions(-) diff --git a/crates/oxide/src/scanner/mod.rs b/crates/oxide/src/scanner/mod.rs index 93cd7a84e..de1cceca8 100644 --- a/crates/oxide/src/scanner/mod.rs +++ b/crates/oxide/src/scanner/mod.rs @@ -333,7 +333,7 @@ impl Scanner { let mut globs = vec![]; for source in self.sources.iter() { match source { - SourceEntry::Auto { base, .. } => { + SourceEntry::Auto { base } | SourceEntry::External { base } => { globs.extend(resolve_globs( base.to_path_buf(), &self.dirs, @@ -364,7 +364,7 @@ impl Scanner { self.sources .iter() .filter_map(|source| match source { - SourceEntry::Auto { base, .. } => Some(GlobEntry { + SourceEntry::Auto { base } | SourceEntry::External { base } => Some(GlobEntry { base: base.to_string_lossy().to_string(), pattern: "**/*".to_string(), }), @@ -779,7 +779,7 @@ fn create_walkers(sources: &Sources) -> Vec { /// - `Ignored` (`@source not`): its pattern at its base fn create_auto_walker(sources: &Sources) -> Option { let mut roots = sources.iter().filter_map(|source| match source { - SourceEntry::Auto { base, .. } => Some(base), + SourceEntry::Auto { base } | SourceEntry::External { base } => Some(base), _ => None, }); @@ -852,10 +852,7 @@ fn create_auto_walker(sources: &Sources) -> Option { // Setup ignores based on `@source` definitions, in directive order so later directives win for source in sources.iter() { match source { - SourceEntry::Auto { - base, - external: true, - } => { + SourceEntry::External { base } => { // External sources bypass all gitignore rules (the directory was explicitly // listed even though it is ignored)… let mut ignore_builder = GitignoreBuilder::new(base); @@ -904,7 +901,9 @@ fn create_auto_walker(sources: &Sources) -> Option { .iter() .enumerate() .filter_map(|(idx, source)| match source { - SourceEntry::Auto { base, .. } => Some((idx, base.clone())), + SourceEntry::Auto { base } | SourceEntry::External { base } => { + Some((idx, base.clone())) + } _ => None, }) .collect(); diff --git a/crates/oxide/src/scanner/sources.rs b/crates/oxide/src/scanner/sources.rs index 139e4ef24..ef717483d 100644 --- a/crates/oxide/src/scanner/sources.rs +++ b/crates/oxide/src/scanner/sources.rs @@ -28,9 +28,12 @@ pub enum SourceEntry { /// @source "src";` /// @source "src/**/*";` /// ``` + Auto { base: PathBuf }, + + /// An `Auto` source whose directory is itself ignored (by the default rules, e.g. + /// `node_modules`, or by a `.gitignore`) but was explicitly listed anyway. /// - /// `external` is set when the directory itself is ignored (by the default rules, e.g. - /// `node_modules`, or by a `.gitignore`) but was explicitly listed anyway: + /// Represented by: /// /// ```css /// @source "../node_modules/my-lib";` @@ -41,7 +44,7 @@ pub enum SourceEntry { /// as if it were a regular auto source, except that `.gitignore` files no longer apply /// inside (git ignores the whole tree anyway). The default rules still apply inside, so /// e.g. nested `node_modules` stay ignored. - Auto { base: PathBuf, external: bool }, + External { base: PathBuf }, /// Explicit source pattern regardless of any auto source detection rules /// @@ -347,10 +350,7 @@ mod tests { assert_eq!( sources, vec![ - SourceEntry::Auto { - base: base.clone(), - external: false, - }, + SourceEntry::Auto { base: base.clone() }, SourceEntry::Pattern { base: base.clone(), pattern: "/foo.html".to_string(), @@ -385,10 +385,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: false, - } + SourceEntry::Auto { base } ); } @@ -401,10 +398,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: true, - } + SourceEntry::External { base } ); } @@ -421,10 +415,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: true, - } + SourceEntry::External { base } ); } @@ -441,10 +432,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: true, - } + SourceEntry::External { base } ); } @@ -468,10 +456,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: false, - } + SourceEntry::Auto { base } ); } @@ -491,10 +476,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: true, - } + SourceEntry::External { base } ); } @@ -510,10 +492,7 @@ mod tests { assert_eq!( auto_source_entry(&base), - SourceEntry::Auto { - base, - external: false, - } + SourceEntry::Auto { base } ); } } @@ -582,11 +561,7 @@ pub fn public_source_entries_to_private_source_entries( let mut source: SourceEntry = public_source.into(); // Mark auto sources as external if their directory is gitignored - if let SourceEntry::Auto { - ref base, - external: false, - } = source - { + if let SourceEntry::Auto { ref base } = source { let inside_git_repo = base.ancestors().any(|dir| dir.join(".git").exists()); // The chain of directories whose `.gitignore` files can apply: `base` itself and @@ -642,10 +617,7 @@ pub fn public_source_entries_to_private_source_entries( match gitignore.matched(prefix, true) { ignore::Match::Ignore(_) => { - source = SourceEntry::Auto { - base: base.into(), - external: true, - }; + source = SourceEntry::External { base: base.into() }; break 'prefixes; } // Re-included; this directory is reachable, move on to the next one. @@ -703,9 +675,13 @@ impl From for SourceEntry { .ends_with(&format!("{}{}", std::path::MAIN_SEPARATOR, dir)) }); - SourceEntry::Auto { - base: value.base.into(), - external: inside_ignored_content_dir, + match inside_ignored_content_dir { + false => SourceEntry::Auto { + base: value.base.into(), + }, + true => SourceEntry::External { + base: value.base.into(), + }, } } }