diff options
author | Aleksey Kladov <[email protected]> | 2019-08-06 12:00:37 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-08-06 13:28:31 +0100 |
commit | 34203256bf8f8ea12b233e0fb49b42bd8c423281 (patch) | |
tree | 79ac51baa1696e06955ced637b6132c6a4eabf48 /crates/ra_vfs_glob/src | |
parent | c9718691043b041f5db878caea687b5a029d4475 (diff) |
introduce ra_vfs_glob crate
It manages exclusion rules for the vfs crate
Diffstat (limited to 'crates/ra_vfs_glob/src')
-rw-r--r-- | crates/ra_vfs_glob/src/lib.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/crates/ra_vfs_glob/src/lib.rs b/crates/ra_vfs_glob/src/lib.rs new file mode 100644 index 000000000..3e54da5fe --- /dev/null +++ b/crates/ra_vfs_glob/src/lib.rs | |||
@@ -0,0 +1,93 @@ | |||
1 | //! `ra_vfs_glob` crate implements exclusion rules for vfs. | ||
2 | //! | ||
3 | //! By default, we include only `.rs` files, and skip some know offenders like | ||
4 | //! `/target` or `/node_modules` altogether. | ||
5 | //! | ||
6 | //! It's also possible to add custom exclusion globs. | ||
7 | |||
8 | use globset::{Glob, GlobSet, GlobSetBuilder}; | ||
9 | use ra_vfs::{Filter, RelativePath}; | ||
10 | |||
11 | const ALWAYS_IGNORED: &[&str] = &["target/**", "**/node_modules/**", "**/.git/**"]; | ||
12 | const IGNORED_FOR_NON_MEMBERS: &[&str] = &["examples/**", "tests/**", "benches/**"]; | ||
13 | |||
14 | pub struct RustPackageFilterBuilder { | ||
15 | is_member: bool, | ||
16 | exclude: GlobSetBuilder, | ||
17 | } | ||
18 | |||
19 | impl Default for RustPackageFilterBuilder { | ||
20 | fn default() -> RustPackageFilterBuilder { | ||
21 | RustPackageFilterBuilder { is_member: false, exclude: GlobSetBuilder::new() } | ||
22 | } | ||
23 | } | ||
24 | |||
25 | impl RustPackageFilterBuilder { | ||
26 | pub fn set_member(mut self, is_member: bool) -> RustPackageFilterBuilder { | ||
27 | self.is_member = is_member; | ||
28 | self | ||
29 | } | ||
30 | pub fn exclude(mut self, glob: &str) -> Result<RustPackageFilterBuilder, globset::Error> { | ||
31 | self.exclude.add(Glob::new(glob)?); | ||
32 | Ok(self) | ||
33 | } | ||
34 | pub fn into_vfs_filter(self) -> Box<dyn Filter> { | ||
35 | let RustPackageFilterBuilder { is_member, mut exclude } = self; | ||
36 | for &glob in ALWAYS_IGNORED { | ||
37 | exclude.add(Glob::new(glob).unwrap()); | ||
38 | } | ||
39 | if !is_member { | ||
40 | for &glob in IGNORED_FOR_NON_MEMBERS { | ||
41 | exclude.add(Glob::new(glob).unwrap()); | ||
42 | } | ||
43 | } | ||
44 | Box::new(RustPackageFilter { exclude: exclude.build().unwrap() }) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | struct RustPackageFilter { | ||
49 | exclude: GlobSet, | ||
50 | } | ||
51 | |||
52 | impl Filter for RustPackageFilter { | ||
53 | fn include_dir(&self, dir_path: &RelativePath) -> bool { | ||
54 | !self.exclude.is_match(dir_path.as_str()) | ||
55 | } | ||
56 | |||
57 | fn include_file(&self, file_path: &RelativePath) -> bool { | ||
58 | file_path.extension() == Some("rs") | ||
59 | } | ||
60 | } | ||
61 | |||
62 | #[test] | ||
63 | fn test_globs() { | ||
64 | let filter = RustPackageFilterBuilder::default().set_member(true).into_vfs_filter(); | ||
65 | |||
66 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
67 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
68 | assert!(filter.include_dir(RelativePath::new("tests"))); | ||
69 | assert!(filter.include_dir(RelativePath::new("benches"))); | ||
70 | |||
71 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
72 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
73 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
74 | |||
75 | let filter = RustPackageFilterBuilder::default().set_member(false).into_vfs_filter(); | ||
76 | |||
77 | assert!(filter.include_dir(RelativePath::new("src/tests"))); | ||
78 | assert!(filter.include_dir(RelativePath::new("src/target"))); | ||
79 | |||
80 | assert!(!filter.include_dir(RelativePath::new("target"))); | ||
81 | assert!(!filter.include_dir(RelativePath::new("src/foo/.git"))); | ||
82 | assert!(!filter.include_dir(RelativePath::new("foo/node_modules"))); | ||
83 | assert!(!filter.include_dir(RelativePath::new("tests"))); | ||
84 | assert!(!filter.include_dir(RelativePath::new("benches"))); | ||
85 | |||
86 | let filter = RustPackageFilterBuilder::default() | ||
87 | .set_member(true) | ||
88 | .exclude("src/llvm-project/**") | ||
89 | .unwrap() | ||
90 | .into_vfs_filter(); | ||
91 | |||
92 | assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); | ||
93 | } | ||