diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-01-23 00:00:00 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-01-23 00:00:00 +0000 |
| commit | 7799b0edd16b0c97eb58ba2de62be27134a76122 (patch) | |
| tree | 1cacb8026e251f51279b6a6be4f57a3cc9b978d2 /src | |
| parent | c543b2f25b6893e5dce6111bc12d9812099251ba (diff) | |
feat(prs-list): check for clean repo
before checking out PR branch
add confirm prompt before checking out branch and applying changes
Diffstat (limited to 'src')
| -rw-r--r-- | src/git.rs | 14 | ||||
| -rw-r--r-- | src/sub_commands/prs/list.rs | 23 |
2 files changed, 33 insertions, 4 deletions
| @@ -3,7 +3,7 @@ use std::path::PathBuf; | |||
| 3 | use std::{env::current_dir, path::Path}; | 3 | use std::{env::current_dir, path::Path}; |
| 4 | 4 | ||
| 5 | use anyhow::{bail, Context, Result}; | 5 | use anyhow::{bail, Context, Result}; |
| 6 | use git2::{Oid, Revwalk}; | 6 | use git2::{DiffOptions, Oid, Revwalk}; |
| 7 | use nostr::prelude::{sha1::Hash as Sha1Hash, Hash}; | 7 | use nostr::prelude::{sha1::Hash as Sha1Hash, Hash}; |
| 8 | 8 | ||
| 9 | use crate::sub_commands::prs::list::tag_value; | 9 | use 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 @@ | |||
| 1 | use anyhow::{Context, Result}; | 1 | use anyhow::{bail, Context, Result}; |
| 2 | 2 | ||
| 3 | #[cfg(not(test))] | 3 | #[cfg(not(test))] |
| 4 | use crate::client::Client; | 4 | use crate::client::Client; |
| 5 | #[cfg(test)] | 5 | #[cfg(test)] |
| 6 | use crate::client::MockConnect; | 6 | use crate::client::MockConnect; |
| 7 | use crate::{ | 7 | use 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 | ||
| 195 | fn 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 | |||
| 195 | pub fn tag_value(event: &nostr::Event, tag_name: &str) -> Result<String> { | 212 | pub fn tag_value(event: &nostr::Event, tag_name: &str) -> Result<String> { |
| 196 | Ok(event | 213 | Ok(event |
| 197 | .tags | 214 | .tags |