From f7fa7f10fae59f7128317c0406b961f113c60dd3 Mon Sep 17 00:00:00 2001 From: A Farzat Date: Sat, 6 Jun 2026 14:25:12 +0300 Subject: Extend duplicate detection to non-adjacent paths --- src/main.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index bf687c6..7455e23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,10 @@ use std::{ + collections::HashSet, env, ffi::OsStr, io::{self, Read, Write}, os::unix::ffi::OsStrExt, - path::{Path, PathBuf}, + path::Path, }; use repo2markdown::{ @@ -74,7 +75,7 @@ pub fn run( let project_name = project_name.unwrap_or_else(|| derive_project_name(root)); renderer.render_header(project_name)?; - let mut last_rendered_path = PathBuf::from(""); + let mut seen_paths = HashSet::new(); for segment in buf.split(|b| *b == 0) { if segment.is_empty() { continue; @@ -82,15 +83,14 @@ pub fn run( let path = Path::new(OsStr::from_bytes(segment)); let normalized_path = normalizer.normalize(path)?; - if normalized_path.relative == last_rendered_path { + if !seen_paths.insert(normalized_path.relative.clone()) { logger.warn(format!( "Duplicate file detected: {:?}", normalized_path.relative )); - } else { - renderer.render_path(&normalized_path)?; - last_rendered_path = normalized_path.relative; + continue; } + renderer.render_path(&normalized_path)?; } Ok(()) } @@ -269,6 +269,28 @@ mod tests { assert_eq!(output.matches("## File: a.rs").count(), 1); } + #[test] + fn duplicate_files_are_skipped_with_preserved_display_order_even_if_not_adjacent() { + let temp_dir = tempdir().unwrap(); + let origin = temp_dir.path(); + let root = temp_dir.path(); + + fs::write(origin.join("a.rs"), "A").unwrap(); + fs::write(origin.join("b.rs"), "B").unwrap(); + + let input = Cursor::new(b"a.rs\0b.rs\0a.rs\0"); + let mut output = Vec::new(); + + run_with_default_logger(input, &mut output, root, origin, None).unwrap(); + + let output = String::from_utf8(output).unwrap(); + assert_eq!(output.matches("## File: a.rs").count(), 1); + assert_eq!(output.matches("## File: b.rs").count(), 1); + let a_pos = output.find("a.rs").unwrap(); + let b_pos = output.find("b.rs").unwrap(); + assert!(a_pos < b_pos); + } + #[test] fn project_name_is_derived_from_root_by_default_even_if_directory_does_not_exist() { let temp_dir = tempdir().unwrap(); -- cgit v1.3.1