Skip to content

Commit 189bb8f

Browse files
authored
Informative for-file error message (#33)
* introducing source enum * removing redundant postfix * friendly for-file error message
1 parent 8a13cff commit 189bb8f

12 files changed

+253
-191
lines changed

src/common_test.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,27 @@ team_file_glob:
286286
}
287287
)
288288
}
289+
290+
pub fn vecs_match<T: PartialEq + std::fmt::Debug>(a: &Vec<T>, b: &Vec<T>) {
291+
// First check lengths match
292+
assert_eq!(a.len(), b.len(), "Vectors have different lengths");
293+
294+
// Check each element in a exists in b
295+
for elem_a in a {
296+
assert!(
297+
b.contains(elem_a),
298+
"Element {:?} from first vector not found in second vector",
299+
elem_a
300+
);
301+
}
302+
303+
// Check each element in b exists in a
304+
for elem_b in b {
305+
assert!(
306+
a.contains(elem_b),
307+
"Element {:?} from second vector not found in first vector",
308+
elem_b
309+
);
310+
}
311+
}
289312
}

src/ownership.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use file_owner_finder::FileOwnerFinder;
2-
use mapper::{OwnerMatcher, TeamName};
2+
use mapper::{OwnerMatcher, Source, TeamName};
33
use std::{
44
fmt::{self, Display},
55
path::Path,
@@ -9,7 +9,7 @@ use tracing::{info, instrument};
99

1010
mod file_generator;
1111
mod file_owner_finder;
12-
mod mapper;
12+
pub(crate) mod mapper;
1313
mod validator;
1414

1515
use crate::{ownership::mapper::DirectoryMapper, project::Project};
@@ -29,11 +29,22 @@ pub struct Ownership {
2929
pub struct FileOwner {
3030
pub team_name: TeamName,
3131
pub team_config_file_path: String,
32+
pub sources: Vec<Source>,
3233
}
3334

3435
impl Display for FileOwner {
3536
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36-
write!(f, "Team: {}\nTeam YML: {}", self.team_name, self.team_config_file_path)
37+
let sources = self
38+
.sources
39+
.iter()
40+
.map(|source| source.to_string())
41+
.collect::<Vec<String>>()
42+
.join(", ");
43+
write!(
44+
f,
45+
"Team: {}\nTeam YML: {}\nSource(s): {}",
46+
self.team_name, self.team_config_file_path, sources
47+
)
3748
}
3849
}
3950

@@ -42,6 +53,7 @@ impl Default for FileOwner {
4253
Self {
4354
team_name: "Unowned".to_string(),
4455
team_config_file_path: "Unowned".to_string(),
56+
sources: vec![],
4557
}
4658
}
4759
}
@@ -102,6 +114,7 @@ impl Ownership {
102114
.path
103115
.strip_prefix(&self.project.base_path)
104116
.map_or_else(|_| String::new(), |p| p.to_string_lossy().to_string()),
117+
sources: owner.sources.clone(),
105118
},
106119
None => FileOwner::default(),
107120
})

src/ownership/file_owner_finder.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{collections::HashMap, path::Path};
22

3-
use super::mapper::{directory_mapper::is_directory_mapper_source, OwnerMatcher, Source, TeamName};
3+
use super::mapper::{OwnerMatcher, Source, TeamName};
44

