Skip to content

Commit 7f263ba

Browse files
committed
sorting special characters
1 parent feb4b97 commit 7f263ba

File tree

3 files changed

+157
-3
lines changed

3 files changed

+157
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "codeowners"
3-
version = "0.2.2"
3+
version = "0.2.3"
44
edition = "2021"
55

66
[profile.release]

src/ownership/file_generator.rs

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::cmp::Ordering;
2+
13
use super::{Entry, Mapper};
24

35
pub struct FileGenerator {
@@ -41,7 +43,159 @@ impl FileGenerator {
4143

4244
fn to_sorted_lines(entries: &[Entry]) -> Vec<String> {
4345
let mut lines: Vec<String> = entries.iter().map(|entry| entry.to_row()).collect();
44-
lines.sort();
46+
lines.sort_by(|a, b| {
47+
if let Some((prefix, _)) = a.split_once("**") {
48+
if b.starts_with(prefix) {
49+
return Ordering::Less;
50+
}
51+
}
52+
if let Some((prefix, _)) = b.split_once("**") {
53+
if a.starts_with(prefix) {
54+
return Ordering::Greater;
55+
}
56+
}
57+
a.cmp(b)
58+
});
4559
lines
4660
}
4761
}
62+
63+
#[cfg(test)]
64+
mod tests {
65+
use super::*;
66+
67+
#[test]
68+
fn test_to_sorted_lines_with_special_characters() {
69+
// The `(` character is less than `*` in the default sort order.
70+
let mut illustrate_issue = vec!["*".to_string(), "(".to_string()];
71+
illustrate_issue.sort();
72+
assert_eq!(illustrate_issue, vec!["(".to_string(), "*".to_string()]);
73+
74+
let entries = vec![
75+
Entry {
76+
// Problem is when a dir name starts with `(`.
77+
path: "directory/owner/(my_folder)/**/**".to_string(),
78+
github_team: "@foo".to_string(),
79+
team_name: "footeam".to_string(),
80+
disabled: false,
81+
},
82+
Entry {
83+
// Another example of a dir starting with `(`.
84+
path: "directory/owner/(my_folder)/without_glob".to_string(),
85+
github_team: "@zoo".to_string(),
86+
team_name: "zooteam".to_string(),
87+
disabled: false,
88+
},
89+
Entry {
90+
// And is compared to a glob that starts with `*`.
91+
path: "directory/owner/**".to_string(),
92+
github_team: "@bar".to_string(),
93+
team_name: "barteam".to_string(),
94+
disabled: false,
95+
},
96+
Entry {
97+
path: "directory/owner/my_folder/**".to_string(),
98+
github_team: "@baz".to_string(),
99+
team_name: "bazteam".to_string(),
100+
disabled: false,
101+
},
102+
Entry {
103+
path: "directory/**".to_string(),
104+
github_team: "@bop".to_string(),
105+
team_name: "bopteam".to_string(),
106+
disabled: false,
107+
},
108+
];
109+
let sorted = FileGenerator::to_sorted_lines(&entries);
110+
assert_eq!(
111+
sorted,
112+
vec![
113+
"/directory/** @bop",
114+
"/directory/owner/** @bar",
115+
"/directory/owner/(my_folder)/**/** @foo",
116+
"/directory/owner/(my_folder)/without_glob @zoo",
117+
"/directory/owner/my_folder/** @baz"
118+
]
119+
);
120+
}
121+
122+
#[test]
123+
fn test_basic_sorting() {
124+
let entries = vec![
125+
Entry {
126+
path: "b_directory/owner/**".to_string(),
127+
github_team: "@bar".to_string(),
128+
team_name: "barteam".to_string(),
129+
disabled: false,
130+
},
131+
Entry {
132+
path: "a_directory/owner/**".to_string(),
133+
github_team: "@foo".to_string(),
134+
team_name: "footeam".to_string(),
135+
disabled: false,
136+
},
137+
];
138+
let sorted = FileGenerator::to_sorted_lines(&entries);
139+
assert_eq!(sorted, vec!["/a_directory/owner/** @foo", "/b_directory/owner/** @bar"]);
140+
}
141+
142+
#[test]
143+
fn test_sorting_with_mixed_case() {
144+
let entries = vec![
145+
Entry {
146+
path: "directory/Owner/**".to_string(),
147+
github_team: "@bar".to_string(),
148+
team_name: "barteam".to_string(),
149+
disabled: false,
150+
},
151+
Entry {
152+
path: "directory/owner/**".to_string(),
153+
github_team: "@foo".to_string(),
154+
team_name: "footeam".to_string(),
155+
disabled: false,
156+
},
157+
];
158+
let sorted = FileGenerator::to_sorted_lines(&entries);
159+
assert_eq!(sorted, vec!["/directory/Owner/** @bar", "/directory/owner/** @foo"]);
160+
}
161+
162+
#[test]
163+
fn test_sorting_with_numbers() {
164+
let entries = vec![
165+
Entry {
166+
path: "directory/owner1/**".to_string(),
167+
github_team: "@foo".to_string(),
168+
team_name: "footeam".to_string(),
169+
disabled: false,
170+
},
171+
Entry {
172+
path: "directory/owner2/**".to_string(),
173+
github_team: "@bar".to_string(),
174+
team_name: "barteam".to_string(),
175+
disabled: false,
176+
},
177+
];
178+
let sorted = FileGenerator::to_sorted_lines(&entries);
179+
assert_eq!(sorted, vec!["/directory/owner1/** @foo", "/directory/owner2/** @bar"]);
180+
}
181+
182+
#[test]
183+
fn test_sorting_with_special_characters() {
184+
let entries = vec![
185+
Entry {
186+
path: "directory/owner-1/**".to_string(),
187+
github_team: "@foo".to_string(),
188+
team_name: "footeam".to_string(),
189+
disabled: false,
190+
},
191+
Entry {
192+
path: "directory/owner_2/**".to_string(),
193+
github_team: "@bar".to_string(),
194+
team_name: "barteam".to_string(),
195+
disabled: false,
196+
},
197+
];
198+
let sorted = FileGenerator::to_sorted_lines(&entries);
199+
assert_eq!(sorted, vec!["/directory/owner-1/** @foo", "/directory/owner_2/** @bar"]);
200+
}
201+
}

0 commit comments

Comments
 (0)