1use std::fs;
2
3pub mod cli;
4pub mod processor;
5pub mod walker;
6
7use cli::Args;
8
9pub fn run(args: Args) -> anyhow::Result<()> {
11 println!(
13 "Processing files in folder: {}",
14 args.input_folder.display()
15 );
16 if let Some(patterns) = &args.patterns {
17 println!("Using patterns: {}", patterns.join(", "));
18 } else {
19 println!("Using patterns: all files");
20 }
21 if let Some(exclude_folders) = &args.exclude_folders {
22 println!("Excluding folders: {}", exclude_folders.join(", "));
23 }
24 if let Some(exclude_extensions) = &args.exclude_extensions {
25 println!("Excluding extensions: {}", exclude_extensions.join(", "));
26 }
27
28 if args.clear_file && args.output_file.exists() {
30 fs::remove_file(&args.output_file)?;
31 println!(
32 "Output file {} has been cleared.",
33 args.output_file.display()
34 );
35 }
36
37 let receiver = walker::find_files(&args)?;
39
40 processor::process_files(receiver, &args.output_file)?;
42
43 println!(
44 "Files have been processed and written to {}",
45 args.output_file.display()
46 );
47
48 Ok(())
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::cli::Args;
55 use assert_fs::TempDir;
56 use assert_fs::prelude::*;
57 use std::fs::File;
58 use std::io::Read;
59 use std::path::Path;
60
61 fn get_test_args(input_folder: &Path, output_file: &Path) -> Args {
62 Args {
63 input_folder: input_folder.to_path_buf(),
64 output_file: output_file.to_path_buf(),
65 patterns: None,
66 clear_file: true,
67 exclude_folders: None,
68 exclude_extensions: None,
69 max_depth: None,
70 hidden: false,
71 no_follow: true,
72 }
73 }
74
75 #[test]
76 fn test_filter_by_multiple_patterns() -> anyhow::Result<()> {
77 let dir = TempDir::new()?;
78 let input_dir_path = dir.path();
79
80 dir.child("Cargo.toml").write_str("[package]")?;
81 dir.child("README.md").write_str("# Project")?;
82 let src_dir = dir.child("src");
83 src_dir.create_dir_all()?;
84 src_dir.child("main.rs").write_str("fn main(){}")?;
85
86 let output_file = input_dir_path.join("output.txt");
87 let mut args = get_test_args(input_dir_path, &output_file);
88 args.patterns = Some(vec!["*.rs".to_string(), "*.toml".to_string()]);
90
91 run(args)?;
92
93 let mut result = String::new();
94 File::open(&output_file)?.read_to_string(&mut result)?;
95
96 assert!(result.contains("main.rs"));
97 assert!(result.contains("Cargo.toml"));
98 assert!(!result.contains("README.md"));
99
100 Ok(())
101 }
102
103 #[test]
104 fn test_skip_binary_files() -> anyhow::Result<()> {
105 let dir = TempDir::new()?;
106 let input_dir_path = dir.path();
107
108 dir.child("text.txt").write_str("some text")?;
109 dir.child("binary.bin")
111 .write_binary(&[b'b', b'i', b'n', 0, b'a', b'r', b'y'])?;
112
113 let output_file = input_dir_path.join("output.txt");
114 let args = get_test_args(input_dir_path, &output_file);
115
116 run(args)?;
117
118 let mut result = String::new();
119 File::open(&output_file)?.read_to_string(&mut result)?;
120
121 assert!(result.contains("text.txt"));
122 assert!(!result.contains("binary.bin"));
123
124 Ok(())
125 }
126}