From 949c6459aa7683453a7160423b689ceadb08954b Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 4 Sep 2024 08:04:48 +0100 Subject: refactor: organise into lib and bin structure the make the code more readable this commit just moves the files, the next commit should fix the imports --- src/sub_commands/pull.rs | 209 ----------------------------------------------- 1 file changed, 209 deletions(-) delete mode 100644 src/sub_commands/pull.rs (limited to 'src/sub_commands/pull.rs') diff --git a/src/sub_commands/pull.rs b/src/sub_commands/pull.rs deleted file mode 100644 index e33a744..0000000 --- a/src/sub_commands/pull.rs +++ /dev/null @@ -1,209 +0,0 @@ -use anyhow::{bail, Context, Result}; - -use super::{ - list::{ - get_all_proposal_patch_events_from_cache, get_commit_id_from_patch, - get_proposals_and_revisions_from_cache, tag_value, - }, - send::event_to_cover_letter, -}; -#[cfg(test)] -use crate::client::MockConnect; -#[cfg(not(test))] -use crate::client::{Client, Connect}; -use crate::{ - client::{fetching_with_report, get_repo_ref_from_cache}, - git::{str_to_sha1, Repo, RepoActions}, - repo_ref::get_repo_coordinates, - sub_commands::{list::get_most_recent_patch_with_ancestors, send::event_is_revision_root}, -}; - -#[allow(clippy::too_many_lines)] -pub async fn launch() -> Result<()> { - let git_repo = Repo::discover().context("cannot find a git repository")?; - let git_repo_path = git_repo.get_path()?; - - let (main_or_master_branch_name, _) = git_repo - .get_main_or_master_branch() - .context("no main or master branch")?; - - let branch_name = git_repo - .get_checked_out_branch_name() - .context("cannot get checked out branch name")?; - - if branch_name == main_or_master_branch_name { - bail!("checkout a branch associated with a proposal first") - } - #[cfg(not(test))] - let client = Client::default(); - #[cfg(test)] - let client = ::default(); - - let repo_coordinates = get_repo_coordinates(&git_repo, &client).await?; - - fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; - - let repo_ref = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await?; - - let proposal_root_event = - get_proposals_and_revisions_from_cache(git_repo_path, repo_ref.coordinates()) - .await? - .iter() - .find(|e| { - event_to_cover_letter(e) - .is_ok_and(|cl| cl.get_branch_name().is_ok_and(|s| s.eq(&branch_name))) - && !event_is_revision_root(e) - }) - .context("cannot find proposal that matches the current branch name")? - .clone(); - let commit_events = get_all_proposal_patch_events_from_cache( - git_repo_path, - &repo_ref, - &proposal_root_event.id(), - ) - .await?; - - let most_recent_proposal_patch_chain = - get_most_recent_patch_with_ancestors(commit_events.clone()) - .context("cannot get most recent patch for proposal")?; - - let local_branch_tip = git_repo.get_tip_of_branch(&branch_name)?; - - let (main_branch_name, master_tip) = git_repo.get_main_or_master_branch()?; - - let (local_ahead_of_main, local_beind_main) = - git_repo.get_commits_ahead_behind(&master_tip, &local_branch_tip)?; - - let proposal_base_commit = str_to_sha1(&tag_value( - most_recent_proposal_patch_chain - .last() - .context("there should be at least one patch as we have already checked for this")?, - "parent-commit", - )?) - .context("cannot get valid parent commit id from patch")?; - - let (_, proposal_behind_main) = - git_repo.get_commits_ahead_behind(&master_tip, &proposal_base_commit)?; - - let proposal_tip = - str_to_sha1( - &get_commit_id_from_patch(most_recent_proposal_patch_chain.first().context( - "there should be at least one patch as we have already checked for this", - )?) - .context("cannot get valid commit_id from patch")?, - ) - .context("cannot get valid commit_id from patch")?; - - // if uptodate - if proposal_tip.eq(&local_branch_tip) { - println!("branch already up-to-date"); - } - // if new appendments - else if most_recent_proposal_patch_chain.iter().any(|patch| { - get_commit_id_from_patch(patch) - .unwrap_or_default() - .eq(&local_branch_tip.to_string()) - }) { - check_clean(&git_repo)?; - let applied = git_repo - .apply_patch_chain(&branch_name, most_recent_proposal_patch_chain) - .context("cannot apply patch chain")?; - println!("applied {} new commits", applied.len(),); - } - // if parent commit doesnt exist - else if !git_repo.does_commit_exist(&proposal_base_commit.to_string())? { - println!( - "a new version of the proposal has a prant commit that doesnt exist in your local repository." - ); - println!("your '{main_branch_name}' branch may not be up-to-date."); - println!("manually run `git pull` on '{main_branch_name}' and try again"); - } - // if new revision and no local changes (tip of local in proposal history) - else if commit_events.iter().any(|patch| { - get_commit_id_from_patch(patch) - .unwrap_or_default() - .eq(&local_branch_tip.to_string()) - }) { - check_clean(&git_repo)?; - - git_repo.create_branch_at_commit(&branch_name, &proposal_base_commit.to_string())?; - let applied = git_repo - .apply_patch_chain(&branch_name, most_recent_proposal_patch_chain) - .context("cannot apply patch chain")?; - - println!( - "pulled new version of proposal ({} ahead {} behind '{main_branch_name}'), replacing old version ({} ahead {} behind '{main_branch_name}')", - applied.len(), - proposal_behind_main.len(), - local_ahead_of_main.len(), - local_beind_main.len(), - ); - } - // if tip of proposal in branch in history (local appendments made to up-to-date - // proposal) - else if git_repo.ancestor_of(&local_branch_tip, &proposal_tip)? { - let (local_ahead_of_proposal, _) = git_repo - .get_commits_ahead_behind(&proposal_tip, &local_branch_tip) - .context("cannot get commits ahead behind for propsal_top and local_branch_tip")?; - println!( - "local proposal branch exists with {} unpublished commits on top of the most up-to-date version of the proposal", - local_ahead_of_proposal.len() - ); - } else { - println!("you have an amended/rebase version the proposal that is unpublished"); - // user probably has a unpublished amended or rebase version of the latest - // proposal version - // if tip of proposal commits exist (were once part of branch but have been - // amended and git clean up job hasn't removed them) - if git_repo.does_commit_exist(&proposal_tip.to_string())? { - println!( - "you have previously applied the latest version of the proposal ({} ahead {} behind '{main_branch_name}') but your local proposal branch has amended or rebased it ({} ahead {} behind '{main_branch_name}')", - most_recent_proposal_patch_chain.len(), - proposal_behind_main.len(), - local_ahead_of_main.len(), - local_beind_main.len(), - ); - } - // user probably has a unpublished amended or rebase version of an older - // proposal version - else { - println!( - "your local proposal branch ({} ahead {} behind '{main_branch_name}') has conflicting changes with the latest published proposal ({} ahead {} behind '{main_branch_name}')", - local_ahead_of_main.len(), - local_beind_main.len(), - most_recent_proposal_patch_chain.len(), - proposal_behind_main.len(), - ); - - println!( - "its likely that you have rebased / amended an old proposal version because git has no record of the latest proposal commit." - ); - println!( - "it is possible that you have been working off the latest version and git has delete this commit as part of a clean up" - ); - } - println!("to view the latest proposal but retain your changes:"); - println!(" 1) create a new branch off the tip commit of this one to store your changes"); - println!(" 2) run `ngit list` and checkout the latest published version of this proposal"); - - println!("if you are confident in your changes consider running `ngit push --force`"); - - // TODO: this copy could be refined further based on this: - // - amended commits in the proposal - // - if local_base eq proposal base - // - amended an older version of proposal - // - if local_base is behind proposal_base - // - rebased the proposal - // - if local_base is ahead of proposal_base - } - Ok(()) -} - -fn check_clean(git_repo: &Repo) -> Result<()> { - if git_repo.has_outstanding_changes()? { - bail!( - "cannot pull proposal branch when repository is not clean. discard or stash (un)staged changes and try again." - ); - } - Ok(()) -} -- cgit v1.2.3