diff options
| author | A Farzat <a@farzat.xyz> | 2026-06-20 14:41:13 +0300 |
|---|---|---|
| committer | A Farzat <a@farzat.xyz> | 2026-06-20 15:59:54 +0300 |
| commit | 4ec209d3863e913cffbe8c6e0a14a292820a2715 (patch) | |
| tree | aeb79461140bd2fb7266b7c0a1bc0fda7d378f56 /src/run.rs | |
| parent | 0b679b0b5d81ad8c5f61031ffe56b3f646ba9234 (diff) | |
| download | repo2markdown-4ec209d3863e913cffbe8c6e0a14a292820a2715.tar.gz repo2markdown-4ec209d3863e913cffbe8c6e0a14a292820a2715.zip | |
Move input parsing from md_generator to run
Diffstat (limited to 'src/run.rs')
| -rw-r--r-- | src/run.rs | 115 |
1 files changed, 110 insertions, 5 deletions
@@ -1,4 +1,9 @@ -use std::io::{Read, Write}; +use std::{ + ffi::OsStr, + io::{Read, Write}, + os::unix::ffi::OsStrExt, + path::Path, +}; use repo2markdown::{ fenced_md_generator::generate_fenced_markdown, logger::Logger, @@ -9,14 +14,22 @@ use crate::cli::Cli; pub fn run<R: Read, W: Write>( cli: &Cli, - input: R, + mut input: R, output: W, ) -> Result<(), Box<dyn std::error::Error>> { let logger = Logger::new(cli.verbosity()); + let mut input_buf = Vec::new(); + input.read_to_end(&mut input_buf)?; + let paths: Vec<&Path> = input_buf + .split(|b| *b == 0) + .filter(|bytes| !bytes.is_empty()) + .map(|bytes| Path::new(OsStr::from_bytes(bytes))) + .collect(); + if cli.fenced { generate_fenced_markdown( - input, + &paths, output, cli.render_options(), &cli.root, @@ -26,7 +39,7 @@ pub fn run<R: Read, W: Write>( ) } else { generate_markdown_from_paths( - input, + &paths, output, cli.render_options(), &cli.root, @@ -39,9 +52,10 @@ pub fn run<R: Read, W: Write>( #[cfg(test)] mod tests { - use std::io::Cursor; + use std::{fs, io::Cursor}; use clap::Parser; + use tempfile::tempdir; use crate::cli::Cli; @@ -74,4 +88,95 @@ mod tests { "```markdown\n# Project name\n```\n" ); } + + #[test] + fn run_reads_null_separated_paths_from_stdin() { + let temp_dir = tempdir().unwrap(); + fs::write(temp_dir.path().join("b.rs"), "B").unwrap(); + fs::write(temp_dir.path().join("a.rs"), "A").unwrap(); + + let cli = Cli::try_parse_from([ + "repo2markdown", + "--origin", + temp_dir.path().to_str().unwrap(), + "--root", + temp_dir.path().to_str().unwrap(), + "--name", + "Project name", + ]) + .unwrap(); + + let input = Cursor::new(b"a.rs\0b.rs\0"); + let mut output = Vec::new(); + + run(&cli, input, &mut output).unwrap(); + + let output = String::from_utf8(output).unwrap(); + + assert!(output.contains("## File: a.rs")); + assert!(output.contains("## File: b.rs")); + assert!(output.contains("```rust\nA\n```")); + assert!(output.contains("```rust\nB\n```")); + + let a_pos = output.find("a.rs").unwrap(); + let b_pos = output.find("b.rs").unwrap(); + assert!(a_pos < b_pos); + } + + #[test] + fn run_ignores_empty_path_segments() { + let temp_dir = tempdir().unwrap(); + + fs::write(temp_dir.path().join("a.rs"), "A").unwrap(); + + let cli = Cli::try_parse_from([ + "repo2markdown", + "--origin", + temp_dir.path().to_str().unwrap(), + "--root", + temp_dir.path().to_str().unwrap(), + "--name", + "Project name", + ]) + .unwrap(); + + let input = Cursor::new(b"\0a.rs\0\0"); + let mut output = Vec::new(); + + run(&cli, input, &mut output).unwrap(); + + let output = String::from_utf8(output).unwrap(); + + assert!(output.contains("## File: a.rs")); + assert!(output.contains("```rust\nA\n```")); + assert_eq!(output.matches("## File: a.rs").count(), 1); + } + + #[test] + fn run_accepts_final_path_without_trailing_nul() { + let temp_dir = tempdir().unwrap(); + + fs::write(temp_dir.path().join("a.rs"), "A").unwrap(); + + let cli = Cli::try_parse_from([ + "repo2markdown", + "--origin", + temp_dir.path().to_str().unwrap(), + "--root", + temp_dir.path().to_str().unwrap(), + "--name", + "Project name", + ]) + .unwrap(); + + let input = Cursor::new(b"a.rs"); + let mut output = Vec::new(); + + run(&cli, input, &mut output).unwrap(); + + let output = String::from_utf8(output).unwrap(); + + assert!(output.contains("## File: a.rs")); + assert!(output.contains("```rust\nA\n```")); + } } |
