diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-15 15:14:39 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-15 15:36:05 +0100 |
| commit | b7f48324a02093d0214b6788e8d7005569a08145 (patch) | |
| tree | 119851dc1d1a84b01e75a7dd8269ac6ac3f15b39 | |
| parent | b404cfa7b622297b30ec509dde2aa4b14a4beac3 (diff) | |
feat(remote): list all proposals as `refs/pr/*`
here we can list Pull Requests whose data aren't on the repo relays
without causing `git clone nostr://` to fail.
we can also list proposals of all statuses so that can review
closed proposals.
| -rw-r--r-- | src/bin/git_remote_nostr/list.rs | 54 | ||||
| -rw-r--r-- | tests/git_remote_nostr/list.rs | 9 |
2 files changed, 54 insertions, 9 deletions
diff --git a/src/bin/git_remote_nostr/list.rs b/src/bin/git_remote_nostr/list.rs index 3159e0a..137c13f 100644 --- a/src/bin/git_remote_nostr/list.rs +++ b/src/bin/git_remote_nostr/list.rs | |||
| @@ -10,7 +10,7 @@ use ngit::{ | |||
| 10 | list::{get_ahead_behind, list_from_remotes}, | 10 | list::{get_ahead_behind, list_from_remotes}, |
| 11 | login::get_curent_user, | 11 | login::get_curent_user, |
| 12 | repo_ref::{self}, | 12 | repo_ref::{self}, |
| 13 | utils::{get_open_or_draft_proposals, get_short_git_server_name}, | 13 | utils::{get_all_proposals, get_open_or_draft_proposals, get_short_git_server_name}, |
| 14 | }; | 14 | }; |
| 15 | use repo_ref::RepoRef; | 15 | use repo_ref::RepoRef; |
| 16 | 16 | ||
| @@ -80,10 +80,15 @@ pub async fn run_list( | |||
| 80 | 80 | ||
| 81 | state.retain(|k, _| !k.starts_with("refs/heads/pr/")); | 81 | state.retain(|k, _| !k.starts_with("refs/heads/pr/")); |
| 82 | 82 | ||
| 83 | let proposals_state = | 83 | state.extend( |
| 84 | get_open_and_draft_proposals_state(&term, git_repo, repo_ref, &remote_states).await?; | 84 | // get as refs/heads/pr/<branch-name>(<shorthand-event-id>) |
| 85 | get_open_and_draft_proposals_state(&term, git_repo, repo_ref, &remote_states).await?, | ||
| 86 | ); | ||
| 85 | 87 | ||
| 86 | state.extend(proposals_state); | 88 | state.extend( |
| 89 | // get as refs/pr/<branch-name>(<shorthand-event-id>) | ||
| 90 | get_all_proposals_state(git_repo, repo_ref).await?, | ||
| 91 | ); | ||
| 87 | 92 | ||
| 88 | // TODO 'for push' should we check with the git servers to see if any of them | 93 | // TODO 'for push' should we check with the git servers to see if any of them |
| 89 | // allow push from the user? | 94 | // allow push from the user? |
| @@ -101,6 +106,8 @@ pub async fn run_list( | |||
| 101 | Ok(remote_states) | 106 | Ok(remote_states) |
| 102 | } | 107 | } |
| 103 | 108 | ||
| 109 | /// fetches branches and tags from git servers so patch parent commits can be | ||
| 110 | /// used to build patches with correct commit ids | ||
| 104 | async fn get_open_and_draft_proposals_state( | 111 | async fn get_open_and_draft_proposals_state( |
| 105 | term: &console::Term, | 112 | term: &console::Term, |
| 106 | git_repo: &Repo, | 113 | git_repo: &Repo, |
| @@ -213,3 +220,42 @@ async fn get_open_and_draft_proposals_state( | |||
| 213 | } | 220 | } |
| 214 | Ok(state) | 221 | Ok(state) |
| 215 | } | 222 | } |
| 223 | |||
| 224 | /// we assume latest default branch oid has been fetched so patch parent commits | ||
| 225 | /// are present. doesnt report on proposals failed to recreate | ||
| 226 | async fn get_all_proposals_state( | ||
| 227 | git_repo: &Repo, | ||
| 228 | repo_ref: &RepoRef, | ||
| 229 | ) -> Result<HashMap<String, String>> { | ||
| 230 | let mut state = HashMap::new(); | ||
| 231 | let all_proposals = get_all_proposals(git_repo, repo_ref).await?; | ||
| 232 | let current_user = get_curent_user(git_repo)?; | ||
| 233 | for (_, (proposal, events_to_apply)) in all_proposals { | ||
| 234 | if let Ok(cl) = event_to_cover_letter(&proposal) { | ||
| 235 | if let Ok(mut branch_name) = cl.get_branch_name_with_pr_prefix_and_shorthand_id() { | ||
| 236 | branch_name = if let Some(public_key) = current_user { | ||
| 237 | if proposal.pubkey.eq(&public_key) { | ||
| 238 | format!("pr/{}", cl.branch_name_without_id_or_prefix) | ||
| 239 | } else { | ||
| 240 | branch_name | ||
| 241 | } | ||
| 242 | } else { | ||
| 243 | branch_name | ||
| 244 | }; | ||
| 245 | if let Some(pr_or_pr_update) = events_to_apply | ||
| 246 | .iter() | ||
| 247 | .find(|e| e.kind.eq(&KIND_PULL_REQUEST) || e.kind.eq(&KIND_PULL_REQUEST_UPDATE)) | ||
| 248 | { | ||
| 249 | if let Ok(tip) = tag_value(pr_or_pr_update, "c") { | ||
| 250 | state.insert(format!("refs/{branch_name}"), tip.clone()); | ||
| 251 | } | ||
| 252 | } else if let Ok(tip) = | ||
| 253 | make_commits_for_proposal(git_repo, repo_ref, &events_to_apply) | ||
| 254 | { | ||
| 255 | state.insert(format!("refs/{branch_name}"), tip.clone()); | ||
| 256 | } | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | Ok(state) | ||
| 261 | } | ||
diff --git a/tests/git_remote_nostr/list.rs b/tests/git_remote_nostr/list.rs index c201054..a2dfe8c 100644 --- a/tests/git_remote_nostr/list.rs +++ b/tests/git_remote_nostr/list.rs | |||
| @@ -323,11 +323,10 @@ mod with_state_announcement { | |||
| 323 | FEATURE_BRANCH_NAME_2, | 323 | FEATURE_BRANCH_NAME_2, |
| 324 | FEATURE_BRANCH_NAME_3, | 324 | FEATURE_BRANCH_NAME_3, |
| 325 | ] { | 325 | ] { |
| 326 | pr_refs.push(format!( | 326 | let tip = proposal_creation_repo.get_tip_of_local_branch(name)?; |
| 327 | "{} refs/heads/{}", | 327 | let branch_name = get_proposal_branch_name_from_events(&r55.events, name)?; |
| 328 | proposal_creation_repo.get_tip_of_local_branch(name)?, | 328 | pr_refs.push(format!("{tip} refs/heads/{branch_name}")); |
| 329 | get_proposal_branch_name_from_events(&r55.events, name)?, | 329 | pr_refs.push(format!("{tip} refs/{branch_name}")); |
| 330 | )); | ||
| 331 | } | 330 | } |
| 332 | 331 | ||
| 333 | assert_eq!( | 332 | assert_eq!( |