diff --git a/src/pull.rs b/src/pull.rs index b8ac4b7cc71b456c05fdb6d7d75583672f920df4..01a9135dcccc791829be9168fbebc33ed1a8c769 100644 --- a/src/pull.rs +++ b/src/pull.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0-or-later use crate::commit; +use crate::init; use crate::mount; use crate::push; use colored::Colorize; @@ -135,19 +136,37 @@ pub fn borg_list() -> Vec<String> { .collect::<Vec<String>>() } + +/// Get the list of every SHA1 commit defined in git +/// +/// * Return: +/// The list of every SHA1 +pub(crate) fn get_git_commits() -> Vec<String> { + init::get_borg_folder(); + let args: Vec<&str> = vec!["log", "--reflog", "--format='%H'"]; + let output = Command::new("git").args(&args).output(); + let res = match output { + Err(e) => { + eprintln!( + "{}: borg list terminated with an error {}", + "error".red(), + e + ); + exit(1); + } + Ok(r) => r, + }; + let commits = String::from_utf8(res.stdout).unwrap().replace("'", "").split_whitespace().map(| c | { c.to_owned()}).collect::<Vec<String>>(); + commits +} + + /// Function that will pull one specific archive in the .borg repository /// /// # Arguments: /// - `remote`: The remote folder to use /// - `archive`: The archive to pull fn pull_one_archive(remote: &str, archive: &str) { - if archive.contains(".tar") { - eprintln!( - "{}: The archive given must not have an extention ! Please retry without any extentions.", - "error".red() - ); - return (); - } let (adress, url) = push::get_adress_and_url(remote); let (borg_folder, _) = commit::check_path(); let borg_folder = borg_folder.canonicalize().unwrap(); @@ -168,6 +187,33 @@ fn pull_one_archive(remote: &str, archive: &str) { import_tar(&borg_folder, &remote_file, &adress, &archive) } + + +/// Function that will pull one specific archive in the .borg repository +/// +/// # Arguments: +/// - `remote`: The remote folder to use +/// - `archive`: The archive to pull +/// - `git_commits`: The lists of commits in the project +fn pull_archive_when_needed(remote: &str, archive: &str, git_commits: &Vec<String>) { + if archive.contains(".tar") { + eprintln!( + "{}: The archive given must not have an extention ! Please retry without any extentions.", + "error".red() + ); + exit(1); + } + if !git_commits.contains(&String::from(archive)) { + eprintln!( + "{}: The archive {} is not present in git history ! Pull git remote changes and try again !", + "error".red(), archive.yellow() + ); + exit(1); + } + pull_one_archive(remote, archive) +} + + /// Function that gets all the archives localised in a remote file-system /// /// # Arguments @@ -267,6 +313,26 @@ pub(crate) fn get_archive_list(url: &PathBuf, adress: &str) -> Vec<String> { } } + +/// Function that checks if all remote archives are git commits +/// Stop the process if it's not the case +/// +/// # Arguments +/// - `git_commits`: List of all SHA1 commits defined in git repository +/// - `archives`: List of all archives defined in remote folder +pub(crate) fn check_archives(git_commits: &Vec<String>, archives: &Vec<String>) { + let mut bad_archives: Vec<&str> = Vec::new(); + for archive in archives { + if !git_commits.contains(archive) { + bad_archives.push(archive) + } + } + if bad_archives.len() > 0 { + eprintln!("{}: The following archives are not commits in your git history. Tips: Update (pull) your local git history.\n{}", "error".red(), bad_archives.join("\n").yellow()); + exit(1); + } +} + /// Function that perform the pull for all remote archive /// /// # Argument: @@ -274,6 +340,8 @@ pub(crate) fn get_archive_list(url: &PathBuf, adress: &str) -> Vec<String> { pub(crate) fn pull_all_archives(remote: &str) { let (adress, url) = push::get_adress_and_url(remote); let archives = get_archive_list(&url, &adress); + let git_commits = get_git_commits(); + check_archives(&git_commits, &archives); for archive in archives { pull_one_archive(remote, &archive); } @@ -292,7 +360,10 @@ pub fn pull(remote: &str, archive: &Option<String>, all: bool) -> () { eprintln!("{}: Nothing to do !. Give an archive name or the flag --all to pull every archives from the remote folder !", "warning".yellow()); return (); } - Some(arc) => pull_one_archive(remote, arc), + Some(arc) => { + let git_commits = get_git_commits(); + pull_archive_when_needed(remote, arc, &git_commits); + }, } } else { match archive {