diff options
Diffstat (limited to 'src/sub_commands/prs/create.rs')
| -rw-r--r-- | src/sub_commands/prs/create.rs | 143 |
1 files changed, 99 insertions, 44 deletions
diff --git a/src/sub_commands/prs/create.rs b/src/sub_commands/prs/create.rs index ad6a61a..0f7cbda 100644 --- a/src/sub_commands/prs/create.rs +++ b/src/sub_commands/prs/create.rs | |||
| @@ -13,7 +13,9 @@ use crate::{ | |||
| 13 | cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms}, | 13 | cli_interactor::{Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms}, |
| 14 | client::Connect, | 14 | client::Connect, |
| 15 | git::{Repo, RepoActions}, | 15 | git::{Repo, RepoActions}, |
| 16 | login, repo_ref, Cli, | 16 | login, |
| 17 | repo_ref::{self, RepoRef, REPO_REF_KIND}, | ||
| 18 | Cli, | ||
| 17 | }; | 19 | }; |
| 18 | 20 | ||
| 19 | #[derive(Debug, clap::Args)] | 21 | #[derive(Debug, clap::Args)] |
| @@ -96,9 +98,6 @@ pub async fn launch( | |||
| 96 | 98 | ||
| 97 | client.set_keys(&keys).await; | 99 | client.set_keys(&keys).await; |
| 98 | 100 | ||
| 99 | let events = | ||
| 100 | generate_pr_and_patch_events(&title, &description, &to_branch, &git_repo, &ahead, &keys)?; | ||
| 101 | |||
| 102 | let repo_ref = repo_ref::fetch( | 101 | let repo_ref = repo_ref::fetch( |
| 103 | &git_repo, | 102 | &git_repo, |
| 104 | git_repo | 103 | git_repo |
| @@ -110,6 +109,16 @@ pub async fn launch( | |||
| 110 | ) | 109 | ) |
| 111 | .await?; | 110 | .await?; |
| 112 | 111 | ||
| 112 | let events = generate_pr_and_patch_events( | ||
| 113 | &title, | ||
| 114 | &description, | ||
| 115 | &to_branch, | ||
| 116 | &git_repo, | ||
| 117 | &ahead, | ||
| 118 | &keys, | ||
| 119 | &repo_ref, | ||
| 120 | )?; | ||
| 121 | |||
| 113 | println!( | 122 | println!( |
| 114 | "posting 1 pull request with {} commits...", | 123 | "posting 1 pull request with {} commits...", |
| 115 | events.len() - 1 | 124 | events.len() - 1 |
| @@ -299,7 +308,7 @@ mod tests_unique_and_duplicate { | |||
| 299 | } | 308 | } |
| 300 | 309 | ||
| 301 | pub static PR_KIND: u64 = 318; | 310 | pub static PR_KIND: u64 = 318; |
| 302 | pub static PATCH_KIND: u64 = 317; | 311 | pub static PATCH_KIND: u64 = 1617; |
| 303 | 312 | ||
| 304 | pub fn generate_pr_and_patch_events( | 313 | pub fn generate_pr_and_patch_events( |
| 305 | title: &str, | 314 | title: &str, |
| @@ -308,6 +317,7 @@ pub fn generate_pr_and_patch_events( | |||
| 308 | git_repo: &Repo, | 317 | git_repo: &Repo, |
| 309 | commits: &Vec<Sha1Hash>, | 318 | commits: &Vec<Sha1Hash>, |
| 310 | keys: &nostr::Keys, | 319 | keys: &nostr::Keys, |
| 320 | repo_ref: &RepoRef, | ||
| 311 | ) -> Result<Vec<nostr::Event>> { | 321 | ) -> Result<Vec<nostr::Event>> { |
| 312 | let root_commit = git_repo | 322 | let root_commit = git_repo |
| 313 | .get_root_commit(to_branch) | 323 | .get_root_commit(to_branch) |
| @@ -342,8 +352,16 @@ pub fn generate_pr_and_patch_events( | |||
| 342 | let mut events = vec![pr_event]; | 352 | let mut events = vec![pr_event]; |
| 343 | for commit in commits { | 353 | for commit in commits { |
| 344 | events.push( | 354 | events.push( |
| 345 | generate_patch_event(git_repo, &root_commit, commit, pr_event_id, keys) | 355 | generate_patch_event( |
| 346 | .context("failed to generate patch event")?, | 356 | git_repo, |
| 357 | &root_commit, | ||
| 358 | commit, | ||
| 359 | pr_event_id, | ||
| 360 | keys, | ||
| 361 | repo_ref, | ||
| 362 | events.last().map(nostr::Event::id), | ||
| 363 | ) | ||
| 364 | .context("failed to generate patch event")?, | ||
| 347 | ); | 365 | ); |
| 348 | } | 366 | } |
| 349 | Ok(events) | 367 | Ok(events) |
| @@ -353,55 +371,92 @@ pub fn generate_patch_event( | |||
| 353 | git_repo: &Repo, | 371 | git_repo: &Repo, |
| 354 | root_commit: &Sha1Hash, | 372 | root_commit: &Sha1Hash, |
| 355 | commit: &Sha1Hash, | 373 | commit: &Sha1Hash, |
| 356 | pr_event_id: nostr::EventId, | 374 | thread_event_id: nostr::EventId, |
| 357 | keys: &nostr::Keys, | 375 | keys: &nostr::Keys, |
| 376 | repo_ref: &RepoRef, | ||
| 377 | parent_patch_event_id: Option<nostr::EventId>, | ||
| 358 | ) -> Result<nostr::Event> { | 378 | ) -> Result<nostr::Event> { |
| 359 | let commit_parent = git_repo | 379 | let commit_parent = git_repo |
| 360 | .get_commit_parent(commit) | 380 | .get_commit_parent(commit) |
| 361 | .context("failed to get parent commit")?; | 381 | .context("failed to get parent commit")?; |
| 382 | let relay_hint = repo_ref.relays.first().map(nostr::UncheckedUrl::from); | ||
| 362 | EventBuilder::new( | 383 | EventBuilder::new( |
| 363 | nostr::event::Kind::Custom(PATCH_KIND), | 384 | nostr::event::Kind::Custom(PATCH_KIND), |
| 364 | git_repo | 385 | git_repo |
| 365 | .make_patch_from_commit(commit) | 386 | .make_patch_from_commit(commit) |
| 366 | .context(format!("cannot make patch for commit {commit}"))?, | 387 | .context(format!("cannot make patch for commit {commit}"))?, |
| 367 | [ | 388 | [ |
| 368 | Tag::Reference(format!("r-{root_commit}")), | 389 | vec![ |
| 369 | Tag::Reference(commit.to_string()), | 390 | Tag::A { |
| 370 | Tag::Reference(commit_parent.to_string()), | 391 | kind: nostr::Kind::Custom(REPO_REF_KIND), |
| 371 | Tag::Event { | 392 | public_key: *repo_ref.maintainers.first() |
| 372 | event_id: pr_event_id, | 393 | .context("repo reference should always have at least one maintainer - the issuer of the repo event") |
| 373 | relay_url: None, // TODO: add relay | 394 | ?, |
| 374 | marker: Some(Marker::Root), | 395 | identifier: repo_ref.identifier.to_string(), |
| 396 | relay_url: relay_hint.clone(), | ||
| 397 | }, | ||
| 398 | Tag::Reference(format!("{root_commit}")), | ||
| 399 | // commit id reference is a trade-off. its now | ||
| 400 | // unclear which one is the root commit id but it | ||
| 401 | // enables easier location of code comments againt | ||
| 402 | // code that makes it into the main branch, assuming | ||
| 403 | // the commit id is correct | ||
| 404 | Tag::Reference(commit.to_string()), | ||
| 405 | |||
| 406 | Tag::Event { | ||
| 407 | event_id: thread_event_id, | ||
| 408 | relay_url: relay_hint.clone(), | ||
| 409 | marker: Some(Marker::Root), | ||
| 410 | }, | ||
| 411 | ], | ||
| 412 | if let Some(id) = parent_patch_event_id { | ||
| 413 | vec![Tag::Event { | ||
| 414 | event_id: id, | ||
| 415 | relay_url: relay_hint.clone(), | ||
| 416 | marker: Some(Marker::Reply), | ||
| 417 | }] | ||
| 418 | } else { | ||
| 419 | vec![] | ||
| 375 | }, | 420 | }, |
| 376 | Tag::Generic( | 421 | // whilst it is in nip34 draft to tag the maintainers |
| 377 | TagKind::Custom("commit".to_string()), | 422 | // I'm not sure it is a good idea because if they are |
| 378 | vec![commit.to_string()], | 423 | // interested in all patches then their specialised |
| 379 | ), | 424 | // client should subscribe to patches tagged with the |
| 380 | Tag::Generic( | 425 | // repo reference. maintainers of large repos will not |
| 381 | TagKind::Custom("parent-commit".to_string()), | 426 | // be interested in every patch. |
| 382 | vec![commit_parent.to_string()], | 427 | repo_ref.maintainers |
| 383 | ), | 428 | .iter() |
| 384 | Tag::Generic( | 429 | .map(|pk| Tag::public_key(*pk)) |
| 385 | TagKind::Custom("commit-sig".to_string()), | 430 | .collect(), |
| 386 | vec![ | 431 | vec![ |
| 387 | git_repo | 432 | Tag::Generic( |
| 388 | .extract_commit_pgp_signature(commit) | 433 | TagKind::Custom("commit".to_string()), |
| 389 | .unwrap_or_default(), | 434 | vec![commit.to_string()], |
| 390 | ], | 435 | ), |
| 391 | ), | 436 | Tag::Generic( |
| 392 | Tag::Description(git_repo.get_commit_message(commit)?.to_string()), | 437 | TagKind::Custom("parent-commit".to_string()), |
| 393 | Tag::Generic( | 438 | vec![commit_parent.to_string()], |
| 394 | TagKind::Custom("author".to_string()), | 439 | ), |
| 395 | git_repo.get_commit_author(commit)?, | 440 | Tag::Generic( |
| 396 | ), | 441 | TagKind::Custom("commit-pgp-sig".to_string()), |
| 397 | Tag::Generic( | 442 | vec![ |
| 398 | TagKind::Custom("committer".to_string()), | 443 | git_repo |
| 399 | git_repo.get_commit_comitter(commit)?, | 444 | .extract_commit_pgp_signature(commit) |
| 400 | ), | 445 | .unwrap_or_default(), |
| 401 | // TODO: add Repo event tags | 446 | ], |
| 402 | // TODO: people tag maintainers | 447 | ), |
| 403 | // TODO: add relay tags | 448 | Tag::Description(git_repo.get_commit_message(commit)?.to_string()), |
| 404 | ], | 449 | Tag::Generic( |
| 450 | TagKind::Custom("author".to_string()), | ||
| 451 | git_repo.get_commit_author(commit)?, | ||
| 452 | ), | ||
| 453 | Tag::Generic( | ||
| 454 | TagKind::Custom("committer".to_string()), | ||
| 455 | git_repo.get_commit_comitter(commit)?, | ||
| 456 | ), | ||
| 457 | ], | ||
| 458 | ] | ||
| 459 | .concat(), | ||
| 405 | ) | 460 | ) |
| 406 | .to_event(keys) | 461 | .to_event(keys) |
| 407 | .context("failed to sign event") | 462 | .context("failed to sign event") |