diff options
Diffstat (limited to 'src/sub_commands/send.rs')
| -rw-r--r-- | src/sub_commands/send.rs | 96 |
1 files changed, 87 insertions, 9 deletions
diff --git a/src/sub_commands/send.rs b/src/sub_commands/send.rs index 105f87a..c9c81ee 100644 --- a/src/sub_commands/send.rs +++ b/src/sub_commands/send.rs | |||
| @@ -1,9 +1,12 @@ | |||
| 1 | use std::time::Duration; | 1 | use std::{str::FromStr, time::Duration}; |
| 2 | 2 | ||
| 3 | use anyhow::{bail, Context, Result}; | 3 | use anyhow::{bail, Context, Result}; |
| 4 | use futures::future::join_all; | 4 | use futures::future::join_all; |
| 5 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; | 5 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; |
| 6 | use nostr::{prelude::sha1::Hash as Sha1Hash, EventBuilder, Marker, Tag, TagKind}; | 6 | use nostr::{ |
| 7 | nips::nip19::Nip19, prelude::sha1::Hash as Sha1Hash, EventBuilder, FromBech32, Marker, Tag, | ||
| 8 | TagKind, UncheckedUrl, | ||
| 9 | }; | ||
| 7 | 10 | ||
| 8 | use super::list::tag_value; | 11 | use super::list::tag_value; |
| 9 | #[cfg(not(test))] | 12 | #[cfg(not(test))] |
| @@ -25,6 +28,10 @@ pub struct SubCommandArgs { | |||
| 25 | /// starting commit (commits since in current branch) or commit range, like | 28 | /// starting commit (commits since in current branch) or commit range, like |
| 26 | /// in `git format-patch` | 29 | /// in `git format-patch` |
| 27 | starting_commit: String, | 30 | starting_commit: String, |
| 31 | #[clap(long)] | ||
| 32 | /// nevent or event id of an existing proposal for which this is a new | ||
| 33 | /// version | ||
| 34 | in_reply_to: Option<String>, | ||
| 28 | /// optional cover letter title | 35 | /// optional cover letter title |
| 29 | #[clap(short, long)] | 36 | #[clap(short, long)] |
| 30 | title: Option<String>, | 37 | title: Option<String>, |
| @@ -161,6 +168,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 161 | &commits, | 168 | &commits, |
| 162 | &keys, | 169 | &keys, |
| 163 | &repo_ref, | 170 | &repo_ref, |
| 171 | &args.in_reply_to, | ||
| 164 | )?; | 172 | )?; |
| 165 | 173 | ||
| 166 | println!( | 174 | println!( |
| @@ -390,6 +398,7 @@ pub fn generate_cover_letter_and_patch_events( | |||
| 390 | commits: &Vec<Sha1Hash>, | 398 | commits: &Vec<Sha1Hash>, |
| 391 | keys: &nostr::Keys, | 399 | keys: &nostr::Keys, |
| 392 | repo_ref: &RepoRef, | 400 | repo_ref: &RepoRef, |
| 401 | in_reply_to: &Option<String>, | ||
| 393 | ) -> Result<Vec<nostr::Event>> { | 402 | ) -> Result<Vec<nostr::Event>> { |
| 394 | let root_commit = git_repo | 403 | let root_commit = git_repo |
| 395 | .get_root_commit() | 404 | .get_root_commit() |
| @@ -418,8 +427,19 @@ pub fn generate_cover_letter_and_patch_events( | |||
| 418 | }, | 427 | }, |
| 419 | Tag::Reference(format!("{root_commit}")), | 428 | Tag::Reference(format!("{root_commit}")), |
| 420 | Tag::Hashtag("cover-letter".to_string()), | 429 | Tag::Hashtag("cover-letter".to_string()), |
| 421 | Tag::Hashtag("root".to_string()), | ||
| 422 | ], | 430 | ], |
| 431 | if let Some(event_ref) = in_reply_to.clone() { | ||
| 432 | vec![ | ||
| 433 | Tag::Hashtag("root".to_string()), | ||
| 434 | Tag::Hashtag("revision-root".to_string()), | ||
| 435 | // TODO check if id is for a root proposal (perhaps its for an issue?) | ||
| 436 | e_tag_from_nip19(&event_ref,"proposal",nostr::Marker::Reply)?, | ||
| 437 | ] | ||
| 438 | } else { | ||
| 439 | vec![ | ||
| 440 | Tag::Hashtag("root".to_string()), | ||
| 441 | ] | ||
| 442 | }, | ||
| 423 | // this is not strictly needed but makes for prettier branch names | 443 | // this is not strictly needed but makes for prettier branch names |
| 424 | // eventually a prefix will be needed of the event id to stop 2 proposals with the same name colliding | 444 | // eventually a prefix will be needed of the event id to stop 2 proposals with the same name colliding |
| 425 | // a change like this, or the removal of this tag will require the actual branch name to be tracked | 445 | // a change like this, or the removal of this tag will require the actual branch name to be tracked |
| @@ -466,6 +486,7 @@ pub fn generate_cover_letter_and_patch_events( | |||
| 466 | } else { | 486 | } else { |
| 467 | None | 487 | None |
| 468 | }, | 488 | }, |
| 489 | in_reply_to, | ||
| 469 | ) | 490 | ) |
| 470 | .context("failed to generate patch event")?, | 491 | .context("failed to generate patch event")?, |
| 471 | ); | 492 | ); |
| @@ -473,6 +494,51 @@ pub fn generate_cover_letter_and_patch_events( | |||
| 473 | Ok(events) | 494 | Ok(events) |
| 474 | } | 495 | } |
| 475 | 496 | ||
| 497 | fn e_tag_from_nip19( | ||
| 498 | reference: &str, | ||
| 499 | reference_name: &str, | ||
| 500 | marker: nostr::Marker, | ||
| 501 | ) -> Result<nostr::Tag> { | ||
| 502 | let mut bech32 = reference.to_string(); | ||
| 503 | loop { | ||
| 504 | if bech32.is_empty() { | ||
| 505 | bech32 = Interactor::default().input( | ||
| 506 | PromptInputParms::default().with_prompt(&format!("{reference_name} nevent")), | ||
| 507 | )?; | ||
| 508 | } | ||
| 509 | |||
| 510 | if let Ok(nip19) = Nip19::from_bech32(bech32.clone()) { | ||
| 511 | match nip19 { | ||
| 512 | Nip19::Event(n) => { | ||
| 513 | break Ok(nostr::Tag::Event { | ||
| 514 | event_id: n.event_id, | ||
| 515 | relay_url: n.relays.first().map(UncheckedUrl::new), | ||
| 516 | marker: Some(marker), | ||
| 517 | }); | ||
| 518 | } | ||
| 519 | Nip19::EventId(id) => { | ||
| 520 | break Ok(nostr::Tag::Event { | ||
| 521 | event_id: id, | ||
| 522 | relay_url: None, | ||
| 523 | marker: Some(marker), | ||
| 524 | }); | ||
| 525 | } | ||
| 526 | _ => {} | ||
| 527 | } | ||
| 528 | } | ||
| 529 | if let Ok(id) = nostr::EventId::from_str(&bech32) { | ||
| 530 | break Ok(nostr::Tag::Event { | ||
| 531 | event_id: id, | ||
| 532 | relay_url: None, | ||
| 533 | marker: Some(marker), | ||
| 534 | }); | ||
| 535 | } | ||
| 536 | println!("not a valid {reference_name} event reference"); | ||
| 537 | |||
| 538 | bech32 = String::new(); | ||
| 539 | } | ||
| 540 | } | ||
| 541 | |||
| 476 | pub struct CoverLetter { | 542 | pub struct CoverLetter { |
| 477 | pub title: String, | 543 | pub title: String, |
| 478 | pub description: String, | 544 | pub description: String, |
| @@ -565,6 +631,7 @@ pub fn generate_patch_event( | |||
| 565 | parent_patch_event_id: Option<nostr::EventId>, | 631 | parent_patch_event_id: Option<nostr::EventId>, |
| 566 | series_count: Option<(u64, u64)>, | 632 | series_count: Option<(u64, u64)>, |
| 567 | branch_name: Option<String>, | 633 | branch_name: Option<String>, |
| 634 | in_reply_to: &Option<String>, | ||
| 568 | ) -> Result<nostr::Event> { | 635 | ) -> Result<nostr::Event> { |
| 569 | let commit_parent = git_repo | 636 | let commit_parent = git_repo |
| 570 | .get_commit_parent(commit) | 637 | .get_commit_parent(commit) |
| @@ -592,16 +659,27 @@ pub fn generate_patch_event( | |||
| 592 | // code that makes it into the main branch, assuming | 659 | // code that makes it into the main branch, assuming |
| 593 | // the commit id is correct | 660 | // the commit id is correct |
| 594 | Tag::Reference(commit.to_string()), | 661 | Tag::Reference(commit.to_string()), |
| 662 | ], | ||
| 595 | 663 | ||
| 596 | if let Some(thread_event_id) = thread_event_id { Tag::Event { | 664 | if let Some(thread_event_id) = thread_event_id { |
| 665 | vec![Tag::Event { | ||
| 597 | event_id: thread_event_id, | 666 | event_id: thread_event_id, |
| 598 | relay_url: relay_hint.clone(), | 667 | relay_url: relay_hint.clone(), |
| 599 | marker: Some(Marker::Root), | 668 | marker: Some(Marker::Root), |
| 600 | } } | 669 | }] |
| 601 | else { | 670 | } else if let Some(event_ref) = in_reply_to.clone() { |
| 602 | Tag::Hashtag("root".to_string()) | 671 | vec![ |
| 603 | }, | 672 | Tag::Hashtag("root".to_string()), |
| 604 | ], | 673 | Tag::Hashtag("revision-root".to_string()), |
| 674 | // TODO check if id is for a root proposal (perhaps its for an issue?) | ||
| 675 | e_tag_from_nip19(&event_ref,"proposal",nostr::Marker::Reply)?, | ||
| 676 | ] | ||
| 677 | } else { | ||
| 678 | vec![ | ||
| 679 | Tag::Hashtag("root".to_string()), | ||
| 680 | ] | ||
| 681 | }, | ||
| 682 | |||
| 605 | if let Some(id) = parent_patch_event_id { | 683 | if let Some(id) = parent_patch_event_id { |
| 606 | vec![Tag::Event { | 684 | vec![Tag::Event { |
| 607 | event_id: id, | 685 | event_id: id, |