Skip to content

Commit

Permalink
feat: started with execute command
Browse files Browse the repository at this point in the history
  • Loading branch information
0xCCF4 committed Dec 1, 2024
1 parent b5f1b34 commit 7cc2438
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub mod stages {
pub mod clean;
/// Contains the implementation of the dedup command.
pub mod dedup;
/// Contains the implementation of the execute command.
pub mod execute;
}

mod data {
Expand Down
66 changes: 65 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use backup_deduplicator::stages::clean::cmd::CleanSettings;
use backup_deduplicator::stages::dedup::golden_model::cmd::{
DedupGoldenModelSettings, MatchingModel,
};
use backup_deduplicator::stages::{analyze, build, clean, dedup};
use backup_deduplicator::stages::{analyze, build, clean, dedup, execute};
use backup_deduplicator::utils;
use clap::{arg, Parser, Subcommand};
use log::{debug, info, trace, LevelFilter};
use std::env;
use std::path::PathBuf;
use std::str::FromStr;
use backup_deduplicator::stages::execute::cmd::{ExecuteAction, ExecuteActionType, ExecuteSettings};

/// A simple command line tool to deduplicate backups.
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -114,6 +115,24 @@ enum Command {
#[command(subcommand)]
mode: DedupMode,
},
/// Execute a list of actions to deduplicate the file tree
Execute {
/// The input actions file to execute.
#[arg(short, long, default_value = "actions.bdc")]
input: String,
/// Dry-run mode, no file changes are made. Actions taken are outputted to the console.
#[arg(long, short = 'n')]
dry_run: bool,
/// Action to be taken. "delete" deletes duplicates, "move" moves duplicates into a subfolder specified using "--move-folder".
#[arg(long, short)]
action: ExecuteActionType,
/// When using the move action: The folder name to move duplicates to.
#[arg(long = "move-folder", default_value = "__DEDUP__")]
move_folder_name: String,
/// The root folders/files from the analysis
#[arg()]
files: Vec<String>,
}
}

#[derive(Subcommand, Debug)]
Expand Down Expand Up @@ -443,6 +462,51 @@ fn main() {
}
}
}
},
Command::Execute {
action,
files,
dry_run,
move_folder_name,
input
} => {
let input = utils::main::parse_path(
input.as_str(),
utils::main::ParsePathKind::AbsoluteExisting,
);

if !input.exists() {
eprintln!("Input file does not exist: {:?}", input);
std::process::exit(exitcode::CONFIG);
}

let files = files.into_iter().map(|file| {
utils::main::parse_path(
file.as_str(),
utils::main::ParsePathKind::AbsoluteExisting,
)
}).collect::<Vec<PathBuf>>();

match execute::cmd::run(ExecuteSettings {
dry_run,
action: match action {
ExecuteActionType::DeleteDuplicates => ExecuteAction::DeleteDuplicates,
ExecuteActionType::MoveDuplicates => ExecuteAction::MoveDuplicates {
folder_name: move_folder_name,
}
},
files,
input
}) {
Ok(_) => {
info!("Execute command completed successfully");
std::process::exit(exitcode::OK);
}
Err(e) => {
eprintln!("Error: {:?}", e);
std::process::exit(exitcode::SOFTWARE);
}
}
}
}
}
1 change: 0 additions & 1 deletion src/stages/build/cmd/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ pub struct BuildSettings {
// pub absolute_paths: bool,
/// The number of threads to use for building the hash tree. None = number of logical CPUs.
pub threads: Option<usize>,

/// The hash algorithm to use for hashing files.
pub hash_type: GeneralHashType,
/// Whether to continue an existing hash tree file.
Expand Down
2 changes: 2 additions & 0 deletions src/stages/execute.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// Contains the implementation of the execute command.
pub mod cmd;
70 changes: 70 additions & 0 deletions src/stages/execute/cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::fs;
use std::path::PathBuf;
use std::str::FromStr;
use anyhow::{anyhow, Result};
use crate::stages::dedup::output::DeduplicationActions;

pub struct ExecuteSettings {
/// The action file
pub input: PathBuf,
/// The root folders/files from the analysis
pub files: Vec<PathBuf>,
/// Dry-run
pub dry_run: bool,
/// The action to take when duplicates are found
pub action: ExecuteAction,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExecuteActionType {
DeleteDuplicates,
MoveDuplicates,
}

impl FromStr for ExecuteActionType {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self> {
match s {
"delete"|"d" => Ok(ExecuteActionType::DeleteDuplicates),
"move"|"m" => Ok(ExecuteActionType::MoveDuplicates),
_ => Err(anyhow!("Invalid action: {}. Possible values are 'delete' and 'move'", s)),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExecuteAction {
DeleteDuplicates,
MoveDuplicates {
folder_name: String
},
}

pub fn run(execute_settings: ExecuteSettings) -> Result<()> {
let mut input_file_options = fs::File::options();
input_file_options.read(true);
input_file_options.write(false);

let input_file = match input_file_options.open(execute_settings.input) {
Ok(file) => file,
Err(err) => {
return Err(anyhow!("Failed to open input file: {}", err));
}
};

let mut input_buf_reader = std::io::BufReader::new(&input_file);

let file: DeduplicationActions = match serde_json::from_reader(&mut input_buf_reader) {
Ok(file) => file,
Err(err) => {
return Err(anyhow!("Failed to read input file: {}", err));
}
};

for x in file.actions {
println!(" - {:?}", x);
}

Ok(())
}

0 comments on commit 7cc2438

Please sign in to comment.