upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib/client.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-12-03 15:29:06 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-12-03 15:29:06 +0000
commitd2478dbca6c5d3f61331ceabe20c6d9315cd6840 (patch)
tree9cd79f52ac96378ef68b4798db48ee65839d9f74 /src/lib/client.rs
parent79f55ad6488ddb628438580acf54a1d23a990cb3 (diff)
refactor: limit fetch to 1 trusted coordinate
previously fetch supported fetching multiple trusted coordinates at once. The additional complexity trade off isn't worth it. It will still fetch events related to the coordinates of maintainers that the trusted maintainer lists. A scenario where there might be multiple trusted coordinates is where a large repo is split into multiple nostr repos to manage pull requests and issues in seperate sub-units. I might therefore have different remotes that target different identifiers. There also might be different set of maintainers groups that are have different views on the latest state of the same codebase and they haven't split off into using different identifiers. Its simplier ngit to fetch these different nostr repos independantly when requested. git-remote-nostr will do this automatically as it works through remotes but for ngit cmds a further change is required so `get_repo_coordinates` and `try_and_get_repo_coordinates` prompts to select the desired one.
Diffstat (limited to 'src/lib/client.rs')
-rw-r--r--src/lib/client.rs86
1 files changed, 52 insertions, 34 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 4b87cd8..32f5bd7 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -89,7 +89,7 @@ pub trait Connect {
89 async fn fetch_all<'a>( 89 async fn fetch_all<'a>(
90 &self, 90 &self,
91 git_repo_path: Option<&'a Path>, 91 git_repo_path: Option<&'a Path>,
92 repo_coordinates: &HashSet<Coordinate>, 92 repo_coordinates: Option<&'a Coordinate>,
93 user_profiles: &HashSet<PublicKey>, 93 user_profiles: &HashSet<PublicKey>,
94 ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)>; 94 ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)>;
95 async fn fetch_all_from_relay<'a>( 95 async fn fetch_all_from_relay<'a>(
@@ -329,7 +329,7 @@ impl Connect for Client {
329 async fn fetch_all<'a>( 329 async fn fetch_all<'a>(
330 &self, 330 &self,
331 git_repo_path: Option<&'a Path>, 331 git_repo_path: Option<&'a Path>,
332 repo_coordinates: &HashSet<Coordinate>, 332 trusted_maintainer_coordinate: Option<&'a Coordinate>,
333 user_profiles: &HashSet<PublicKey>, 333 user_profiles: &HashSet<PublicKey>,
334 ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)> { 334 ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)> {
335 let fallback_relays = &self 335 let fallback_relays = &self
@@ -340,7 +340,7 @@ impl Connect for Client {
340 340
341 let mut request = create_relays_request( 341 let mut request = create_relays_request(
342 git_repo_path, 342 git_repo_path,
343 repo_coordinates, 343 trusted_maintainer_coordinate,
344 user_profiles, 344 user_profiles,
345 fallback_relays.clone(), 345 fallback_relays.clone(),
346 ) 346 )
@@ -468,8 +468,12 @@ impl Connect for Client {
468 } 468 }
469 processed_relays.extend(relays.clone()); 469 processed_relays.extend(relays.clone());
470 470
471 if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await { 471 if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate {
472 request.repo_relays = repo_ref.relays.iter().cloned().collect(); 472 if let Ok(repo_ref) =
473 get_repo_ref_from_cache(git_repo_path, trusted_maintainer_coordinate).await
474 {
475 request.repo_relays = repo_ref.relays.iter().cloned().collect();
476 }
473 } 477 }
474 478
475 request.user_relays_for_profiles = { 479 request.user_relays_for_profiles = {
@@ -809,18 +813,24 @@ pub async fn save_event_in_global_cache(
809 813
810pub async fn get_repo_ref_from_cache( 814pub async fn get_repo_ref_from_cache(
811 git_repo_path: Option<&Path>, 815 git_repo_path: Option<&Path>,
812 repo_coordinates: &HashSet<Coordinate>, 816 repo_coordinate: &Coordinate,
813) -> Result<RepoRef> { 817) -> Result<RepoRef> {
814 let mut maintainers = HashSet::new(); 818 let mut maintainers = HashSet::new();
815 let mut new_coordinate: bool; 819 let mut new_coordinate: bool;
816 820
817 for c in repo_coordinates { 821 maintainers.insert(repo_coordinate.public_key);
818 maintainers.insert(c.public_key);
819 }
820 let mut repo_events = vec![]; 822 let mut repo_events = vec![];
821 loop { 823 loop {
822 new_coordinate = false; 824 new_coordinate = false;
823 let repo_events_filter = get_filter_repo_events(repo_coordinates); 825 let repo_events_filter =
826 get_filter_repo_events(&HashSet::from_iter(maintainers.iter().map(|m| {
827 Coordinate {
828 kind: Kind::GitRepoAnnouncement,
829 public_key: *m,
830 identifier: repo_coordinate.identifier.to_string(),
831 relays: vec![],
832 }
833 })));
824 834
825 let events = [ 835 let events = [
826 get_event_from_global_cache(git_repo_path, vec![repo_events_filter.clone()]).await?, 836 get_event_from_global_cache(git_repo_path, vec![repo_events_filter.clone()]).await?,
@@ -832,13 +842,7 @@ pub async fn get_repo_ref_from_cache(
832 ] 842 ]
833 .concat(); 843 .concat();
834 for e in events { 844 for e in events {
835 if let Ok(repo_ref) = RepoRef::try_from(( 845 if let Ok(repo_ref) = RepoRef::try_from((e.clone(), None)) {
836 e.clone(),
837 repo_coordinates
838 .iter()
839 .next()
840 .map(|coordinate| coordinate.public_key),
841 )) {
842 for m in repo_ref.maintainers { 846 for m in repo_ref.maintainers {
843 if maintainers.insert(m) { 847 if maintainers.insert(m) {
844 new_coordinate = true; 848 new_coordinate = true;
@@ -857,10 +861,7 @@ pub async fn get_repo_ref_from_cache(
857 .first() 861 .first()
858 .context("no repo announcement event found at specified coordinates. if you are the repository maintainer consider running `ngit init` to create one")? 862 .context("no repo announcement event found at specified coordinates. if you are the repository maintainer consider running `ngit init` to create one")?
859 .clone(), 863 .clone(),
860 repo_coordinates 864 Some(repo_coordinate.public_key),
861 .iter()
862 .next()
863 .map(|coordinate| coordinate.public_key),
864 ))?; 865 ))?;
865 866
866 let mut events: HashMap<Coordinate, nostr::Event> = HashMap::new(); 867 let mut events: HashMap<Coordinate, nostr::Event> = HashMap::new();
@@ -913,27 +914,40 @@ pub async fn get_state_from_cache(
913#[allow(clippy::too_many_lines)] 914#[allow(clippy::too_many_lines)]
914async fn create_relays_request( 915async fn create_relays_request(
915 git_repo_path: Option<&Path>, 916 git_repo_path: Option<&Path>,
916 repo_coordinates: &HashSet<Coordinate>, 917 trusted_maintainer_coordinate: Option<&Coordinate>,
917 user_profiles: &HashSet<PublicKey>, 918 user_profiles: &HashSet<PublicKey>,
918 fallback_relays: HashSet<RelayUrl>, 919 fallback_relays: HashSet<RelayUrl>,
919) -> Result<FetchRequest> { 920) -> Result<FetchRequest> {
920 let repo_ref = get_repo_ref_from_cache(git_repo_path, repo_coordinates).await; 921 let repo_ref = if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate {
922 if let Ok(repo_ref) =
923 get_repo_ref_from_cache(git_repo_path, trusted_maintainer_coordinate).await
924 {
925 Some(repo_ref)
926 } else {
927 None
928 }
929 } else {
930 None
931 };
921 932
922 let repo_coordinates = { 933 let repo_coordinates = {
923 // add coordinates of users listed in maintainers to explicitly specified 934 // add coordinates of users listed in maintainers to explicitly specified
924 // coodinates 935 // coodinates
925 let mut repo_coordinates = repo_coordinates.clone(); 936 let mut set: HashSet<Coordinate> = HashSet::new();
926 if let Ok(repo_ref) = &repo_ref { 937 if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate {
938 set.insert(trusted_maintainer_coordinate.clone());
939 }
940 if let Some(repo_ref) = &repo_ref {
927 for c in repo_ref.coordinates() { 941 for c in repo_ref.coordinates() {
928 if !repo_coordinates 942 if !set
929 .iter() 943 .iter()
930 .any(|e| e.identifier.eq(&c.identifier) && e.public_key.eq(&c.public_key)) 944 .any(|e| e.identifier.eq(&c.identifier) && e.public_key.eq(&c.public_key))
931 { 945 {
932 repo_coordinates.insert(c); 946 set.insert(c);
933 } 947 }
934 } 948 }
935 } 949 }
936 repo_coordinates 950 set
937 }; 951 };
938 952
939 let repo_coordinates_without_relays = { 953 let repo_coordinates_without_relays = {
@@ -954,7 +968,7 @@ async fn create_relays_request(
954 let mut contributors: HashSet<PublicKey> = HashSet::new(); 968 let mut contributors: HashSet<PublicKey> = HashSet::new();
955 969
956 if !repo_coordinates_without_relays.is_empty() { 970 if !repo_coordinates_without_relays.is_empty() {
957 if let Ok(repo_ref) = &repo_ref { 971 if let Some(repo_ref) = &repo_ref {
958 for m in &repo_ref.maintainers { 972 for m in &repo_ref.maintainers {
959 contributors.insert(m.to_owned()); 973 contributors.insert(m.to_owned());
960 } 974 }
@@ -1077,7 +1091,7 @@ async fn create_relays_request(
1077 1091
1078 let relays = { 1092 let relays = {
1079 let mut relays = fallback_relays; 1093 let mut relays = fallback_relays;
1080 if let Ok(repo_ref) = &repo_ref { 1094 if let Some(repo_ref) = &repo_ref {
1081 for r in repo_ref.relays.clone() { 1095 for r in repo_ref.relays.clone() {
1082 relays.insert(r); 1096 relays.insert(r);
1083 } 1097 }
@@ -1113,7 +1127,7 @@ async fn create_relays_request(
1113 selected_relay: None, 1127 selected_relay: None,
1114 repo_relays: relays, 1128 repo_relays: relays,
1115 relay_column_width, 1129 relay_column_width,
1116 repo_coordinates_without_relays: if let Ok(repo_ref) = &repo_ref { 1130 repo_coordinates_without_relays: if let Some(repo_ref) = &repo_ref {
1117 repo_ref.coordinates_with_timestamps() 1131 repo_ref.coordinates_with_timestamps()
1118 } else { 1132 } else {
1119 repo_coordinates_without_relays 1133 repo_coordinates_without_relays
@@ -1121,7 +1135,7 @@ async fn create_relays_request(
1121 .map(|c| (c.clone(), None)) 1135 .map(|c| (c.clone(), None))
1122 .collect() 1136 .collect()
1123 }, 1137 },
1124 state: if let Ok(repo_ref) = &repo_ref { 1138 state: if let Some(repo_ref) = &repo_ref {
1125 if let Ok(existing_state) = get_state_from_cache(git_repo_path, repo_ref).await { 1139 if let Ok(existing_state) = get_state_from_cache(git_repo_path, repo_ref).await {
1126 Some((existing_state.event.created_at, existing_state.event.id)) 1140 Some((existing_state.event.created_at, existing_state.event.id))
1127 } else { 1141 } else {
@@ -1523,12 +1537,16 @@ pub async fn fetching_with_report(
1523 git_repo_path: &Path, 1537 git_repo_path: &Path,
1524 #[cfg(test)] client: &crate::client::MockConnect, 1538 #[cfg(test)] client: &crate::client::MockConnect,
1525 #[cfg(not(test))] client: &Client, 1539 #[cfg(not(test))] client: &Client,
1526 repo_coordinates: &HashSet<Coordinate>, 1540 trusted_maintainer_coordinate: &Coordinate,
1527) -> Result<FetchReport> { 1541) -> Result<FetchReport> {
1528 let term = console::Term::stderr(); 1542 let term = console::Term::stderr();
1529 term.write_line("fetching updates...")?; 1543 term.write_line("fetching updates...")?;
1530 let (relay_reports, progress_reporter) = client 1544 let (relay_reports, progress_reporter) = client
1531 .fetch_all(Some(git_repo_path), repo_coordinates, &HashSet::new()) 1545 .fetch_all(
1546 Some(git_repo_path),
1547 Some(trusted_maintainer_coordinate),
1548 &HashSet::new(),
1549 )
1532 .await?; 1550 .await?;
1533 if !relay_reports.iter().any(std::result::Result::is_err) { 1551 if !relay_reports.iter().any(std::result::Result::is_err) {
1534 let _ = progress_reporter.clear(); 1552 let _ = progress_reporter.clear();