From 5f45edbebe310decb06f955d95665a6ad387c6cb Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sat, 31 May 2025 15:34:21 +0100 Subject: feat(push): prevent push if no ann event To ensure additional maintainers publish an annoucement event, require it for them to push --- src/bin/git_remote_nostr/push.rs | 14 ++++++++++++++ src/bin/ngit/sub_commands/init.rs | 1 + src/lib/client.rs | 6 ++++++ src/lib/repo_ref.rs | 9 +++++++++ 4 files changed, 30 insertions(+) (limited to 'src') diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index c4953f8..56bf177 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs @@ -199,6 +199,20 @@ async fn create_and_publish_events( if proposal_refspecs.is_empty() { return Ok((vec![], true)); } + } else if repo_ref + .maintainers_without_annoucnement + .clone() + .is_some_and(|ms| ms.contains(&user_ref.public_key)) + { + for refspec in git_server_refspecs { + let (_, to) = refspec_to_from_to(refspec).unwrap(); + eprintln!( + "error {to} you must run `ngit init` before pushing updates. you've been offered maintainership but you must accept it before pushing", + ); + } + if proposal_refspecs.is_empty() { + return Ok((vec![], true)); + } } let mut events = vec![]; diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs index 1d9fda0..aea4f8b 100644 --- a/src/bin/ngit/sub_commands/init.rs +++ b/src/bin/ngit/sub_commands/init.rs @@ -703,6 +703,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { relays: relays.clone(), blossoms, trusted_maintainer: user_ref.public_key, + maintainers_without_annoucnement: None, maintainers: maintainers.clone(), events: HashMap::new(), nostr_git_url: None, diff --git a/src/lib/client.rs b/src/lib/client.rs index bfa7b33..3b613b6 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs @@ -985,6 +985,9 @@ pub async fn get_repo_ref_from_cache( .collect(); let mut seen_blossoms: HashSet = HashSet::from_iter(blossoms.iter().cloned()); + // also set maintainers_without_annoucnement + let mut maintainers_without_annoucnement: Vec = vec![]; + for m in &maintainers { if let Some(event) = repo_events.iter().find(|e| e.pubkey == *m) { if let Ok(m_repo_ref) = RepoRef::try_from((event.clone(), None)) { @@ -1004,6 +1007,8 @@ pub async fn get_repo_ref_from_cache( } } } + } else { + maintainers_without_annoucnement.push(*m); } } @@ -1014,6 +1019,7 @@ pub async fn get_repo_ref_from_cache( relays, git_server, events, + maintainers_without_annoucnement: Some(maintainers_without_annoucnement), ..repo_ref }) } diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index bf52cda..78968b4 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs @@ -42,6 +42,8 @@ pub struct RepoRef { pub blossoms: Vec, pub maintainers: Vec, pub trusted_maintainer: PublicKey, + // set to None if not known + pub maintainers_without_annoucnement: Option>, pub events: HashMap, pub nostr_git_url: Option, } @@ -49,6 +51,11 @@ pub struct RepoRef { impl TryFrom<(nostr::Event, Option)> for RepoRef { type Error = anyhow::Error; + /* + * this could do with a refactor to intergrate enhancements made by + * `get_repo_ref_from_cache`. Other than tests, its only used there and the + * changes made by that function are important. + */ fn try_from((event, trusted_maintainer): (nostr::Event, Option)) -> Result { // TODO: turn trusted maintainer into NostrUrlDecoded if !event.kind.eq(&Kind::GitRepoAnnouncement) { @@ -66,6 +73,7 @@ impl TryFrom<(nostr::Event, Option)> for RepoRef { blossoms: Vec::new(), maintainers: Vec::new(), trusted_maintainer: trusted_maintainer.unwrap_or(event.pubkey), + maintainers_without_annoucnement: None, events: HashMap::new(), nostr_git_url: None, }; @@ -740,6 +748,7 @@ mod tests { ], blossoms: vec![], trusted_maintainer: TEST_KEY_1_KEYS.public_key(), + maintainers_without_annoucnement: None, maintainers: vec![TEST_KEY_1_KEYS.public_key(), TEST_KEY_2_KEYS.public_key()], events: HashMap::new(), nostr_git_url: None, -- cgit v1.2.3