55
#[derive(Debug)]
66
pub struct Owner {
@@ -21,10 +21,13 @@ impl<'a> FileOwnerFinder<'a> {
2121
let (owner, source) = owner_matcher.owner_for(relative_path);
2222

2323
if let Some(team_name) = owner {
24-
if is_directory_mapper_source(source) {
25-
directory_overrider.process(team_name, source);
26-
} else {
27-
team_sources_map.entry(team_name).or_default().push(source.clone());
24+
match source {
25+
Source::Directory(_) => {
26+
directory_overrider.process(team_name, source);
27+
}
28+
_ => {
29+
team_sources_map.entry(team_name).or_default().push(source.clone());
30+
}
2831
}
2932
}
3033
}
@@ -74,20 +77,20 @@ mod tests {
7477
let mut directory_overrider = DirectoryOverrider::default();
7578
assert_eq!(directory_overrider.specific_directory_owner(), None);
7679
let team_name_1 = "team1".to_string();
77-
let source_1 = "src/**".to_string();
80+
let source_1 = Source::Directory("src/**".to_string());
7881
directory_overrider.process(&team_name_1, &source_1);
7982
assert_eq!(directory_overrider.specific_directory_owner(), Some((&team_name_1, &source_1)));
8083

8184
let team_name_longest = "team2".to_string();
82-
let source_longest = "source/subdir/**".to_string();
85+
let source_longest = Source::Directory("source/subdir/**".to_string());
8386
directory_overrider.process(&team_name_longest, &source_longest);
8487
assert_eq!(
8588
directory_overrider.specific_directory_owner(),
8689
Some((&team_name_longest, &source_longest))
8790
);
8891

8992
let team_name_3 = "team3".to_string();
90-
let source_3 = "source/**".to_string();
93+
let source_3 = Source::Directory("source/**".to_string());
9194
directory_overrider.process(&team_name_3, &source_3);
9295
assert_eq!(
9396
directory_overrider.specific_directory_owner(),

src/ownership/mapper.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use glob_match::glob_match;
22
use std::{
33
collections::HashMap,
4+
fmt::{self, Display},
45
path::{Path, PathBuf},
56
};
67

@@ -27,7 +28,38 @@ pub trait Mapper {
2728
fn owner_matchers(&self) -> Vec<OwnerMatcher>;
2829
}
2930
pub type TeamName = String;
30-
pub type Source = String;
31+
32+
#[derive(Debug, PartialEq, Clone)]
33+
pub enum Source {
34+
Directory(String),
35+
TeamFile,
36+
TeamGem,
37+
TeamGlob,
38+
Package(String, String),
39+
TeamYml,
40+
}
41+
42+
impl Display for Source {
43+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44+
match self {
45+
Source::Directory(path) => write!(f, "DirectoryMapper({})", path),
46+
Source::TeamFile => write!(f, "TeamFileMapper"),
47+
Source::TeamGem => write!(f, "TeamGemMapper"),
48+
Source::TeamGlob => write!(f, "TeamGlobMapper"),
49+
Source::Package(file_type, path) => write!(f, "PackageMapper({}, glob: {})", file_type, path),
50+
Source::TeamYml => write!(f, "TeamYmlMapper"),
51+
}
52+
}
53+
}
54+
55+
impl Source {
56+
pub fn len(&self) -> usize {
57+
match self {
58+
Source::Directory(path) => path.matches('/').count(),
59+
_ => 0,
60+
}
61+
}
62+
}
3163

3264
#[derive(Debug, PartialEq)]
3365
pub enum OwnerMatcher {
@@ -55,7 +87,7 @@ mod tests {
5587
use super::*;
5688

5789
fn assert_owner_for(glob: &str, relative_path: &str, expect_match: bool) {
58-
let source = "directory_mapper (\"packs/bam\")".to_string();
90+
let source = Source::Directory("packs/bam".to_string());
5991
let team_name = "team1".to_string();
6092
let owner_matcher = OwnerMatcher::Glob {
6193
glob: glob.to_string(),
@@ -96,4 +128,17 @@ mod tests {
96128
true,
97129
);
98130
}
131+
132+
#[test]
133+
fn display_source() {
134+
assert_eq!(Source::Directory("packs/bam".to_string()).to_string(), "DirectoryMapper(packs/bam)");
135+
assert_eq!(Source::TeamFile.to_string(), "TeamFileMapper");
136+
assert_eq!(Source::TeamGem.to_string(), "TeamGemMapper");
137+
assert_eq!(Source::TeamGlob.to_string(), "TeamGlobMapper");
138+
assert_eq!(
139+
Source::Package("Ruby".to_string(), "packs/bam/**/**".to_string()).to_string(),
140+
"PackageMapper(Ruby, glob: packs/bam/**/**)"
141+
);
142+
assert_eq!(Source::TeamYml.to_string(), "TeamYmlMapper");
143+
}
99144
}

0 commit comments

Comments
 (0)