From 806b23c8f4e0e804315cd766f493b5d424acaffa Mon Sep 17 00:00:00 2001 From: Abdulla Abdurakhmanov Date: Sun, 1 Sep 2024 11:47:24 +0200 Subject: [PATCH] --save-json-results support --- src/args.rs | 7 +++++++ src/commands/copy_command.rs | 23 ++++++++++++++++++++++- src/main.rs | 19 ++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/args.rs b/src/args.rs index b18fd1e..294f049 100644 --- a/src/args.rs +++ b/src/args.rs @@ -6,6 +6,7 @@ use crate::redacters::{ }; use clap::*; use std::fmt::Display; +use std::path::PathBuf; use url::Url; #[derive(Parser, Debug)] @@ -51,6 +52,12 @@ pub enum CliCommand { #[arg(long, help = "Override media type detection using glob patterns such as 'text/plain=*.md'", value_parser = CliCommand::parse_key_val::)] mime_override: Vec<(mime::Mime, globset::Glob)>, + + #[arg( + long, + help = "Save redacted results in JSON format to the specified file" + )] + save_json_results: Option, }, #[command(about = "List files in the source")] Ls { diff --git a/src/commands/copy_command.rs b/src/commands/copy_command.rs index f04724f..09eb12f 100644 --- a/src/commands/copy_command.rs +++ b/src/commands/copy_command.rs @@ -11,11 +11,14 @@ use console::{pad_str, Alignment, Style, Term}; use futures::Stream; use gcloud_sdk::prost::bytes; use indicatif::*; +use serde::Serialize; use std::error::Error; use std::time::{Duration, Instant}; +#[derive(Debug, Clone, Serialize)] pub struct CopyCommandResult { pub files_copied: usize, + pub files_redacted: usize, pub files_skipped: usize, } @@ -121,6 +124,7 @@ pub async fn command_copy( bar.set_length(files_found as u64); let mut total_files_copied = 0; + let mut total_files_redacted = 0; let mut total_files_skipped = source_files_result.skipped; for source_file in source_files { match transfer_and_redact_file( @@ -137,11 +141,16 @@ pub async fn command_copy( .await? { TransferFileResult::Copied => total_files_copied += 1, + TransferFileResult::RedactedAndCopied => { + total_files_redacted += 1; + total_files_copied += 1; + } TransferFileResult::Skipped => total_files_skipped += 1, } } Ok(CopyCommandResult { files_copied: total_files_copied, + files_redacted: total_files_redacted, files_skipped: total_files_skipped, }) } else { @@ -161,10 +170,17 @@ pub async fn command_copy( { TransferFileResult::Copied => CopyCommandResult { files_copied: 1, + files_redacted: 0, + files_skipped: 0, + }, + TransferFileResult::RedactedAndCopied => CopyCommandResult { + files_copied: 1, + files_redacted: 1, files_skipped: 0, }, TransferFileResult::Skipped => CopyCommandResult { files_copied: 0, + files_redacted: 0, files_skipped: 1, }, }, @@ -237,6 +253,7 @@ async fn report_copy_info( enum TransferFileResult { Copied, + RedactedAndCopied, Skipped, } @@ -396,7 +413,11 @@ async fn redact_upload_file< destination_fs .upload(redacted_result.stream, Some(dest_file_ref)) .await?; - Ok(TransferFileResult::Copied) + if redacted_result.number_of_redactions > 0 { + Ok(TransferFileResult::RedactedAndCopied) + } else { + Ok(TransferFileResult::Copied) + } } Ok(_) => { bar.println( diff --git a/src/main.rs b/src/main.rs index 02b4e8c..84ce087 100644 --- a/src/main.rs +++ b/src/main.rs @@ -70,6 +70,7 @@ async fn handle_args(cli: CliArgs, term: &Term) -> AppResult<()> { filename_filter, redacter_args, mime_override, + save_json_results, } => { let options = CopyCommandOptions::new( filename_filter, @@ -87,17 +88,33 @@ async fn handle_args(cli: CliArgs, term: &Term) -> AppResult<()> { .await?; term.write_line( format!( - "\n{} -> {}: {} files processed. {} files skipped.", + "\n{} -> {}: {} files copied ({} redacted). {} files skipped.", source, destination, Style::new() .bold() .green() .apply_to(copy_result.files_copied), + Style::new() + .green() + .dim() + .apply_to(copy_result.files_redacted), Style::new().yellow().apply_to(copy_result.files_skipped), ) .as_str(), )?; + if let Some(json_path) = save_json_results { + let json_result = serde_json::to_string_pretty(©_result)?; + let mut file = tokio::fs::File::create(&json_path).await?; + tokio::io::AsyncWriteExt::write_all(&mut file, json_result.as_bytes()).await?; + term.write_line( + format!( + "Results saved to JSON file: {}", + Style::new().bold().apply_to(json_path.display()) + ) + .as_str(), + )?; + } } CliCommand::Ls { source,