upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/lib/git_events.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-07-22 17:14:21 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-07-22 17:14:21 +0100
commitf4e1df4c718a3755ffe50e99946996729f3504e9 (patch)
tree9d3d83f42d4d9cf7f18c5451d524a7b995d8053b /src/lib/git_events.rs
parentd1283a6b55826175423bd382a859928e0f92ffe7 (diff)
feat(pr): generate pr event > oversized patch
but only for new proposals
Diffstat (limited to 'src/lib/git_events.rs')
-rw-r--r--src/lib/git_events.rs130
1 files changed, 111 insertions, 19 deletions
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index 09ec040..86b9641 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -1,7 +1,10 @@
1use std::{str::FromStr, sync::Arc}; 1use std::{str::FromStr, sync::Arc};
2 2
3use anyhow::{Context, Result, bail}; 3use anyhow::{Context, Result, bail};
4use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; 4use nostr::{
5 event::UnsignedEvent,
6 nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19},
7};
5use nostr_sdk::{ 8use nostr_sdk::{
6 Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, Tag, TagKind, 9 Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, Tag, TagKind,
7 TagStandard, hashes::sha1::Hash as Sha1Hash, 10 TagStandard, hashes::sha1::Hash as Sha1Hash,
@@ -347,6 +350,111 @@ pub fn event_tag_from_nip19_or_hex(
347 } 350 }
348} 351}
349 352
353pub fn generate_unsigned_pr_event(
354 git_repo: &Repo,
355 repo_ref: &RepoRef,
356 signing_public_key: &PublicKey,
357 commit: &Sha1Hash,
358 clone_url_hint: &[&str],
359 mentions: &[nostr::Tag],
360) -> Result<UnsignedEvent> {
361 let title = git_repo.get_commit_message_summary(commit)?;
362
363 let description = {
364 let mut description = git_repo.get_commit_message(commit)?.trim().to_string();
365 if let Some(remaining_description) = description.strip_prefix(&title) {
366 description = remaining_description.trim().to_string();
367 }
368 description
369 };
370
371 let root_commit = git_repo
372 .get_root_commit()
373 .context("failed to get root commit of the repository")?;
374
375 Ok(EventBuilder::new(KIND_PULL_REQUEST, description)
376 .tags(
377 [
378 repo_ref
379 .maintainers
380 .iter()
381 .map(|m| {
382 Tag::from_standardized(TagStandard::Coordinate {
383 coordinate: Coordinate {
384 kind: nostr::Kind::GitRepoAnnouncement,
385 public_key: *m,
386 identifier: repo_ref.identifier.to_string(),
387 },
388 relay_url: repo_ref.relays.first().cloned(),
389 uppercase: false,
390 })
391 })
392 .collect::<Vec<Tag>>(),
393 mentions.to_vec(),
394 vec![
395 Tag::from_standardized(TagStandard::Subject(title.clone())),
396 Tag::from_standardized(TagStandard::Reference(format!("{root_commit}"))),
397 Tag::custom(
398 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("c")),
399 vec![format!("{commit}")],
400 ),
401 Tag::custom(
402 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("clone")),
403 clone_url_hint
404 .iter()
405 .map(|s| s.to_string())
406 .collect::<Vec<String>>(),
407 ),
408 Tag::custom(
409 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("alt")),
410 vec![format!("git Pull Request: {}", title.clone())],
411 ),
412 ],
413 if let Some(branch_name_tag) = make_branch_name_tag_from_check_out_branch(git_repo)
414 {
415 vec![branch_name_tag]
416 } else {
417 vec![]
418 },
419 repo_ref
420 .maintainers
421 .iter()
422 .map(|pk| Tag::public_key(*pk))
423 .collect(),
424 ]
425 .concat(),
426 )
427 .build(*signing_public_key))
428}
429
430fn make_branch_name_tag_from_check_out_branch(git_repo: &Repo) -> Option<Tag> {
431 if let Ok(branch_name) = git_repo.get_checked_out_branch_name() {
432 if !branch_name.eq("main")
433 && !branch_name.eq("master")
434 && !branch_name.eq("origin/main")
435 && !branch_name.eq("origin/master")
436 {
437 Some(Tag::custom(
438 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("branch-name")),
439 vec![
440 if let Some(branch_name) = branch_name.strip_prefix("pr/") {
441 branch_name.to_string()
442 } else {
443 branch_name
444 }
445 .chars()
446 .take(60)
447 .collect::<String>(),
448 ],
449 ))
450 } else {
451 None
452 }
453 } else {
454 None
455 }
456}
457
350#[allow(clippy::too_many_lines)] 458#[allow(clippy::too_many_lines)]
351pub async fn generate_cover_letter_and_patch_events( 459pub async fn generate_cover_letter_and_patch_events(
352 cover_letter_title_description: Option<(String, String)>, 460 cover_letter_title_description: Option<(String, String)>,
@@ -409,24 +517,8 @@ pub async fn generate_cover_letter_and_patch_events(
409 // eventually a prefix will be needed of the event id to stop 2 proposals with the same name colliding 517 // eventually a prefix will be needed of the event id to stop 2 proposals with the same name colliding
410 // a change like this, or the removal of this tag will require the actual branch name to be tracked 518 // a change like this, or the removal of this tag will require the actual branch name to be tracked
411 // so pulling and pushing still work 519 // so pulling and pushing still work
412 if let Ok(branch_name) = git_repo.get_checked_out_branch_name() { 520 if let Some(branch_name_tag) = make_branch_name_tag_from_check_out_branch(git_repo) {
413 if !branch_name.eq("main") 521 vec![branch_name_tag]
414 && !branch_name.eq("master")
415 && !branch_name.eq("origin/main")
416 && !branch_name.eq("origin/master")
417 {
418 vec![
419 Tag::custom(
420 nostr::TagKind::Custom(std::borrow::Cow::Borrowed("branch-name")),
421 vec![if let Some(branch_name) = branch_name.strip_prefix("pr/") {
422 branch_name.to_string()
423 } else {
424 branch_name
425 }.chars().take(60).collect::<String>()],
426 ),
427 ]
428 }
429 else { vec![] }
430 } else { 522 } else {
431 vec![] 523 vec![]
432 }, 524 },