Skip to content

Commit

Permalink
remove concept of mnt and path_repo, use simply path1, path2, `re…
Browse files Browse the repository at this point in the history
…po`, `repo1` and `repo2`
  • Loading branch information
radumarias committed Jul 10, 2024
1 parent 6e8d567 commit 424ace7
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 77 deletions.
112 changes: 56 additions & 56 deletions file-tree-merge/src/apply_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ pub fn apply(
changes: Changes,
items_path1: Items,
items_path2: Items,
path1_mnt: &Path,
path2_mnt: &Path,
path1_repo: &Path,
_path2_repo: &Path,
path1: &Path,
path2: &Path,
repo1: &Path,
repo2: &Path,
dry_run: bool,
checksum: bool,
crc: bool,
Expand Down Expand Up @@ -53,10 +53,10 @@ pub fn apply(
path,
items_path1.clone(),
items_path2.clone(),
path1_mnt,
path2_mnt,
path1_repo,
_path2_repo,
path1,
path2,
repo1,
repo2,
dry_run,
checksum,
crc,
Expand Down Expand Up @@ -96,10 +96,10 @@ pub fn apply(
path,
items_path1.clone(),
items_path2.clone(),
path1_mnt,
path2_mnt,
path1_repo,
_path2_repo,
path1,
path2,
repo1,
repo2,
dry_run,
checksum,
crc,
Expand Down Expand Up @@ -141,23 +141,23 @@ pub fn apply(
.bold()
);
}
git_add(&path1_repo.join(TREE_DIR), ".")?;
git_commit(path1_repo)?;
git_add(&repo1.join(TREE_DIR), ".")?;
git_commit(repo1)?;

Ok(())
}

fn items_content_eq(
path1_mnt: &&Path,
path1: &&Path,
a: &Item,
path2_mnt: &&Path,
path2: &&Path,
b: &Item,
checksum: bool,
) -> io::Result<bool> {
if a.size == b.size && a.mtime == b.mtime {
if checksum {
let hash1 = file_hash(&path1_mnt.join(&a.path), HashKind::Md5)?;
let hash2 = file_hash(&path2_mnt.join(&b.path), HashKind::Md5)?;
let hash1 = file_hash(&path1.join(&a.path), HashKind::Md5)?;
let hash2 = file_hash(&path2.join(&b.path), HashKind::Md5)?;
Ok(hash1.eq(&hash2))
} else {
Ok(true)
Expand All @@ -172,10 +172,10 @@ fn process(
path: &String,
items_path1: Arc<Mutex<Items>>,
items_path2: Arc<Mutex<Items>>,
path1_mnt: &Path,
path2_mnt: &Path,
path1_repo: &Path,
_path2_repo: &Path,
path1: &Path,
path2: &Path,
repo1: &Path,
_repo2: &Path,
dry_run: bool,
checksum: bool,
crc: bool,
Expand All @@ -186,7 +186,7 @@ fn process(
applied_size_since_commit: &AtomicU64,
commit_after_size_bytes: i32,
) -> Result<()> {
let path2 = path2_mnt.join(path);
let dst = path2.join(path);
ctr.fetch_add(1, Ordering::SeqCst);
match change.clone() {
Change::Add | Change::Modify => {
Expand All @@ -202,20 +202,20 @@ fn process(
let guard = items_path1.lock().unwrap();
let path1_item = guard.get(path).unwrap();
if let Some(dst_item) = items_path2.lock().unwrap().get(path) {
if items_content_eq(&path1_mnt, &path1_item, &path2_mnt, &dst_item, checksum)? {
if items_content_eq(&path1, &path1_item, &path2, &dst_item, checksum)? {
add = false;
}
}
if add {
if dry_run {
return Ok(());
}
fs::create_dir_all(path2.parent().unwrap())?;
fs::copy(path1_mnt.join(&path), path2.clone())?;
File::set_times(&File::open(path2.clone())?, path1_item.times)?;
File::open(path2.clone())?.sync_all()?;
File::open(path2.parent().unwrap())?.sync_all()?;
if crc && !crc_eq(&path1_mnt.join(&path), &path2.clone())? {
fs::create_dir_all(dst.parent().unwrap())?;
fs::copy(path1.join(&path), dst.clone())?;
File::set_times(&File::open(dst.clone())?, path1_item.times)?;
File::open(dst.clone())?.sync_all()?;
File::open(dst.parent().unwrap())?.sync_all()?;
if crc && !crc_eq(&path1.join(&path), &dst.clone())? {
// todo: collect in errors
println!(
"{}",
Expand All @@ -236,12 +236,12 @@ fn process(
if ctr.load(Ordering::SeqCst) % batch_size as u64 == 0 {
println!("{} '{}'", change.to_string().red(), path.red().bold());
}
if path2.exists() {
if dst.exists() {
if dry_run {
return Ok(());
}
fs::remove_file(path2.clone())?;
File::open(path2.parent().unwrap())?.sync_all()?;
fs::remove_file(dst.clone())?;
File::open(dst.parent().unwrap())?.sync_all()?;
} else if ctr.load(Ordering::SeqCst) % batch_size as u64 == 0 {
println!("{}", " skip, not present in path2".yellow());
}
Expand All @@ -254,26 +254,26 @@ fn process(
let guard = items_path1.lock().unwrap();
let path1_item = guard.get(path).unwrap();
// todo: compare if old file hash in src is same as old file hash in dst
if path2_mnt.join(&old_path).exists() {
if path2.join(&old_path).exists() {
if dry_run {
return Ok(());
}
fs::create_dir_all(path2.parent().unwrap())?;
fs::rename(path2_mnt.join(&old_path), path2.clone())?;
File::set_times(&File::open(path2.clone())?, path1_item.times)?;
File::open(path2.clone())?.sync_all()?;
File::open(path2.parent().unwrap())?.sync_all()?;
fs::create_dir_all(dst.parent().unwrap())?;
fs::rename(path2.join(&old_path), dst.clone())?;
File::set_times(&File::open(dst.clone())?, path1_item.times)?;
File::open(dst.clone())?.sync_all()?;
File::open(dst.parent().unwrap())?.sync_all()?;
} else {
println!("{}", format!(" cannot R '{old_path}' -> '{path}', old file not present in path2. Will copy instead from path1 to the new destination").yellow());
if dry_run {
return Ok(());
}
fs::create_dir_all(path2_mnt.join(path).parent().unwrap())?;
fs::copy(path1_mnt.join(path), path2.clone())?;
File::set_times(&File::open(path2.clone())?, path1_item.times)?;
File::open(path2.clone())?.sync_all()?;
File::open(path2.parent().unwrap())?.sync_all()?;
if crc && !crc_eq(&path1_mnt.join(path), &path2.clone())? {
fs::create_dir_all(path2.join(path).parent().unwrap())?;
fs::copy(path1.join(path), dst.clone())?;
File::set_times(&File::open(dst.clone())?, path1_item.times)?;
File::open(dst.clone())?.sync_all()?;
File::open(dst.parent().unwrap())?.sync_all()?;
if crc && !crc_eq(&path1.join(path), &dst.clone())? {
// todo: collect in errors
println!(
"{}",
Expand All @@ -292,24 +292,24 @@ fn process(
let guard = items_path1.lock().unwrap();
let path1_item = guard.get(path).unwrap();
// todo: compare if old file hash in src is same as old file hash in dst
if path2_mnt.join(&old_path).exists() {
if path2.join(&old_path).exists() {
if dry_run {
return Ok(());
}
fs::create_dir_all(path2.clone().parent().unwrap())?;
fs::copy(path2_mnt.join(&old_path), path2.clone())?;
File::set_times(&File::open(path2.clone())?, path1_item.times)?;
File::open(path2.clone())?.sync_all()?;
File::open(path2.parent().unwrap())?.sync_all()?;
fs::create_dir_all(dst.clone().parent().unwrap())?;
fs::copy(path2.join(&old_path), dst.clone())?;
File::set_times(&File::open(dst.clone())?, path1_item.times)?;
File::open(dst.clone())?.sync_all()?;
File::open(dst.parent().unwrap())?.sync_all()?;
} else {
println!("{}", format!(" cannot C '{old_path}' -> '{path}', old file not present in path2. Will copy instead from path1 to the new destination").yellow());
if dry_run {
return Ok(());
}
fs::create_dir_all(path2.parent().unwrap())?;
fs::copy(path1_mnt.join(path), path2.clone())?;
fs::create_dir_all(dst.parent().unwrap())?;
fs::copy(path1.join(path), dst.clone())?;
}
if crc && !crc_eq(&path1_mnt.join(path), &path2.clone())? {
if crc && !crc_eq(&path1.join(path), &dst.clone())? {
// todo: collect in errors
println!(
"{}",
Expand All @@ -322,10 +322,10 @@ fn process(
}
}
let _guard = git_lock.lock().unwrap();
git_add(&path1_repo.join(TREE_DIR), path)?;
git_add(&repo1.join(TREE_DIR), path)?;
if applied_size_since_commit.load(Ordering::SeqCst) > commit_after_size_bytes as u64 {
println!("{}", "Checkpointing applied changes...".cyan());
git_commit(path1_repo)?;
git_commit(repo1)?;
applied_size_since_commit.store(0, Ordering::SeqCst);
}
Ok(())
Expand Down
2 changes: 0 additions & 2 deletions file-tree-merge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ pub mod change_tree_merge;
pub mod path_walker;
pub mod tree_creator;

pub const MNT_DIR: &str = "mnt";
pub const REPO_DIR: &str = "repo";
pub const TREE_DIR: &str = "tree";

pub trait IterRef {
Expand Down
38 changes: 19 additions & 19 deletions file-tree-merge/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@ struct Args {
short,
long,
short = 'a',
help = "First mount point, where actual files that needs to be synced are located."
help = "First directory where actual files that needs to be synced are located."
)]
path1_mnt: PathBuf,
path1: PathBuf,

#[arg(
short,
long,
short = 'b',
help = "Second mount point, where actual files that needs to be synced are located."
help = "Second directory where actual files that needs to be synced are located."
)]
path2_mnt: PathBuf,
path2: PathBuf,

#[arg(
short,
long,
short = 'r',
help = "A directory where we'll keep a git repo to detect changes. Should persist between runs. MUST NOT BE INSIDE ANY OF <PATH1-MNT> or <PATH2-MNT> DIRECTORIES"
help = "A directory where we'll keep a git repo to detect changes. Should persist between runs. MUST NOT BE INSIDE ANY OF path1 or path2 DIRECTORIES"
)]
path_repo: PathBuf,
repo: PathBuf,

#[arg(
short,
long,
default_value_t = false,
help = "This simulates the sync. Will not actually create or change any of the files in <PATH1-MNT> or <PATH2-MNT>, will just print the operations that would have normally be applied to both ends"
help = "This simulates the sync. Will not actually create or change any of the files in path1 or path2, will just print the operations that would have normally be applied to both ends"
)]
dry_run: bool,

Expand All @@ -54,7 +54,7 @@ struct Args {
long,
short = 't',
default_value_t = false,
help = "If specified it will calculate MD5 hash for files when comparing file in <PATH1-MNT> with the file in <PATH2-MNT> when applying Add and Modify operations. It will be considerably slower when activated"
help = "If specified it will calculate MD5 hash for files when comparing file in path1 with the file in path2 when applying Add and Modify operations. It will be considerably slower when activated"
)]
checksum: bool,

Expand All @@ -63,7 +63,7 @@ struct Args {
long,
short = 'x',
default_value_t = false,
help = "If specified it will skip CRC check after file was transferred. Without this it compares the CRC of the file in <PATH1-MNT> before transfer with the CRC of the file in <PATH2-MNT> after transferred. This ensures the transfer was successful. Checking CRC is highly recommend if any of <PATH1-MNT> or <PATH1-MNT> are accessed over the network"
help = "If specified it will skip CRC check after file was transferred. Without this it compares the CRC of the file in path1 before transfer with the CRC of the file in path2 after transferred. This ensures the transfer was successful. Checking CRC is highly recommend if any of path1 or path1 are accessed over the network"
)]
no_crc: bool,
}
Expand Down Expand Up @@ -91,9 +91,9 @@ fn main() -> Result<()> {

println!("{}", "Build changes trees...".cyan());
let (changes_tree1, errors1) =
changes_tree(PathWalker::new(&args.path1_mnt), &args.path_repo.join("1"))?;
changes_tree(PathWalker::new(&args.path1), &args.repo.join("1"))?;
let (changes_tree2, errors2) =
changes_tree(PathWalker::new(&args.path2_mnt), &args.path_repo.join("2"))?;
changes_tree(PathWalker::new(&args.path2), &args.repo.join("2"))?;

println!("{}", "Merge changes trees...".cyan());
change_tree_merge::merge(changes_tree1, changes_tree2, MergeStrategy::OneWay)?.pipe(|x| {
Expand All @@ -111,20 +111,20 @@ fn main() -> Result<()> {
changes_src,
items_path1,
items_path2,
&args.path1_mnt,
&args.path2_mnt,
&args.path_repo.join("1"),
&args.path_repo.join("2"),
&args.path1,
&args.path2,
&args.repo.join("1"),
&args.repo.join("2"),
args.dry_run,
args.checksum,
!args.no_crc,
)?;
println!("{}", "Cleanup repo...".cyan());
git_delete_history(&args.path_repo.join("1"))?;
git_delete_history(&args.repo.join("1"))?;
// todo: dst -> src
git_add(&args.path_repo.join("1"), ".")?;
git_commit(&args.path_repo.join("2"))?;
git_delete_history(&args.path_repo.join("2"))?;
git_add(&args.repo.join("1"), ".")?;
git_commit(&args.repo.join("2"))?;
git_delete_history(&args.repo.join("2"))?;
Ok(())
})?;

Expand Down

0 comments on commit 424ace7

Please sign in to comment.