Enhance slugification process and deduplication logic

- Updated the `slugify_name` function to strip trailing spaces and dots before checking for Windows reserved names, ensuring correct handling of inputs like "CON.".
- Added tests to validate the new slugification behavior, particularly for Windows reserved names with trailing characters.
- Refactored `syncback_dir_no_meta` to pre-seed `taken_names` from old children's slugified instance names, improving deduplication against existing siblings regardless of iteration order.
This commit is contained in:
Joe 2026-02-10 04:10:00 -06:00
parent 41264a5ac0
commit 9688224cb4
2 changed files with 44 additions and 10 deletions

View file

@ -243,6 +243,13 @@ pub fn slugify_name(name: &str) -> String {
}
}
// Strip trailing spaces and dots (invalid on Windows) BEFORE the
// reserved-name check so that inputs like "CON." or "CON " are
// reduced to "CON" and then correctly caught below.
while result.ends_with(' ') || result.ends_with('.') {
result.pop();
}
// Handle Windows reserved names by appending an underscore
let result_lower = result.to_lowercase();
for forbidden in INVALID_WINDOWS_NAMES {
@ -252,11 +259,6 @@ pub fn slugify_name(name: &str) -> String {
}
}
// Strip trailing spaces and dots (invalid on Windows)
while result.ends_with(' ') || result.ends_with('.') {
result.pop();
}
// If the result is empty or all underscores, use a fallback
if result.is_empty() || result.chars().all(|c| c == '_') {
result = "instance".to_string();
@ -381,6 +383,21 @@ mod tests {
assert_eq!(slugify_name("nul"), "nul_");
}
#[test]
fn slugify_windows_reserved_with_trailing_dots_and_spaces() {
// Trailing dots/spaces must be stripped BEFORE the reserved name
// check, otherwise "CON." bypasses the check and becomes "CON".
assert_eq!(slugify_name("CON."), "CON_");
assert_eq!(slugify_name("CON "), "CON_");
assert_eq!(slugify_name("CON.."), "CON_");
assert_eq!(slugify_name("CON. "), "CON_");
assert_eq!(slugify_name("PRN."), "PRN_");
assert_eq!(slugify_name("AUX "), "AUX_");
assert_eq!(slugify_name("nul."), "nul_");
assert_eq!(slugify_name("com1."), "com1_");
assert_eq!(slugify_name("LPT1 "), "LPT1_");
}
#[test]
fn slugify_trailing_dot() {
// Trailing dots are stripped (invalid on Windows)