Skip to content
Snippets Groups Projects
Commit e88d7623 authored by nfontrod's avatar nfontrod
Browse files

src/mount.rs: add last and diff parameter to mount archive function + creation of fill_diff module

parent 4b5dad9f
No related branches found
No related tags found
No related merge requests found
......@@ -17,8 +17,18 @@ fn get_mount_folder(borgfolder: &PathBuf) -> PathBuf {
mount_folder
}
pub fn mount_archive(commit: &Option<String>, path: &Option<String>, versions: bool) -> () {
let (borg_folder, _) = commit::check_path();
pub fn mount_archive(
commit: &Option<String>,
path: &Option<String>,
mut versions: bool,
diff: bool,
last: Option<u8>,
) -> () {
if diff & versions {
eprintln!("Diff cannot be performed with version view. Setting versions to false");
versions = false;
}
let (borg_folder, result_folder) = commit::check_path();
let mount_folder = get_mount_folder(&borg_folder);
let globp = match commit {
Some(g) => format!("-a '{}'", g),
......@@ -28,14 +38,25 @@ pub fn mount_archive(commit: &Option<String>, path: &Option<String>, versions: b
Some(p) => String::from(p),
None => String::from(""),
};
let lastp = match last {
Some(p) => {
if p > 0 {
format!("--last {}", p)
} else {
String::from("")
}
}
None => String::from(""),
};
let vopt = match versions {
true => String::from("-o versions"),
false => String::from(""),
};
let cmd = format!(
"borg mount {} {} {} {} {}",
"borg mount {} {} {} {} {} {}",
globp,
vopt,
lastp,
borg_folder.to_str().unwrap(),
mount_folder.to_str().unwrap(),
mp
......@@ -48,6 +69,9 @@ pub fn mount_archive(commit: &Option<String>, path: &Option<String>, versions: b
exit(num);
}
}
if diff {
file_diff::display_diff(&mount_folder, &result_folder, path);
}
}
/// Unount an borg archive mounted in .mount folder
......@@ -79,3 +103,139 @@ pub fn umount_archive(silent: bool) -> () {
}
}
}
mod file_diff {
use std::{
fs,
path::PathBuf,
process::{exit, Command},
};
extern crate globwalk;
use filetime::FileTime;
/// Function used to recover files inside the folder `folder`
/// # Arguments
/// * folder: The folder containing the path pattern
/// * path_pattern: A pattern used to recover the files into that folder
/// # Returns
/// The list of file located inside `folder` matching `path_pattern`
fn recover_files(folder: &PathBuf, path_pattern: &str) -> Vec<PathBuf> {
let mfiles = globwalk::GlobWalkerBuilder::from_patterns(folder, &[path_pattern])
.max_depth(100)
.follow_links(false)
.build()
.unwrap()
.into_iter()
.filter_map(Result::ok)
.map(|x| x.path().to_path_buf())
.collect::<Vec<_>>();
let rfiles = mfiles
.into_iter()
.filter(|x| x.is_file())
.collect::<Vec<PathBuf>>();
rfiles
}
/// Arrange files by their last modification dates
/// # Arguments
/// * file_tuple: A tuple of two files
/// # Return
/// The file tuple ordered by creation date
fn arrange_by_modification_date(file_tuple: (PathBuf, PathBuf)) -> (PathBuf, PathBuf) {
let (f1, f2) = file_tuple;
let meta1 = fs::metadata(&f1).unwrap();
let time1 = FileTime::from_last_modification_time(&meta1);
let meta2 = fs::metadata(&f2).unwrap();
let time2 = FileTime::from_last_modification_time(&meta2);
if time1 < time2 {
(f1, f2)
} else {
(f2, f1)
}
}
/// Check the len of the list of files given in input with vfiles
/// # Arguments
/// * vfiles: A tuple containing files of interest
/// # Results
/// A tuple containing two paths only if vfiles contains two files else
/// return an error
fn check_file_len(vfiles: &Vec<PathBuf>) -> (PathBuf, PathBuf) {
match vfiles.len() {
2 => (vfiles[0].to_path_buf(), vfiles[1].to_path_buf()),
x => {
eprintln!(
"Unable to show diffs because {x} files were match by the --path pattern !"
);
exit(32);
}
}
}
/// Add to the list of files given in input those located in the current
/// result folder and arrange them by modification date
/// # Arguments
/// * vfile: A list of files
/// * result_folder: The result folder of the current project
/// * pattern: The path pattern given to the mount function
fn update_files(
vfile: &Vec<PathBuf>,
result_folder: &PathBuf,
pattern: &String,
) -> (PathBuf, PathBuf) {
let nres = if pattern.starts_with("results/") {
result_folder
.canonicalize()
.unwrap()
.parent()
.unwrap()
.to_path_buf()
} else {
result_folder.to_path_buf()
};
if vfile.len() == 1 {
let tmp = recover_files(&nres, pattern);
let mut tmp2 = vfile.clone();
tmp2.extend(tmp);
check_file_len(&tmp2)
} else {
arrange_by_modification_date(check_file_len(vfile))
}
}
/// launch delta program
/// # Arguments
/// tuple_file: A tuple containing two files
fn launch_delta(tuple_file: (PathBuf, PathBuf)) -> () {
Command::new("delta")
.arg(tuple_file.0.to_str().unwrap())
.arg(tuple_file.1.to_str().unwrap())
.spawn()
.expect("command failed")
.wait()
.expect("wait failed");
}
/// Function used to displays the differences between two files matching the pattern `path_pattern`
/// # Arguments
/// * mount_folder: The folder containing the path pattern
/// * path_pattern: A pattern used to recover the files into that folder
pub fn display_diff(
mount_folder: &PathBuf,
result_folder: &PathBuf,
path_pattern: &Option<String>,
) -> () {
let my_pattern = match path_pattern {
None => {
eprintln!("Cannot compare files is no path 'argument --path/-p are given !");
exit(31);
}
Some(p) => p,
};
let npattern = format!("*/{}", my_pattern);
let rfiles = recover_files(mount_folder, &npattern);
let ffiles = update_files(&rfiles, result_folder, my_pattern);
println!("{:?}", ffiles);
launch_delta(ffiles);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment