From b10340cb00a00da07d0ae735796d83801454779e Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Fri, 20 Feb 2026 21:14:45 +0000 Subject: use trusted maintainer's grasp servers as fallback for co-maintainers when a co-maintainer has no grasp servers of their own, fall back to the trusted maintainer's grasp servers rather than jumping straight to system defaults. if the trusted maintainer only uses a single grasp server, the first system default is appended for redundancy. system defaults are only used when neither the user nor the trusted maintainer has any grasp servers configured. --- src/bin/ngit/sub_commands/init.rs | 15 +++++++++-- src/lib/accept_maintainership.rs | 53 +++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs index 5c43e6e..5ff57d5 100644 --- a/src/bin/ngit/sub_commands/init.rs +++ b/src/bin/ngit/sub_commands/init.rs @@ -282,12 +282,23 @@ fn resolve_grasp_servers( if !interactive || cli.defaults || state.has_coordinate() || cli.force { // Prefer grasp servers from my existing announcement, then user's grasp - // list, then system fallbacks + // list (or trusted maintainer's servers as fallback), then system defaults let existing = detect_existing_grasp_servers(my_ref.as_ref(), &args.relay, &[], identifier); if !existing.is_empty() { return Ok(existing); } - return Ok(grasp_servers_from_user_or_fallback(user_ref, client)); + // For co-maintainer state, pass the repo_ref so the trusted + // maintainer's grasp servers can be used as a fallback. + let trusted_maintainer_repo_ref = if matches!(state, InitState::CoMaintainer { .. }) { + state.repo_ref() + } else { + None + }; + return Ok(grasp_servers_from_user_or_fallback( + user_ref, + trusted_maintainer_repo_ref, + client, + )); } // Interactive prompt diff --git a/src/lib/accept_maintainership.rs b/src/lib/accept_maintainership.rs index 39f10cf..086b858 100644 --- a/src/lib/accept_maintainership.rs +++ b/src/lib/accept_maintainership.rs @@ -66,7 +66,8 @@ pub async fn accept_maintainership_with_defaults( // --- Step 1: resolve infrastructure --- - let selected_grasp_servers = grasp_servers_from_user_or_fallback(user_ref, client); + let selected_grasp_servers = + grasp_servers_from_user_or_fallback(user_ref, Some(repo_ref), client); let mut git_servers: Vec = vec![]; let mut relay_strings: Vec = vec![]; @@ -208,26 +209,56 @@ pub async fn accept_maintainership_with_defaults( // Grasp server helpers // --------------------------------------------------------------------------- -/// Return the user's saved grasp servers, falling back to client defaults. +/// Return grasp servers for a co-maintainer using the following priority: +/// +/// 1. User's own saved grasp server list (if non-empty). +/// 2. Trusted maintainer's grasp servers derived from +/// `trusted_maintainer_repo_ref` (if provided and non-empty). If the trusted +/// maintainer only uses a single grasp server, the first system-default +/// grasp server is appended so the co-maintainer has at least two servers +/// for redundancy. +/// 3. System / client default grasp servers. pub fn grasp_servers_from_user_or_fallback( user_ref: &UserRef, + trusted_maintainer_repo_ref: Option<&RepoRef>, #[cfg(test)] client: &MockConnect, #[cfg(not(test))] client: &Client, ) -> Vec { - if user_ref.grasp_list.urls.is_empty() { - client - .get_grasp_default_set() - .iter() - .map(std::string::ToString::to_string) - .collect() - } else { - user_ref + // Priority 1: user's own grasp list. + if !user_ref.grasp_list.urls.is_empty() { + return user_ref .grasp_list .urls .iter() .map(std::string::ToString::to_string) - .collect() + .collect(); } + + // Priority 2: trusted maintainer's grasp servers. + if let Some(rr) = trusted_maintainer_repo_ref { + let maintainer_servers = rr.grasp_servers(); + if !maintainer_servers.is_empty() { + if maintainer_servers.len() == 1 { + // Supplement a single server with the first system default for + // redundancy, avoiding duplicates. + let mut servers = maintainer_servers; + if let Some(first_default) = client.get_grasp_default_set().first() { + if !servers.contains(first_default) { + servers.push(first_default.clone()); + } + } + return servers; + } + return maintainer_servers; + } + } + + // Priority 3: system defaults. + client + .get_grasp_default_set() + .iter() + .map(std::string::ToString::to_string) + .collect() } // --------------------------------------------------------------------------- -- cgit v1.2.3