diff options
| author | A Farzat <a@farzat.xyz> | 2026-06-06 14:25:12 +0300 |
|---|---|---|
| committer | A Farzat <a@farzat.xyz> | 2026-06-06 14:25:12 +0300 |
| commit | f7fa7f10fae59f7128317c0406b961f113c60dd3 (patch) | |
| tree | 97c83c13fd5a9e4a3ab6ab258433504d1e7ea2f7 | |
| parent | afc1765530e69cf40aac4b33e4c5e384b4702f22 (diff) | |
| download | repo2markdown-f7fa7f10fae59f7128317c0406b961f113c60dd3.tar.gz repo2markdown-f7fa7f10fae59f7128317c0406b961f113c60dd3.zip | |
Extend duplicate detection to non-adjacent paths
| -rw-r--r-- | src/main.rs | 34 |
1 files 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<R: Read, W: Write>( 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<R: Read, W: Write>( 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(()) } @@ -270,6 +270,28 @@ mod tests { } #[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(); let origin_base = temp_dir.path(); |
