diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-12-12 15:15:58 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-12-12 17:03:03 +0000 |
| commit | aeb164a6890a433828739bde23d3477b78e532a4 (patch) | |
| tree | 5bd86e0971c2809eaeee9b3340513fe0bc460c84 | |
| parent | aefaadcdf8891d8fb235f87e14c498016b3fbcef (diff) | |
feat(push): merge event for applied commits
publish a merge event when the commit author signature and timestamp
match patches within an open proposal
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index 2921387..98e93ca 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs | |||
| @@ -1031,7 +1031,7 @@ async fn get_merged_proposals_info( | |||
| 1031 | } else { | 1031 | } else { |
| 1032 | // three way merge or fast forward merge commits | 1032 | // three way merge or fast forward merge commits |
| 1033 | // note: ahead included commits of three-way merged branches | 1033 | // note: ahead included commits of three-way merged branches |
| 1034 | for patch_event in available_patches | 1034 | let mut matching_patches = available_patches |
| 1035 | .iter() | 1035 | .iter() |
| 1036 | .filter(|e| { | 1036 | .filter(|e| { |
| 1037 | e.tags.iter().any(|t| { | 1037 | e.tags.iter().any(|t| { |
| @@ -1040,8 +1040,8 @@ async fn get_merged_proposals_info( | |||
| 1040 | && t.as_slice()[1].eq(&commit_hash.to_string()) | 1040 | && t.as_slice()[1].eq(&commit_hash.to_string()) |
| 1041 | }) | 1041 | }) |
| 1042 | }) | 1042 | }) |
| 1043 | .collect::<Vec<&Event>>() | 1043 | .collect::<Vec<&Event>>(); |
| 1044 | { | 1044 | for patch_event in &matching_patches { |
| 1045 | if let Ok((proposal_id, revision_id)) = | 1045 | if let Ok((proposal_id, revision_id)) = |
| 1046 | get_proposal_and_revision_root_from_patch(git_repo, patch_event).await | 1046 | get_proposal_and_revision_root_from_patch(git_repo, patch_event).await |
| 1047 | { | 1047 | { |
| @@ -1058,11 +1058,59 @@ async fn get_merged_proposals_info( | |||
| 1058 | } | 1058 | } |
| 1059 | } | 1059 | } |
| 1060 | } | 1060 | } |
| 1061 | // applied commits - this is done after so that merged revisions take priority | ||
| 1062 | if matching_patches.is_empty() { | ||
| 1063 | let author = git_repo.get_commit_author(commit_hash)?; | ||
| 1064 | matching_patches = available_patches | ||
| 1065 | .iter() | ||
| 1066 | .filter(|e| { | ||
| 1067 | if let Ok(patch_author) = get_patch_author(e) { | ||
| 1068 | patch_author == author | ||
| 1069 | } else { | ||
| 1070 | false | ||
| 1071 | } | ||
| 1072 | }) | ||
| 1073 | .collect::<Vec<&Event>>(); | ||
| 1074 | for patch_event in matching_patches { | ||
| 1075 | if let Ok((proposal_id, revision_id)) = | ||
| 1076 | get_proposal_and_revision_root_from_patch(git_repo, patch_event).await | ||
| 1077 | { | ||
| 1078 | let (entry_revision_id, merged_patches) = | ||
| 1079 | proposals.entry(proposal_id).or_default(); | ||
| 1080 | // ignore revisions without all the applied commits | ||
| 1081 | if entry_revision_id == &revision_id { | ||
| 1082 | merged_patches.insert( | ||
| 1083 | *commit_hash, | ||
| 1084 | MergedPRCommitType::PatchApplied { | ||
| 1085 | event_id: patch_event.id, | ||
| 1086 | }, | ||
| 1087 | ); | ||
| 1088 | } | ||
| 1089 | } | ||
| 1090 | } | ||
| 1091 | } | ||
| 1061 | } | 1092 | } |
| 1062 | } | 1093 | } |
| 1063 | Ok(proposals) | 1094 | Ok(proposals) |
| 1064 | } | 1095 | } |
| 1065 | 1096 | ||
| 1097 | fn get_patch_author(event: &Event) -> Result<Vec<String>> { | ||
| 1098 | for t in event.tags.clone() { | ||
| 1099 | match t.as_slice() { | ||
| 1100 | [tag, name, email, unixtime, offset] if tag == "author" => { | ||
| 1101 | return Ok(vec![ | ||
| 1102 | name.to_string(), | ||
| 1103 | email.to_string(), | ||
| 1104 | unixtime.to_string(), | ||
| 1105 | offset.to_string(), | ||
| 1106 | ]); | ||
| 1107 | } | ||
| 1108 | _ => (), | ||
| 1109 | } | ||
| 1110 | } | ||
| 1111 | bail!("could not find valid author tag") | ||
| 1112 | } | ||
| 1113 | |||
| 1066 | async fn create_merge_events( | 1114 | async fn create_merge_events( |
| 1067 | term: &console::Term, | 1115 | term: &console::Term, |
| 1068 | git_repo: &Repo, | 1116 | git_repo: &Repo, |
| @@ -1085,6 +1133,17 @@ async fn create_merge_events( | |||
| 1085 | ) | 1133 | ) |
| 1086 | .as_str(), | 1134 | .as_str(), |
| 1087 | )?; | 1135 | )?; |
| 1136 | } else if merged_patches | ||
| 1137 | .values() | ||
| 1138 | .any(|m| matches!(m, MergedPRCommitType::PatchApplied { .. })) | ||
| 1139 | { | ||
| 1140 | term.write_line( | ||
| 1141 | format!( | ||
| 1142 | "applied commits from proposal: create nostr proposal status event for {}", | ||
| 1143 | event_to_cover_letter(&proposal)?.get_branch_name()?, | ||
| 1144 | ) | ||
| 1145 | .as_str(), | ||
| 1146 | )?; | ||
| 1088 | } else { | 1147 | } else { |
| 1089 | term.write_line( | 1148 | term.write_line( |
| 1090 | format!( | 1149 | format!( |
| @@ -1123,6 +1182,12 @@ async fn create_merge_events( | |||
| 1123 | | MergedPRCommitType::PatchCommit { event_id } => Some(*event_id), | 1182 | | MergedPRCommitType::PatchCommit { event_id } => Some(*event_id), |
| 1124 | }) | 1183 | }) |
| 1125 | .collect(), | 1184 | .collect(), |
| 1185 | !merged_patches | ||
| 1186 | .iter() | ||
| 1187 | .any(|(_, m)| *m == MergedPRCommitType::MergeCommit) | ||
| 1188 | && merged_patches | ||
| 1189 | .values() | ||
| 1190 | .any(|m| matches!(m, MergedPRCommitType::PatchApplied { .. })), | ||
| 1126 | ) | 1191 | ) |
| 1127 | .await?, | 1192 | .await?, |
| 1128 | ); | 1193 | ); |
| @@ -1130,7 +1195,7 @@ async fn create_merge_events( | |||
| 1130 | Ok(events) | 1195 | Ok(events) |
| 1131 | } | 1196 | } |
| 1132 | 1197 | ||
| 1133 | #[derive(PartialEq)] | 1198 | #[derive(PartialEq, Debug)] |
| 1134 | enum MergedPRCommitType { | 1199 | enum MergedPRCommitType { |
| 1135 | MergeCommit, | 1200 | MergeCommit, |
| 1136 | PatchCommit { event_id: EventId }, | 1201 | PatchCommit { event_id: EventId }, |
| @@ -1144,6 +1209,7 @@ async fn create_merge_status( | |||
| 1144 | revision: &Option<Event>, | 1209 | revision: &Option<Event>, |
| 1145 | merge_commits: Vec<Sha1Hash>, | 1210 | merge_commits: Vec<Sha1Hash>, |
| 1146 | merged_patches: Vec<EventId>, | 1211 | merged_patches: Vec<EventId>, |
| 1212 | applied: bool, | ||
| 1147 | ) -> Result<Event> { | 1213 | ) -> Result<Event> { |
| 1148 | let mut public_keys = repo_ref | 1214 | let mut public_keys = repo_ref |
| 1149 | .maintainers | 1215 | .maintainers |
| @@ -1205,7 +1271,11 @@ async fn create_merge_status( | |||
| 1205 | repo_ref.root_commit.to_string(), | 1271 | repo_ref.root_commit.to_string(), |
| 1206 | )), | 1272 | )), |
| 1207 | Tag::custom( | 1273 | Tag::custom( |
| 1208 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed("merge-commit-id")), | 1274 | nostr::TagKind::Custom(std::borrow::Cow::Borrowed(if applied { |
| 1275 | "applied-as-commits" | ||
| 1276 | } else { | ||
| 1277 | "merge-commit-id" | ||
| 1278 | })), | ||
| 1209 | merge_commits | 1279 | merge_commits |
| 1210 | .iter() | 1280 | .iter() |
| 1211 | .map(|merge_commit| format!("{merge_commit}")) | 1281 | .map(|merge_commit| format!("{merge_commit}")) |