diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-01 09:54:35 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-01 15:13:16 +0100 |
| commit | a23efd79edb59be0e9c84f1fbeea45664dd63515 (patch) | |
| tree | 846221f56234a331605d1c1dbc91127948b2240e /src/bin/ngit/sub_commands/send.rs | |
| parent | a625be66cfbced5f96cb0123a286937543e7273c (diff) | |
refactor(send): abstract proposal commit checks
as the function is too long
Diffstat (limited to 'src/bin/ngit/sub_commands/send.rs')
| -rw-r--r-- | src/bin/ngit/sub_commands/send.rs | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/src/bin/ngit/sub_commands/send.rs b/src/bin/ngit/sub_commands/send.rs index 8b49e37..34965a1 100644 --- a/src/bin/ngit/sub_commands/send.rs +++ b/src/bin/ngit/sub_commands/send.rs | |||
| @@ -104,39 +104,13 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 104 | let (first_commit_ahead, behind) = | 104 | let (first_commit_ahead, behind) = |
| 105 | git_repo.get_commits_ahead_behind(&main_tip, commits.last().context("no commits")?)?; | 105 | git_repo.get_commits_ahead_behind(&main_tip, commits.last().context("no commits")?)?; |
| 106 | 106 | ||
| 107 | // check proposal ahead of origin/main | 107 | check_commits_are_suitable_for_proposal( |
| 108 | if first_commit_ahead.len().gt(&1) && !Interactor::default().confirm( | 108 | &first_commit_ahead, |
| 109 | PromptConfirmParms::default() | 109 | &commits, |
| 110 | .with_prompt( | 110 | &behind, |
| 111 | format!("proposal builds on a commit {} ahead of '{main_branch_name}' - do you want to continue?", first_commit_ahead.len() - 1) | 111 | main_branch_name, |
| 112 | ) | 112 | &main_tip, |
| 113 | .with_default(false) | 113 | )?; |
| 114 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 115 | bail!("aborting because selected commits were ahead of origin/master"); | ||
| 116 | } | ||
| 117 | |||
| 118 | // check if a selected commit is already in origin | ||
| 119 | if commits.iter().any(|c| c.eq(&main_tip)) { | ||
| 120 | if !Interactor::default().confirm( | ||
| 121 | PromptConfirmParms::default() | ||
| 122 | .with_prompt( | ||
| 123 | format!("proposal contains commit(s) already in '{main_branch_name}'. proceed anyway?") | ||
| 124 | ) | ||
| 125 | .with_default(false) | ||
| 126 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 127 | bail!("aborting as proposal contains commit(s) already in '{main_branch_name}'"); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | // check proposal isn't behind origin/main | ||
| 131 | else if !behind.is_empty() && !Interactor::default().confirm( | ||
| 132 | PromptConfirmParms::default() | ||
| 133 | .with_prompt( | ||
| 134 | format!("proposal is {} behind '{main_branch_name}'. consider rebasing before submission. proceed anyway?", behind.len()) | ||
| 135 | ) | ||
| 136 | .with_default(false) | ||
| 137 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 138 | bail!("aborting so commits can be rebased"); | ||
| 139 | } | ||
| 140 | 114 | ||
| 141 | let title = if args.no_cover_letter { | 115 | let title = if args.no_cover_letter { |
| 142 | None | 116 | None |
| @@ -269,6 +243,49 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 269 | Ok(()) | 243 | Ok(()) |
| 270 | } | 244 | } |
| 271 | 245 | ||
| 246 | fn check_commits_are_suitable_for_proposal( | ||
| 247 | first_commit_ahead: &[Sha1Hash], | ||
| 248 | commits: &[Sha1Hash], | ||
| 249 | behind: &[Sha1Hash], | ||
| 250 | main_branch_name: &str, | ||
| 251 | main_tip: &Sha1Hash, | ||
| 252 | ) -> Result<()> { | ||
| 253 | // check proposal ahead of origin/main | ||
| 254 | if first_commit_ahead.len().gt(&1) && !Interactor::default().confirm( | ||
| 255 | PromptConfirmParms::default() | ||
| 256 | .with_prompt( | ||
| 257 | format!("proposal builds on a commit {} ahead of '{main_branch_name}' - do you want to continue?", first_commit_ahead.len() - 1) | ||
| 258 | ) | ||
| 259 | .with_default(false) | ||
| 260 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 261 | bail!("aborting because selected commits were ahead of origin/master"); | ||
| 262 | } | ||
| 263 | |||
| 264 | // check if a selected commit is already in origin | ||
| 265 | if commits.iter().any(|c| c.eq(main_tip)) { | ||
| 266 | if !Interactor::default().confirm( | ||
| 267 | PromptConfirmParms::default() | ||
| 268 | .with_prompt( | ||
| 269 | format!("proposal contains commit(s) already in '{main_branch_name}'. proceed anyway?") | ||
| 270 | ) | ||
| 271 | .with_default(false) | ||
| 272 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 273 | bail!("aborting as proposal contains commit(s) already in '{main_branch_name}'"); | ||
| 274 | } | ||
| 275 | } | ||
| 276 | // check proposal isn't behind origin/main | ||
| 277 | else if !behind.is_empty() && !Interactor::default().confirm( | ||
| 278 | PromptConfirmParms::default() | ||
| 279 | .with_prompt( | ||
| 280 | format!("proposal is {} behind '{main_branch_name}'. consider rebasing before submission. proceed anyway?", behind.len()) | ||
| 281 | ) | ||
| 282 | .with_default(false) | ||
| 283 | ).context("failed to get confirmation response from interactor confirm")? { | ||
| 284 | bail!("aborting so commits can be rebased"); | ||
| 285 | } | ||
| 286 | Ok(()) | ||
| 287 | } | ||
| 288 | |||
| 272 | fn choose_commits(git_repo: &Repo, proposed_commits: Vec<Sha1Hash>) -> Result<Vec<Sha1Hash>> { | 289 | fn choose_commits(git_repo: &Repo, proposed_commits: Vec<Sha1Hash>) -> Result<Vec<Sha1Hash>> { |
| 273 | let mut proposed_commits = if proposed_commits.len().gt(&10) { | 290 | let mut proposed_commits = if proposed_commits.len().gt(&10) { |
| 274 | vec![] | 291 | vec![] |