From 69bad0b7ba9995c6e63c1138ab3a972b229d8540 Mon Sep 17 00:00:00 2001 From: specCon18 Date: Thu, 30 May 2024 13:29:57 -0400 Subject: [PATCH] added md table support --- src/main.rs | 170 ++++++++++++++++++++++------------------------------ test_out.md | 5 ++ 2 files changed, 77 insertions(+), 98 deletions(-) create mode 100644 test_out.md diff --git a/src/main.rs b/src/main.rs index e9b8e97..05539f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,59 +1,3 @@ -//! This module provides functionality to parse file trees for TODO comments. -//! -//! This tool traverses a directory of files, searching for substrings of "//TODO:" and -//! outputs all instances in a parsable format. -//! -//! # Example -//! -//! ``` -//! use clap::Parser; -//! use std::{io, fs, path::PathBuf}; -//! -//! #[derive(Parser)] -//! #[command(name = "YUNODO")] -//! #[command(version = "0.3.0")] -//! #[command(about = "parse file tree for //TODO: comments", long_about = "parses a directory of files for substrings of //TODO: and outputs all instances in a parsable format")] -//! struct Cli { -//! /// Sets a custom config file -//! #[arg(short, long, value_name = "PATH")] -//! path: Option, -//! #[arg(short, long, value_name = "DEBUG")] -//! debug: Option, -//! } -//! -//! /// Reads files in a given directory and its subdirectories. -//! /// -//! /// # Arguments -//! /// -//! /// * `dir_path` - A string slice representing the path to the directory. -//! /// -//! /// # Returns -//! /// -//! /// A Result containing a vector of tuples where each tuple contains the filename and -//! /// a vector of lines in the file, or an io::Error if an error occurs during file I/O. -//! fn read_files_in_directory(dir_path: &str) -> io::Result)>> { -//! // Function implementation... -//! } -//! -//! fn main() { -//! let cli = Cli::parse(); -//! if let Some(path) = cli.path.as_deref() { -//! let path_string = path.display().to_string(); -//! let mut output_csv_item: String = String::new(); -//! match read_files_in_directory(&path_string.as_str()) { -//! Ok(files_content) => { -//! for (filename, lines) in files_content { -//! // Iterating through lines in each file... -//! } -//! } -//! Err(err) => { -//! eprintln!("Error: {}", err); -//! } -//! } -//! println!("{}", output_csv_item) -//! } -//! } -//! ``` use clap::Parser; use std::{io, fs, path::PathBuf}; //TODO: implement mod file_tree :ODOT// @@ -69,39 +13,6 @@ struct Cli { debug: Option, } -/// Reads files in a given directory and its subdirectories. -/// -/// # Arguments -/// -/// * `dir_path` - A string slice representing the path to the directory. -/// -/// # Returns -/// -/// A Result containing a vector of tuples where each tuple contains the filename and -/// a vector of lines in the file, or an io::Error if an error occurs during file I/O. -fn read_files_in_directory(dir_path: &str) -> io::Result)>> { - let mut files_content = Vec::new(); - let paths = fs::read_dir(dir_path)?; - - for path in paths { - let entry = path?; - let path = entry.path(); - if path.is_file() { - // If the entry is a file, read its content - let filename = path.file_name().unwrap().to_string_lossy().into_owned(); - let content = fs::read_to_string(&path)?; - let lines: Vec = content.lines().map(|s| s.to_string()).collect(); - files_content.push((filename, lines)); - } else if path.is_dir() { - // If the entry is a directory, recursively call the function to read its content - let subdir_path = path.to_string_lossy().into_owned(); - let subdir_content = read_files_in_directory(&subdir_path)?; - files_content.extend(subdir_content); - } - } - - Ok(files_content) -} fn main() { let cli = Cli::parse(); if let Some(path) = cli.path.as_deref() { @@ -150,8 +61,13 @@ fn main() { if let Some(end_index) = last_part.find(":ODOT//") { let extracted = &last_part[..end_index]; // Format output CSV item - //TODO:Call format_csv fn:ODOT// - format_csv(output_csv_item, path_string,&filename, line_number, extracted.to_string()); + if !output_csv_item.is_empty(){ + //OUTPUT_CSV_TO_APPEND, PATH, FILENAME, LINE_NUMBER, EXTRACTED_COMMENT + output_csv_item = format!("{},{},{},{},{}", output_csv_item, path_string, filename, line_number + 1, extracted); + } else { + //PATH, FILENAME, LINE_NUMBER, EXTRACTED_COMMENT + output_csv_item = format!("{},{},{},{}",path_string, filename, line_number + 1, extracted); + } } } } @@ -162,13 +78,71 @@ fn main() { eprintln!("Error: {}", err); } } - println!("{}",output_csv_item) + out_as_md_table(output_csv_item); } } -fn format_csv(output:String,path:String,filename:&String,line_number:usize,comment:String){ - if !output.is_empty(){ - output = format!("{},path:\"{}\",file_name:\"{}\",line_number:\"{}\",comment:\"{}\"", output, path, filename, line_number + 1, comment); - } else { - output = format!("path:\"{}\",file_name:\"{}\",line_number:\"{}\",comment:\"{}\"",path, filename, line_number + 1, comment); - } + +/// Reads files in a given directory and its subdirectories. +/// +/// # Arguments +/// +/// * `dir_path` - A string slice representing the path to the directory. +/// +/// # Returns +/// +/// A Result containing a vector of tuples where each tuple contains the filename and +/// a vector of lines in the file, or an io::Error if an error occurs during file I/O. +fn read_files_in_directory(dir_path: &str) -> io::Result)>> { + let mut files_content = Vec::new(); + let paths = fs::read_dir(dir_path)?; + + for path in paths { + let entry = path?; + let path = entry.path(); + if path.is_file() { + // If the entry is a file, read its content + let filename = path.file_name().unwrap().to_string_lossy().into_owned(); + let content = fs::read_to_string(&path)?; + let lines: Vec = content.lines().map(|s| s.to_string()).collect(); + files_content.push((filename, lines)); + } else if path.is_dir() { + // If the entry is a directory, recursively call the function to read its content + let subdir_path = path.to_string_lossy().into_owned(); + let subdir_content = read_files_in_directory(&subdir_path)?; + files_content.extend(subdir_content); + } + } + + Ok(files_content) +} +fn out_as_md_table(input_csv:String){ + //TODO: iterate the input_csv and split into vec @ comma then pop vec backfilling table appending formatted values to new vec to be iterated and displayed :ODOT// + let mut split_input: Vec<&str> = input_csv.split(',').collect(); + //Formatting Values + let headers = String::from("| File Path | File Name | Line Number | Comment |"); + let divider = String::from("|:----------|:---------:|:-----------:|:--------|"); + + //Output Vector + let mut table:Vec = Vec::new(); + table.push(headers); + table.push(divider); + split_and_print(&mut split_input, &mut table); + for line in table { + println!("{}",line); + } +} +fn split_and_print(vec: &mut Vec<&str>,table: &mut Vec) { + if vec.is_empty() { + return; + } + + let mut vec2 = vec.split_off(4); + let comment = vec.pop(); + let line = vec.pop(); + let name = vec.pop(); + let path = vec.pop(); + let spacer = '|'; + let formatted_row = format!("{} {} {} {} {} {} {} {} {}",spacer,path.unwrap(),spacer,name.unwrap(),spacer,line.unwrap(),spacer,comment.unwrap(),spacer); + table.push(formatted_row); + split_and_print(&mut vec2, table); } diff --git a/test_out.md b/test_out.md new file mode 100644 index 0000000..8687b3e --- /dev/null +++ b/test_out.md @@ -0,0 +1,5 @@ +| File Path | File Name | Line Number | Comment | +|:----------|:---------:|:-----------:|:--------| +| ./src/ | main.rs | 3 | implement mod file_tree | +| ./src/ | main.rs | 119 | iterate the input_csv and split into vec @ comma then pop vec backfilling table appending formatted values to new vec to be iterated and displayed | +| ./src/ | file_tree.rs | 5 | make sha384 digest |