upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/git.rs14
-rw-r--r--src/sub_commands/prs/list.rs23
-rw-r--r--tests/prs_list.rs23
3 files changed, 53 insertions, 7 deletions
diff --git a/src/git.rs b/src/git.rs
index 41520c6..e832c23 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -3,7 +3,7 @@ use std::path::PathBuf;
3use std::{env::current_dir, path::Path}; 3use std::{env::current_dir, path::Path};
4 4
5use anyhow::{bail, Context, Result}; 5use anyhow::{bail, Context, Result};
6use git2::{Oid, Revwalk}; 6use git2::{DiffOptions, Oid, Revwalk};
7use nostr::prelude::{sha1::Hash as Sha1Hash, Hash}; 7use nostr::prelude::{sha1::Hash as Sha1Hash, Hash};
8 8
9use crate::sub_commands::prs::list::tag_value; 9use crate::sub_commands::prs::list::tag_value;
@@ -52,6 +52,8 @@ pub trait RepoActions {
52 base_commit: &Sha1Hash, 52 base_commit: &Sha1Hash,
53 latest_commit: &Sha1Hash, 53 latest_commit: &Sha1Hash,
54 ) -> Result<(Vec<Sha1Hash>, Vec<Sha1Hash>)>; 54 ) -> Result<(Vec<Sha1Hash>, Vec<Sha1Hash>)>;
55 // including (un)staged changes and (un)tracked files
56 fn has_outstanding_changes(&self) -> Result<bool>;
55 fn make_patch_from_commit(&self, commit: &Sha1Hash) -> Result<String>; 57 fn make_patch_from_commit(&self, commit: &Sha1Hash) -> Result<String>;
56 fn extract_commit_pgp_signature(&self, commit: &Sha1Hash) -> Result<String>; 58 fn extract_commit_pgp_signature(&self, commit: &Sha1Hash) -> Result<String>;
57 fn checkout(&self, ref_name: &str) -> Result<Sha1Hash>; 59 fn checkout(&self, ref_name: &str) -> Result<Sha1Hash>;
@@ -242,6 +244,16 @@ impl RepoActions for Repo {
242 .to_owned()) 244 .to_owned())
243 } 245 }
244 246
247 // including (un)staged changes and (un)tracked files
248 fn has_outstanding_changes(&self) -> Result<bool> {
249 let diff = self.git_repo.diff_tree_to_workdir_with_index(
250 Some(&self.git_repo.head()?.peel_to_tree()?),
251 Some(DiffOptions::new().include_untracked(true)),
252 )?;
253
254 Ok(diff.deltas().len().gt(&0))
255 }
256
245 fn get_commits_ahead_behind( 257 fn get_commits_ahead_behind(
246 &self, 258 &self,
247 base_commit: &Sha1Hash, 259 base_commit: &Sha1Hash,
diff --git a/src/sub_commands/prs/list.rs b/src/sub_commands/prs/list.rs
index a6aa8b7..f896f5a 100644
--- a/src/sub_commands/prs/list.rs
+++ b/src/sub_commands/prs/list.rs
@@ -1,11 +1,11 @@
1use anyhow::{Context, Result}; 1use anyhow::{bail, Context, Result};
2 2
3#[cfg(not(test))] 3#[cfg(not(test))]
4use crate::client::Client; 4use crate::client::Client;
5#[cfg(test)] 5#[cfg(test)]
6use crate::client::MockConnect; 6use crate::client::MockConnect;
7use crate::{ 7use crate::{
8 cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms}, 8 cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms},
9 client::Connect, 9 client::Connect,
10 git::{Repo, RepoActions}, 10 git::{Repo, RepoActions},
11 repo_ref, 11 repo_ref,
@@ -134,7 +134,7 @@ pub async fn launch(
134 .map(std::borrow::ToOwned::to_owned) 134 .map(std::borrow::ToOwned::to_owned)
135 .collect(); 135 .collect();
136 136
137 // TODO: are there outstanding changes to prevent checking out a new branch? 137 confirm_checkout(&git_repo)?;
138 138
139 let most_recent_pr_patch_chain = get_most_recent_patch_with_ancestors(commits_events) 139 let most_recent_pr_patch_chain = get_most_recent_patch_with_ancestors(commits_events)
140 .context("cannot get most recent patch for PR")?; 140 .context("cannot get most recent patch for PR")?;
@@ -192,6 +192,23 @@ pub async fn launch(
192 Ok(()) 192 Ok(())
193} 193}
194 194
195fn confirm_checkout(git_repo: &Repo) -> Result<()> {
196 if !Interactor::default().confirm(
197 PromptConfirmParms::default()
198 .with_prompt("check out branch?")
199 .with_default(true),
200 )? {
201 bail!("Exiting...");
202 }
203
204 if git_repo.has_outstanding_changes()? {
205 bail!(
206 "cannot pull PR branch when repository is not clean. discard or stash (un)staged changes and try again."
207 );
208 }
209 Ok(())
210}
211
195pub fn tag_value(event: &nostr::Event, tag_name: &str) -> Result<String> { 212pub fn tag_value(event: &nostr::Event, tag_name: &str) -> Result<String> {
196 Ok(event 213 Ok(event
197 .tags 214 .tags
diff --git a/tests/prs_list.rs b/tests/prs_list.rs
index 7bc3935..7f753c0 100644
--- a/tests/prs_list.rs
+++ b/tests/prs_list.rs
@@ -141,7 +141,9 @@ mod when_main_branch_is_uptodate {
141 ], 141 ],
142 )?; 142 )?;
143 c.succeeds_with(0, true)?; 143 c.succeeds_with(0, true)?;
144 144 let mut confirm =
145 p.expect_confirm_eventually("check out branch?", Some(true))?;
146 confirm.succeeds_with(None)?;
145 p.expect_end_eventually_and_print()?; 147 p.expect_end_eventually_and_print()?;
146 148
147 for p in [51, 52, 53, 55, 56] { 149 for p in [51, 52, 53, 55, 56] {
@@ -200,6 +202,8 @@ mod when_main_branch_is_uptodate {
200 )?; 202 )?;
201 c.succeeds_with(0, true)?; 203 c.succeeds_with(0, true)?;
202 p.expect("finding commits...\r\n")?; 204 p.expect("finding commits...\r\n")?;
205 let mut confirm = p.expect_confirm("check out branch?", Some(true))?;
206 confirm.succeeds_with(None)?;
203 p.expect("checked out PR branch. pulled 2 new commits\r\n")?; 207 p.expect("checked out PR branch. pulled 2 new commits\r\n")?;
204 p.expect_end()?; 208 p.expect_end()?;
205 209
@@ -302,7 +306,9 @@ mod when_main_branch_is_uptodate {
302 ], 306 ],
303 )?; 307 )?;
304 c.succeeds_with(2, true)?; 308 c.succeeds_with(2, true)?;
305 309 let mut confirm =
310 p.expect_confirm_eventually("check out branch?", Some(true))?;
311 confirm.succeeds_with(None)?;
306 p.expect_end_eventually_and_print()?; 312 p.expect_end_eventually_and_print()?;
307 313
308 for p in [51, 52, 53, 55, 56] { 314 for p in [51, 52, 53, 55, 56] {
@@ -361,6 +367,8 @@ mod when_main_branch_is_uptodate {
361 )?; 367 )?;
362 c.succeeds_with(2, true)?; 368 c.succeeds_with(2, true)?;
363 p.expect("finding commits...\r\n")?; 369 p.expect("finding commits...\r\n")?;
370 let mut confirm = p.expect_confirm("check out branch?", Some(true))?;
371 confirm.succeeds_with(None)?;
364 p.expect("checked out PR branch. pulled 2 new commits\r\n")?; 372 p.expect("checked out PR branch. pulled 2 new commits\r\n")?;
365 p.expect_end()?; 373 p.expect_end()?;
366 374
@@ -478,6 +486,9 @@ mod when_main_branch_is_uptodate {
478 ], 486 ],
479 )?; 487 )?;
480 c.succeeds_with(0, true)?; 488 c.succeeds_with(0, true)?;
489 let mut confirm =
490 p.expect_confirm_eventually("check out branch?", Some(true))?;
491 confirm.succeeds_with(None)?;
481 p.expect_end_eventually_and_print()?; 492 p.expect_end_eventually_and_print()?;
482 493
483 for p in [51, 52, 53, 55, 56] { 494 for p in [51, 52, 53, 55, 56] {
@@ -544,6 +555,8 @@ mod when_main_branch_is_uptodate {
544 )?; 555 )?;
545 c.succeeds_with(0, true)?; 556 c.succeeds_with(0, true)?;
546 p.expect("finding commits...\r\n")?; 557 p.expect("finding commits...\r\n")?;
558 let mut confirm = p.expect_confirm("check out branch?", Some(true))?;
559 confirm.succeeds_with(None)?;
547 p.expect("checked out PR branch. no new commits to pull\r\n")?; 560 p.expect("checked out PR branch. no new commits to pull\r\n")?;
548 p.expect_end()?; 561 p.expect_end()?;
549 562
@@ -632,7 +645,9 @@ mod when_main_branch_is_uptodate {
632 ], 645 ],
633 )?; 646 )?;
634 c.succeeds_with(0, true)?; 647 c.succeeds_with(0, true)?;
635 648 let mut confirm =
649 p.expect_confirm_eventually("check out branch?", Some(true))?;
650 confirm.succeeds_with(None)?;
636 p.expect_end_eventually_and_print()?; 651 p.expect_end_eventually_and_print()?;
637 652
638 for p in [51, 52, 53, 55, 56] { 653 for p in [51, 52, 53, 55, 56] {
@@ -699,6 +714,8 @@ mod when_main_branch_is_uptodate {
699 )?; 714 )?;
700 c.succeeds_with(0, true)?; 715 c.succeeds_with(0, true)?;
701 p.expect("finding commits...\r\n")?; 716 p.expect("finding commits...\r\n")?;
717 let mut confirm = p.expect_confirm("check out branch?", Some(true))?;
718 confirm.succeeds_with(None)?;
702 p.expect("checked out PR branch. pulled 1 new commits\r\n")?; 719 p.expect("checked out PR branch. pulled 1 new commits\r\n")?;
703 p.expect_end()?; 720 p.expect_end()?;
704 721