mirror of
https://github.com/Dummi26/rembackup.git
synced 2025-03-10 05:13:54 +01:00
add --ignore
This commit is contained in:
parent
d1cc067bef
commit
e8e5b363ff
0
Cargo.toml
Normal file → Executable file
0
Cargo.toml
Normal file → Executable file
@ -14,4 +14,12 @@ pub struct Args {
|
|||||||
/// where your backup will be stored
|
/// where your backup will be stored
|
||||||
#[arg()]
|
#[arg()]
|
||||||
pub target: Option<PathBuf>,
|
pub target: Option<PathBuf>,
|
||||||
|
/// directories to ignore.
|
||||||
|
/// can be paths relative to <source> (like backups/) or paths starting with <source> (like my_source/backups/).
|
||||||
|
/// if <index> starts with <source>, it is automatically ignored and doesn't need to be specified.
|
||||||
|
#[arg(long)]
|
||||||
|
pub ignore: Vec<PathBuf>,
|
||||||
|
/// don't ask for confirmation, just apply the changes.
|
||||||
|
#[arg(long)]
|
||||||
|
pub noconfirm: bool,
|
||||||
}
|
}
|
||||||
|
43
src/main.rs
43
src/main.rs
@ -19,7 +19,14 @@ fn main() {
|
|||||||
let args = args::Args::parse();
|
let args = args::Args::parse();
|
||||||
// index diff
|
// index diff
|
||||||
eprintln!("performing index diff...");
|
eprintln!("performing index diff...");
|
||||||
let changes = match perform_index_diff(&args.source, &args.index) {
|
let source = &args.source;
|
||||||
|
let index = &args.index;
|
||||||
|
let ignore_subdirs = args
|
||||||
|
.ignore
|
||||||
|
.iter()
|
||||||
|
.map(|path| path.strip_prefix(source).unwrap_or(path))
|
||||||
|
.collect();
|
||||||
|
let changes = match perform_index_diff(source, index, ignore_subdirs) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to generate index diff:\n {e}");
|
eprintln!("Failed to generate index diff:\n {e}");
|
||||||
@ -44,18 +51,30 @@ fn main() {
|
|||||||
eprintln!(" + add/update file");
|
eprintln!(" + add/update file");
|
||||||
eprintln!(" - remove file");
|
eprintln!(" - remove file");
|
||||||
eprintln!(" [-] remove directory (and all contents!)");
|
eprintln!(" [-] remove directory (and all contents!)");
|
||||||
eprintln!("Press Enter to to apply these actions.");
|
// apply changes after confirming
|
||||||
if args.target.is_none() {
|
if !args.noconfirm {
|
||||||
eprintln!("[WARN] You didn't set a `target` directory!\n[WARN] Be careful not to update your index without actually applying the changes to the `target` filesystem!");
|
let mut line = String::new();
|
||||||
}
|
loop {
|
||||||
// apply changes
|
if args.target.is_none() {
|
||||||
if std::io::stdin().read_line(&mut String::new()).is_ok() {
|
eprintln!("[WARN] You didn't set a `target` directory!\n[WARN] Be careful not to update your index without actually applying the changes to the `target` filesystem!\nType 'Ok' and press enter to continue.");
|
||||||
match apply_indexchanges(&args.source, &args.index, &args.target, &changes) {
|
} else {
|
||||||
Ok(()) => {}
|
eprintln!("Exclude unwanted directories/files using --ignore,\nor press enter to apply the changes.");
|
||||||
Err(e) => {
|
|
||||||
eprintln!("Failed to apply: {e}");
|
|
||||||
exit(30);
|
|
||||||
}
|
}
|
||||||
|
line.clear();
|
||||||
|
std::io::stdin().read_line(&mut line).unwrap();
|
||||||
|
let line = line.trim().to_lowercase();
|
||||||
|
if line == "exit" {
|
||||||
|
return;
|
||||||
|
} else if args.target.is_some() || line == "ok" {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match apply_indexchanges(&args.source, &args.index, &args.target, &changes) {
|
||||||
|
Ok(()) => {}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to apply: {e}");
|
||||||
|
exit(30);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,22 @@ use std::{collections::HashMap, fs, io, path::Path};
|
|||||||
|
|
||||||
use crate::{indexchanges::IndexChange, indexfile::IndexFile};
|
use crate::{indexchanges::IndexChange, indexfile::IndexFile};
|
||||||
|
|
||||||
pub fn perform_index_diff(source: &Path, index: &Path) -> io::Result<Vec<IndexChange>> {
|
pub fn perform_index_diff<'a>(
|
||||||
|
source: &Path,
|
||||||
|
index: &'a Path,
|
||||||
|
mut ignore_subdirs: Vec<&'a Path>,
|
||||||
|
) -> io::Result<Vec<IndexChange>> {
|
||||||
let mut changes = Vec::new();
|
let mut changes = Vec::new();
|
||||||
|
if let Ok(inner_index) = index.strip_prefix(source) {
|
||||||
|
eprintln!("[info] source contains index, but index will not be part of the backup.");
|
||||||
|
ignore_subdirs.push(inner_index);
|
||||||
|
}
|
||||||
rec(
|
rec(
|
||||||
source.as_ref(),
|
source.as_ref(),
|
||||||
Path::new(""),
|
Path::new(""),
|
||||||
index,
|
index,
|
||||||
&mut changes,
|
&mut changes,
|
||||||
index.strip_prefix(source).ok(),
|
&ignore_subdirs,
|
||||||
)?;
|
)?;
|
||||||
Ok(changes)
|
Ok(changes)
|
||||||
}
|
}
|
||||||
@ -23,11 +31,10 @@ fn rec(
|
|||||||
// list of changes to be made
|
// list of changes to be made
|
||||||
changes: &mut Vec<IndexChange>,
|
changes: &mut Vec<IndexChange>,
|
||||||
// if the index is part of `source`, where exactly is it?
|
// if the index is part of `source`, where exactly is it?
|
||||||
inner_index: Option<&Path>,
|
ignore_subdirs: &Vec<&Path>,
|
||||||
) -> Result<(), io::Error> {
|
) -> Result<(), io::Error> {
|
||||||
if let Some(ii) = &inner_index {
|
for ii in ignore_subdirs {
|
||||||
if rel_path.starts_with(ii) {
|
if rel_path.starts_with(ii) {
|
||||||
eprintln!("[info] source contains index, but index will not be part of the backup.");
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +69,7 @@ fn rec(
|
|||||||
&rel_path.join(entry.file_name()),
|
&rel_path.join(entry.file_name()),
|
||||||
index_files,
|
index_files,
|
||||||
changes,
|
changes,
|
||||||
inner_index,
|
ignore_subdirs,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
if let Some(true) = in_index_and_is_dir {
|
if let Some(true) = in_index_and_is_dir {
|
||||||
|
Loading…
Reference in New Issue
Block a user