diff --git a/src/pull.rs b/src/pull.rs index 01a9135dcccc791829be9168fbebc33ed1a8c769..4f16840bb0108d936285f66dbb0165bfa8bb3ecc 100644 --- a/src/pull.rs +++ b/src/pull.rs @@ -12,6 +12,34 @@ use std::path::PathBuf; use std::process::exit; use std::process::Command; use std::process::Stdio; +use std::collections::HashMap; + + +/// Function used to execute a given command and get it's output +/// +/// # Arguments +/// - `prog`: String of the program to execute +/// - `args`: The list of arguments +/// +/// # Return +/// std::process::Output objects +fn execute_cmd(prog: &str, args: Vec<&str>) -> std::process::Output { + let output = Command::new(prog).args(&args).output(); + let res = match output { + Err(e) => { + eprintln!( + "{}: {} log terminated with an error {}", + "error".red(), + prog, + e + ); + exit(1); + } + Ok(r) => r, + }; + res +} + /// Function used to import a tar archive in the remote folder of the current /// filsesystem @@ -148,7 +176,7 @@ pub(crate) fn get_git_commits() -> Vec<String> { let res = match output { Err(e) => { eprintln!( - "{}: borg list terminated with an error {}", + "{}: git log terminated with an error {}", "error".red(), e ); @@ -347,6 +375,37 @@ pub(crate) fn pull_all_archives(remote: &str) { } } +/// Function that determines if an archive is a tag or a branch +/// +/// # Argument +/// - `commit`: A commit SHA1 or a branch or tag name +/// +/// # Return The SHA1 of the corresponding commit +pub(crate) fn get_sha1_commit(commit: &str) -> String { + let args: Vec<&str> = vec!["for-each-ref", "--format='%(refname:short)~~%(objectname)'", "refs/heads/"]; + let output = execute_cmd("git", args); + let mut branches_str = String::from_utf8(output.stdout).unwrap().replace("'", "").split_whitespace().map(| c | { c.to_owned() }).collect::<Vec<String>>(); + let args: Vec<&str> = vec!["for-each-ref", "--format='%(refname:short)~~%(objectname)'", "refs/tags/"]; + let output = execute_cmd("git", args); + let tag_str = String::from_utf8(output.stdout).unwrap().replace("'", "").split_whitespace().map(| c | { c.to_owned() }).collect::<Vec<String>>(); + branches_str.extend(tag_str); + let mut my_dic: HashMap<String, String> = HashMap::new(); + for br in branches_str { + let tmp: Vec<&str> = br.split("~~").collect(); + if tmp.len() != 2 { + eprintln!("{}: Cannot recover git branch and SHA1 commit", "error".red()); + exit(1) + } + let (k, v) = (tmp.get(0).unwrap().to_owned().to_owned(), tmp.get(1).unwrap().to_owned().to_owned()); + my_dic.insert(k, v); + } + match my_dic.get(commit) { + Some(sha1) => sha1, + None => commit + }.to_owned() +} + + /// Create a push the tar achive on the selected remote path /// # Arguments /// - `remote`: The name of a remote @@ -362,7 +421,8 @@ pub fn pull(remote: &str, archive: &Option<String>, all: bool) -> () { } Some(arc) => { let git_commits = get_git_commits(); - pull_archive_when_needed(remote, arc, &git_commits); + let arc = get_sha1_commit(&arc); + pull_archive_when_needed(remote, &arc, &git_commits); }, } } else { diff --git a/src/push.rs b/src/push.rs index f09646fbecfcb0996ea50de711cedef12cac71cc..7941376623994f92b1472c88a04565f5807f1eb2 100644 --- a/src/push.rs +++ b/src/push.rs @@ -4,6 +4,7 @@ use crate::commit; use crate::mount; +use crate::pull; use crate::remote; use colored::Colorize; use std::fs; @@ -434,7 +435,8 @@ pub fn push(remote: &str, archive: &str, compression: &str) -> () { let borg_folder = borg_folder.canonicalize().unwrap(); let (adress, url) = get_adress_and_url(remote); check_dest_and_copy(&borg_folder, &url, &adress); - let remote_file = get_remote_file(&url, archive, compression); + let archive = pull::get_sha1_commit(archive); + let remote_file = get_remote_file(&url, &archive, compression); let remote_file = handle_existing_remote_file(&remote_file, &adress, "push"); export_tar(&borg_folder, &remote_file, &adress, &archive); }