From 513fce723c7e37aa353844303f36022517f2db43 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Fri, 25 Jul 2025 21:02:26 +0100 Subject: refactor: move `utils` and `list` helpers to lib to enable forthcoming `ngit sync` cmd --- src/bin/git_remote_nostr/list.rs | 163 ++------------------------------------- 1 file changed, 5 insertions(+), 158 deletions(-) (limited to 'src/bin/git_remote_nostr/list.rs') diff --git a/src/bin/git_remote_nostr/list.rs b/src/bin/git_remote_nostr/list.rs index 7bdf170..df98c12 100644 --- a/src/bin/git_remote_nostr/list.rs +++ b/src/bin/git_remote_nostr/list.rs @@ -1,30 +1,22 @@ -use core::str; use std::collections::HashMap; -use anyhow::{Context, Result, anyhow}; -use auth_git2::GitAuthenticator; +use anyhow::{Context, Result}; use client::get_state_from_cache; use git::RepoActions; use ngit::{ client, - git::{ - self, - nostr_url::{CloneUrl, NostrUrlDecoded, ServerProtocol}, - }, + git::{self}, git_events::{KIND_PULL_REQUEST, KIND_PULL_REQUEST_UPDATE, event_to_cover_letter, tag_value}, + list::{get_ahead_behind, list_from_remotes}, login::get_curent_user, - repo_ref::{self, is_grasp_server}, + repo_ref::{self}, + utils::{get_open_or_draft_proposals, get_short_git_server_name}, }; -use nostr_sdk::hashes::sha1::Hash as Sha1Hash; use repo_ref::RepoRef; use crate::{ fetch::{fetch_from_git_server, make_commits_for_proposal}, git::Repo, - utils::{ - Direction, get_open_or_draft_proposals, get_read_protocols_to_try, - get_short_git_server_name, join_with_and, set_protocol_preference, - }, }; pub async fn run_list( @@ -210,148 +202,3 @@ async fn get_open_and_draft_proposals_state( } Ok(state) } - -pub fn list_from_remotes( - term: &console::Term, - git_repo: &Repo, - git_servers: &Vec, - decoded_nostr_url: &NostrUrlDecoded, - grasp_servers: &[String], -) -> HashMap, bool)> { - let mut remote_states = HashMap::new(); - let mut errors = HashMap::new(); - for url in git_servers { - let is_grasp_server = is_grasp_server(url, grasp_servers); - match list_from_remote(term, git_repo, url, decoded_nostr_url, is_grasp_server) { - Err(error) => { - errors.insert(url, error); - } - Ok(state) => { - remote_states.insert(url.to_string(), (state, is_grasp_server)); - } - } - } - remote_states -} - -pub fn list_from_remote( - term: &console::Term, - git_repo: &Repo, - git_server_url: &str, - decoded_nostr_url: &NostrUrlDecoded, - is_grasp_server: bool, -) -> Result> { - let server_url = git_server_url.parse::()?; - let protocols_to_attempt = - get_read_protocols_to_try(git_repo, &server_url, decoded_nostr_url, is_grasp_server); - - let mut failed_protocols = vec![]; - let mut remote_state: Option> = None; - - for protocol in &protocols_to_attempt { - term.write_line( - format!( - "fetching {} ref list over {protocol}...", - server_url.short_name(), - ) - .as_str(), - )?; - - let formatted_url = server_url.format_as(protocol, &decoded_nostr_url.user)?; - let res = list_from_remote_url( - git_repo, - &formatted_url, - [ServerProtocol::UnauthHttps, ServerProtocol::UnauthHttp].contains(protocol), - term, - ); - - match res { - Ok(state) => { - remote_state = Some(state); - term.clear_last_lines(1)?; - if !failed_protocols.is_empty() { - term.write_line( - format!( - "list: succeeded over {protocol} from {}", - server_url.short_name(), - ) - .as_str(), - )?; - let _ = - set_protocol_preference(git_repo, protocol, &server_url, &Direction::Fetch); - } - break; - } - Err(error) => { - term.clear_last_lines(1)?; - term.write_line( - format!("list: {formatted_url} failed over {protocol}: {error}").as_str(), - )?; - failed_protocols.push(protocol); - } - } - } - if let Some(remote_state) = remote_state { - if failed_protocols.is_empty() { - term.clear_last_lines(1)?; - } - Ok(remote_state) - } else { - let error = anyhow!( - "{} failed over {}{}", - server_url.short_name(), - join_with_and(&failed_protocols), - if decoded_nostr_url.protocol.is_some() { - " and nostr url contains protocol override so no other protocols were attempted" - } else { - "" - }, - ); - term.write_line(format!("list: {error}").as_str())?; - Err(error) - } -} - -fn list_from_remote_url( - git_repo: &Repo, - git_server_remote_url: &str, - dont_authenticate: bool, - term: &console::Term, -) -> Result> { - let git_config = git_repo.git_repo.config()?; - - let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_remote_url)?; - // authentication may be required - let auth = GitAuthenticator::default(); - let mut remote_callbacks = git2::RemoteCallbacks::new(); - if !dont_authenticate { - remote_callbacks.credentials(auth.credentials(&git_config)); - } - term.write_line("list: connecting...")?; - git_server_remote.connect_auth(git2::Direction::Fetch, Some(remote_callbacks), None)?; - term.clear_last_lines(1)?; - let mut state = HashMap::new(); - for head in git_server_remote.list()? { - if let Some(symbolic_reference) = head.symref_target() { - state.insert( - head.name().to_string(), - format!("ref: {symbolic_reference}"), - ); - // ignore dereferenced tags - } else if !head.name().to_string().ends_with("^{}") { - state.insert(head.name().to_string(), head.oid().to_string()); - } - } - git_server_remote.disconnect()?; - Ok(state) -} - -fn get_ahead_behind( - git_repo: &Repo, - base_ref_or_oid: &str, - latest_ref_or_oid: &str, -) -> Result<(Vec, Vec)> { - let base = git_repo.get_commit_or_tip_of_reference(base_ref_or_oid)?; - let latest = git_repo.get_commit_or_tip_of_reference(latest_ref_or_oid)?; - git_repo.get_commits_ahead_behind(&base, &latest) -} -- cgit v1.2.3