1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
//! `ra_vfs_glob` crate implements exclusion rules for vfs.
//!
//! By default, we include only `.rs` files, and skip some know offenders like
//! `/target` or `/node_modules` altogether.
//!
//! It's also possible to add custom exclusion globs.
use globset::{GlobSet, GlobSetBuilder};
use ra_vfs::{Filter, RelativePath};
pub use globset::{Glob, GlobBuilder};
const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"];
const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"];
pub struct RustPackageFilterBuilder {
is_member: bool,
exclude: GlobSetBuilder,
}
impl Default for RustPackageFilterBuilder {
fn default() -> RustPackageFilterBuilder {
RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() }
}
}
impl RustPackageFilterBuilder {
pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder {
self.is_member = is_member;
self
}
pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder {
self.exclude.add(glob);
self
}
pub fn into_vfs_filter(self) -> Box<dyn Filter> {
let RustPackageFilterBuilder { is_member, mut exclude } = self;
for &glob in ALWAYS_IGNORED {
exclude.add(Glob::new(glob).unwrap());
}
if !is_member {
for &glob in IGNORED_FOR_NON_MEMBERS {
exclude.add(Glob::new(glob).unwrap());
}
}
Box::new(RustPackageFilter { exclude: exclude.build().unwrap() })
}
}
struct RustPackageFilter {
exclude: GlobSet,
}
impl Filter for RustPackageFilter {
fn include_dir(&self, dir_path: &RelativePath) -> bool {
!self.exclude.is_match(dir_path.as_str())
}
fn include_file(&self, file_path: &RelativePath) -> bool {
file_path.extension() == Some("rs")
}
}
#[test]
fn test_globs() {
let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter();
assert!(filter.include_dir(RelativePath::new("src/tests")));
assert!(filter.include_dir(RelativePath::new("src/target")));
assert!(filter.include_dir(RelativePath::new("tests")));
assert!(filter.include_dir(RelativePath::new("benches")));
assert!(!filter.include_dir(RelativePath::new("target")));
assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));
let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter();
assert!(filter.include_dir(RelativePath::new("src/tests")));
assert!(filter.include_dir(RelativePath::new("src/target")));
assert!(!filter.include_dir(RelativePath::new("target")));
assert!(!filter.include_dir(RelativePath::new("src/foo/.git")));
assert!(!filter.include_dir(RelativePath::new("foo/node_modules")));
assert!(!filter.include_dir(RelativePath::new("tests")));
assert!(!filter.include_dir(RelativePath::new("benches")));
let filter = RustPackageFilterBuilder::default()
.set_member(true)
.exclude(Glob::new("src/llvm-project/**").unwrap())
.into_vfs_filter();
assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang")));
}
|