Skip to main content

fallow_core/discover/
mod.rs

1mod entry_points;
2mod infrastructure;
3mod parse_scripts;
4mod walk;
5
6// Re-export types from fallow-types
7pub use fallow_types::discover::{DiscoveredFile, EntryPoint, EntryPointSource, FileId};
8
9// Re-export public functions — preserves the existing `crate::discover::*` API
10pub use entry_points::{
11    CategorizedEntryPoints, compile_glob_set, discover_dynamically_loaded_entry_points,
12    discover_entry_points, discover_plugin_entry_point_sets, discover_plugin_entry_points,
13    discover_workspace_entry_points,
14};
15pub(crate) use entry_points::{
16    EntryPointDiscovery, discover_entry_points_with_warnings,
17    discover_workspace_entry_points_with_warnings, warn_skipped_entry_summary,
18};
19pub use infrastructure::discover_infrastructure_entry_points;
20pub use walk::{PRODUCTION_EXCLUDE_PATTERNS, SOURCE_EXTENSIONS, discover_files};
21
22/// Hidden (dot-prefixed) directories that should be included in file discovery.
23///
24/// Most hidden directories (`.git`, `.cache`, etc.) should be skipped, but certain
25/// convention directories contain source or config files that fallow needs to see:
26/// - `.storybook` — Storybook configuration (the Storybook plugin depends on this)
27/// - `.vitepress` — VitePress configuration and theme files
28/// - `.well-known` — Standard web convention directory
29/// - `.changeset` — Changesets configuration
30/// - `.github` — GitHub workflows and CI scripts
31const ALLOWED_HIDDEN_DIRS: &[&str] = &[
32    ".storybook",
33    ".vitepress",
34    ".well-known",
35    ".changeset",
36    ".github",
37];
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    // ── ALLOWED_HIDDEN_DIRS exhaustiveness ───────────────────────────
44
45    #[test]
46    fn allowed_hidden_dirs_count() {
47        // Guard: if a new dir is added, add a test for it
48        assert_eq!(
49            ALLOWED_HIDDEN_DIRS.len(),
50            5,
51            "update tests when adding new allowed hidden dirs"
52        );
53    }
54
55    #[test]
56    fn allowed_hidden_dirs_all_start_with_dot() {
57        for dir in ALLOWED_HIDDEN_DIRS {
58            assert!(
59                dir.starts_with('.'),
60                "allowed hidden dir '{dir}' must start with '.'"
61            );
62        }
63    }
64
65    #[test]
66    fn allowed_hidden_dirs_no_duplicates() {
67        let mut seen = rustc_hash::FxHashSet::default();
68        for dir in ALLOWED_HIDDEN_DIRS {
69            assert!(seen.insert(*dir), "duplicate allowed hidden dir: {dir}");
70        }
71    }
72
73    #[test]
74    fn allowed_hidden_dirs_no_trailing_slash() {
75        for dir in ALLOWED_HIDDEN_DIRS {
76            assert!(
77                !dir.ends_with('/'),
78                "allowed hidden dir '{dir}' should not have trailing slash"
79            );
80        }
81    }
82
83    // ── Re-export smoke tests ───────────────────────────────────────
84
85    #[test]
86    fn file_id_re_exported() {
87        // Verify the re-export works by constructing a FileId through the discover module
88        let id = FileId(42);
89        assert_eq!(id.0, 42);
90    }
91
92    #[test]
93    fn source_extensions_re_exported() {
94        assert!(SOURCE_EXTENSIONS.contains(&"ts"));
95        assert!(SOURCE_EXTENSIONS.contains(&"tsx"));
96    }
97
98    #[test]
99    fn compile_glob_set_re_exported() {
100        let result = compile_glob_set(&["**/*.ts".to_string()]);
101        assert!(result.is_some());
102    }
103}