From e47a3a0a66efe0cfc54da39158de38b9e9afc35b Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 24 Aug 2025 13:35:36 +0200 Subject: [PATCH] feat: enhance configuration structure and improve documentation for bundling process --- src/lib.rs | 109 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f2199ad..4bea666 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,11 @@ use ignore::gitignore::Gitignore; use tracing::{error, info, warn}; use walkdir::{DirEntry, WalkDir}; +/// Represents the output format for the bundled files. +/// +/// - `Markdown`: Outputs files in Markdown format with code blocks. +/// - `Text`: Outputs files as plain text. +/// - `Console`: Outputs files formatted for console display (default). #[derive(Debug, Clone, ValueEnum, Default)] pub enum Format { Markdown, @@ -18,20 +23,38 @@ pub enum Format { Console, } +/// Configuration options for the file bundling process. #[derive(Debug)] pub struct Config { + /// The directory to process. pub directory: PathBuf, + /// The optional output file path. If not provided, output is written to stdout. pub output: Option, + /// File extensions to include in the output. pub include: Vec, + /// File extensions to exclude from the output. pub exclude: Vec, + /// The format of the output (Markdown, Text, or Console). pub format: Format, + /// Whether to append the current date to the output file name. pub append_date: bool, + /// Whether to append the current Git hash to the output file name. pub append_git_hash: bool, + /// Whether to include line numbers in the output. pub line_numbers: bool, + /// Whether to ignore hidden files and directories. pub ignore_hidden: bool, + /// Whether to respect `.gitignore` rules. pub respect_gitignore: bool, } +/// Runs the file bundling process based on the provided configuration. +/// +/// # Arguments +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `Result<()>` - Returns `Ok(())` if successful, or an error if the process fails. pub fn run(config: Config) -> Result<()> { let mut output_path = config.output.clone(); @@ -44,7 +67,14 @@ pub fn run(config: Config) -> Result<()> { process_directory(&config, writer) } -/// Appends date and git hash to the output file name if required. +/// Appends the current date and/or Git hash to the output file name if required. +/// +/// # Arguments +/// * `output_path` - The optional output file path to modify. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `Result<()>` - Returns `Ok(())` if successful, or an error if the operation fails. fn append_date_and_git_hash(output_path: &mut Option, config: &Config) -> Result<()> { if let Some(path) = output_path { let mut new_filename = path @@ -82,7 +112,13 @@ fn append_date_and_git_hash(output_path: &mut Option, config: &Config) Ok(()) } -/// Determines the output writer (file or stdout). +/// Determines the output writer (file or stdout) based on the configuration. +/// +/// # Arguments +/// * `output_path` - The optional output file path. +/// +/// # Returns +/// * `Result>` - Returns a writer for the output. fn determine_output_writer(output_path: &Option) -> Result> { if let Some(path) = output_path { info!("Output will be written to: {}", path.display()); @@ -95,7 +131,14 @@ fn determine_output_writer(output_path: &Option) -> Result` - Returns `Ok(())` if successful, or an error if the process fails. fn process_directory(config: &Config, mut writer: Box) -> Result<()> { let (gitignore, _) = Gitignore::new(config.directory.join(".gitignore")); @@ -121,12 +164,28 @@ fn process_directory(config: &Config, mut writer: Box) -> Result<()> Ok(()) } -/// Determines if a directory entry should be included. +/// Determines if a directory entry should be included based on the configuration. +/// +/// # Arguments +/// * `entry` - The directory entry to check. +/// * `gitignore` - The `.gitignore` rules to respect. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `bool` - Returns `true` if the entry should be included, `false` otherwise. fn should_include_entry(entry: &DirEntry, gitignore: &Gitignore, config: &Config) -> bool { !is_hidden(entry, config) && !is_ignored(entry, gitignore, config) } -/// Processes a single file entry. +/// Processes a single file entry and writes its content to the writer. +/// +/// # Arguments +/// * `entry` - The file entry to process. +/// * `writer` - The writer to output the file content. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `Result<()>` - Returns `Ok(())` if successful, or an error if the process fails. fn process_file_entry(entry: &DirEntry, writer: &mut dyn Write, config: &Config) -> Result<()> { let path = entry.path(); if !path.is_file() { @@ -159,6 +218,17 @@ fn process_file_entry(entry: &DirEntry, writer: &mut dyn Write, config: &Config) .with_context(|| format!("Failed to write file content for {}", path.display())) } +/// Writes the content of a single file to the writer based on the specified format. +/// +/// # Arguments +/// * `writer` - The writer to output the file content. +/// * `path` - The relative path of the file. +/// * `content` - The content of the file. +/// * `extension` - The file extension. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `Result<()>` - Returns `Ok(())` if successful, or an error if the operation fails. fn write_file_content( writer: &mut dyn Write, path: &Path, @@ -183,7 +253,15 @@ fn write_file_content( Ok(()) } -/// Helper to write content line by line, optionally with line numbers. +/// Writes content line by line to the writer, optionally including line numbers. +/// +/// # Arguments +/// * `writer` - The writer to output the content. +/// * `content` - The content to write. +/// * `line_numbers` - Whether to include line numbers. +/// +/// # Returns +/// * `Result<()>` - Returns `Ok(())` if successful, or an error if the operation fails. fn write_content_lines(writer: &mut dyn Write, content: &str, line_numbers: bool) -> Result<()> { if line_numbers { for (i, line) in content.lines().enumerate() { @@ -195,7 +273,14 @@ fn write_content_lines(writer: &mut dyn Write, content: &str, line_numbers: bool Ok(()) } -/// Helper function to check if a directory entry is hidden. +/// Checks if a directory entry is hidden based on the configuration. +/// +/// # Arguments +/// * `entry` - The directory entry to check. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `bool` - Returns `true` if the entry is hidden, `false` otherwise. fn is_hidden(entry: &DirEntry, config: &Config) -> bool { config.ignore_hidden && entry @@ -205,7 +290,15 @@ fn is_hidden(entry: &DirEntry, config: &Config) -> bool { .unwrap_or(false) } -/// Helper function to check if a directory entry is ignored by .gitignore. +/// Checks if a directory entry is ignored by `.gitignore` rules. +/// +/// # Arguments +/// * `entry` - The directory entry to check. +/// * `gitignore` - The `.gitignore` rules to respect. +/// * `config` - The configuration options for the bundling process. +/// +/// # Returns +/// * `bool` - Returns `true` if the entry is ignored, `false` otherwise. fn is_ignored(entry: &DirEntry, gitignore: &Gitignore, config: &Config) -> bool { if !config.respect_gitignore { return false;