upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/client.rs75
-rw-r--r--src/lib/git/mod.rs4
-rw-r--r--src/lib/git_events.rs36
-rw-r--r--src/lib/login/key_encryption.rs30
-rw-r--r--src/lib/login/mod.rs10
-rw-r--r--src/lib/repo_ref.rs103
-rw-r--r--src/lib/repo_state.rs4
7 files changed, 131 insertions, 131 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 59e17f2..5f9e996 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -29,7 +29,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, P
29#[cfg(test)] 29#[cfg(test)]
30use mockall::*; 30use mockall::*;
31use nostr::{nips::nip01::Coordinate, Event}; 31use nostr::{nips::nip01::Coordinate, Event};
32use nostr_database::{NostrDatabase, Order}; 32use nostr_database::NostrDatabase;
33use nostr_sdk::{ 33use nostr_sdk::{
34 prelude::RelayLimits, EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, 34 prelude::RelayLimits, EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey,
35 SingleLetterTag, Timestamp, Url, 35 SingleLetterTag, Timestamp, Url,
@@ -231,10 +231,10 @@ impl Connect for Client {
231 }); 231 });
232 } 232 }
233 save_event_in_cache(git_repo_path, &event).await?; 233 save_event_in_cache(git_repo_path, &event).await?;
234 if event.kind().eq(&Kind::GitRepoAnnouncement) { 234 if event.kind.eq(&Kind::GitRepoAnnouncement) {
235 save_event_in_global_cache(git_repo_path, &event).await?; 235 save_event_in_global_cache(git_repo_path, &event).await?;
236 } 236 }
237 Ok(event.id()) 237 Ok(event.id)
238 } 238 }
239 239
240 async fn get_events( 240 async fn get_events(
@@ -758,7 +758,7 @@ pub async fn get_events_from_cache(
758) -> Result<Vec<nostr::Event>> { 758) -> Result<Vec<nostr::Event>> {
759 get_local_cache_database(git_repo_path) 759 get_local_cache_database(git_repo_path)
760 .await? 760 .await?
761 .query(filters.clone(), Order::Asc) 761 .query(filters.clone())
762 .await 762 .await
763 .context( 763 .context(
764 "cannot execute query on opened git repo nostr cache database .git/nostr-cache.sqlite", 764 "cannot execute query on opened git repo nostr cache database .git/nostr-cache.sqlite",
@@ -771,7 +771,7 @@ pub async fn get_event_from_global_cache(
771) -> Result<Vec<nostr::Event>> { 771) -> Result<Vec<nostr::Event>> {
772 get_global_cache_database(git_repo_path) 772 get_global_cache_database(git_repo_path)
773 .await? 773 .await?
774 .query(filters.clone(), Order::Asc) 774 .query(filters.clone())
775 .await 775 .await
776 .context("cannot execute query on opened ngit nostr cache database") 776 .context("cannot execute query on opened ngit nostr cache database")
777} 777}
@@ -839,12 +839,12 @@ pub async fn get_repo_ref_from_cache(
839 839
840 let mut events: HashMap<Coordinate, nostr::Event> = HashMap::new(); 840 let mut events: HashMap<Coordinate, nostr::Event> = HashMap::new();
841 for m in &maintainers { 841 for m in &maintainers {
842 if let Some(e) = repo_events.iter().find(|e| e.author().eq(m)) { 842 if let Some(e) = repo_events.iter().find(|e| e.pubkey.eq(m)) {
843 events.insert( 843 events.insert(
844 Coordinate { 844 Coordinate {
845 kind: e.kind, 845 kind: e.kind,
846 identifier: e.identifier().unwrap().to_string(), 846 identifier: e.identifier().unwrap().to_string(),
847 public_key: e.author(), 847 public_key: e.pubkey,
848 relays: vec![], 848 relays: vec![],
849 }, 849 },
850 e.clone(), 850 e.clone(),
@@ -938,8 +938,8 @@ async fn create_relays_request(
938 .await? 938 .await?
939 { 939 {
940 if event_is_patch_set_root(event) || event_is_revision_root(event) { 940 if event_is_patch_set_root(event) || event_is_revision_root(event) {
941 proposals.insert(event.id()); 941 proposals.insert(event.id);
942 contributors.insert(event.author()); 942 contributors.insert(event.pubkey);
943 } 943 }
944 } 944 }
945 945
@@ -951,7 +951,7 @@ async fn create_relays_request(
951 for c in &contributors { 951 for c in &contributors {
952 if let Some(event) = profile_events 952 if let Some(event) = profile_events
953 .iter() 953 .iter()
954 .find(|e| e.kind() == Kind::Metadata && e.author().eq(c)) 954 .find(|e| e.kind == Kind::Metadata && e.pubkey.eq(c))
955 { 955 {
956 save_event_in_cache(git_repo_path, event).await?; 956 save_event_in_cache(git_repo_path, event).await?;
957 } else { 957 } else {
@@ -1109,7 +1109,7 @@ async fn process_fetched_events(
1109 for event in &events { 1109 for event in &events {
1110 if !request.existing_events.contains(&event.id) { 1110 if !request.existing_events.contains(&event.id) {
1111 save_event_in_cache(git_repo_path, event).await?; 1111 save_event_in_cache(git_repo_path, event).await?;
1112 if event.kind().eq(&Kind::GitRepoAnnouncement) { 1112 if event.kind.eq(&Kind::GitRepoAnnouncement) {
1113 save_event_in_global_cache(git_repo_path, event).await?; 1113 save_event_in_global_cache(git_repo_path, event).await?;
1114 let new_coordinate = !request 1114 let new_coordinate = !request
1115 .repo_coordinates_without_relays 1115 .repo_coordinates_without_relays
@@ -1135,8 +1135,8 @@ async fn process_fetched_events(
1135 if update_to_existing { 1135 if update_to_existing {
1136 report.updated_repo_announcements.push(( 1136 report.updated_repo_announcements.push((
1137 Coordinate { 1137 Coordinate {
1138 kind: event.kind(), 1138 kind: event.kind,
1139 public_key: event.author(), 1139 public_key: event.pubkey,
1140 identifier: event.identifier().unwrap().to_owned(), 1140 identifier: event.identifier().unwrap().to_owned(),
1141 relays: vec![], 1141 relays: vec![],
1142 }, 1142 },
@@ -1155,7 +1155,7 @@ async fn process_fetched_events(
1155 .any(|c| c.identifier.eq(&repo_ref.identifier) && m.eq(&c.public_key)) 1155 .any(|c| c.identifier.eq(&repo_ref.identifier) && m.eq(&c.public_key))
1156 { 1156 {
1157 let c = Coordinate { 1157 let c = Coordinate {
1158 kind: event.kind(), 1158 kind: event.kind,
1159 public_key: *m, 1159 public_key: *m,
1160 identifier: repo_ref.identifier.clone(), 1160 identifier: repo_ref.identifier.clone(),
1161 relays: vec![], 1161 relays: vec![],
@@ -1177,7 +1177,7 @@ async fn process_fetched_events(
1177 } 1177 }
1178 } 1178 }
1179 } 1179 }
1180 } else if event.kind().eq(&STATE_KIND) { 1180 } else if event.kind.eq(&STATE_KIND) {
1181 let existing_state = if report.updated_state.is_some() { 1181 let existing_state = if report.updated_state.is_some() {
1182 report.updated_state 1182 report.updated_state
1183 } else { 1183 } else {
@@ -1193,27 +1193,23 @@ async fn process_fetched_events(
1193 } else if event_is_patch_set_root(event) { 1193 } else if event_is_patch_set_root(event) {
1194 fresh_proposal_roots.insert(event.id); 1194 fresh_proposal_roots.insert(event.id);
1195 report.proposals.insert(event.id); 1195 report.proposals.insert(event.id);
1196 if !request.contributors.contains(&event.author()) 1196 if !request.contributors.contains(&event.pubkey)
1197 && !fresh_profiles.contains(&event.author()) 1197 && !fresh_profiles.contains(&event.pubkey)
1198 { 1198 {
1199 fresh_profiles.insert(event.author()); 1199 fresh_profiles.insert(event.pubkey);
1200 } 1200 }
1201 } else if [Kind::RelayList, Kind::Metadata].contains(&event.kind()) { 1201 } else if [Kind::RelayList, Kind::Metadata].contains(&event.kind) {
1202 if request 1202 if request.missing_contributor_profiles.contains(&event.pubkey) {
1203 .missing_contributor_profiles 1203 report.contributor_profiles.insert(event.pubkey);
1204 .contains(&event.author())
1205 {
1206 report.contributor_profiles.insert(event.author());
1207 } else if let Some((_, (metadata_timestamp, relay_list_timestamp))) = request 1204 } else if let Some((_, (metadata_timestamp, relay_list_timestamp))) = request
1208 .profiles_to_fetch_from_user_relays 1205 .profiles_to_fetch_from_user_relays
1209 .get_key_value(&event.author()) 1206 .get_key_value(&event.pubkey)
1210 { 1207 {
1211 if (Kind::Metadata.eq(&event.kind()) 1208 if (Kind::Metadata.eq(&event.kind) && event.created_at.gt(metadata_timestamp))
1212 && event.created_at().gt(metadata_timestamp)) 1209 || (Kind::RelayList.eq(&event.kind)
1213 || (Kind::RelayList.eq(&event.kind()) 1210 && event.created_at.gt(relay_list_timestamp))
1214 && event.created_at().gt(relay_list_timestamp))
1215 { 1211 {
1216 report.profile_updates.insert(event.author()); 1212 report.profile_updates.insert(event.pubkey);
1217 } 1213 }
1218 } 1214 }
1219 save_event_in_global_cache(git_repo_path, event).await?; 1215 save_event_in_global_cache(git_repo_path, event).await?;
@@ -1224,9 +1220,9 @@ async fn process_fetched_events(
1224 if !request.existing_events.contains(&event.id) 1220 if !request.existing_events.contains(&event.id)
1225 && !event.event_ids().any(|id| report.proposals.contains(id)) 1221 && !event.event_ids().any(|id| report.proposals.contains(id))
1226 { 1222 {
1227 if event.kind().eq(&Kind::GitPatch) && !event_is_patch_set_root(event) { 1223 if event.kind.eq(&Kind::GitPatch) && !event_is_patch_set_root(event) {
1228 report.commits.insert(event.id); 1224 report.commits.insert(event.id);
1229 } else if status_kinds().contains(&event.kind()) { 1225 } else if status_kinds().contains(&event.kind) {
1230 report.statuses.insert(event.id); 1226 report.statuses.insert(event.id);
1231 } 1227 }
1232 } 1228 }
@@ -1549,21 +1545,21 @@ pub async fn get_all_proposal_patch_events_from_cache(
1549 vec![ 1545 vec![
1550 commit_events 1546 commit_events
1551 .iter() 1547 .iter()
1552 .find(|e| e.id().eq(proposal_id)) 1548 .find(|e| e.id.eq(proposal_id))
1553 .context("proposal not in cache")? 1549 .context("proposal not in cache")?
1554 .author(), 1550 .pubkey,
1555 ], 1551 ],
1556 ] 1552 ]
1557 .concat() 1553 .concat()
1558 .iter() 1554 .iter()
1559 .copied() 1555 .copied()
1560 .collect(); 1556 .collect();
1561 commit_events.retain(|e| permissioned_users.contains(&e.author())); 1557 commit_events.retain(|e| permissioned_users.contains(&e.pubkey));
1562 1558
1563 let revision_roots: HashSet<nostr::EventId> = commit_events 1559 let revision_roots: HashSet<nostr::EventId> = commit_events
1564 .iter() 1560 .iter()
1565 .filter(|e| event_is_revision_root(e)) 1561 .filter(|e| event_is_revision_root(e))
1566 .map(nostr::Event::id) 1562 .map(|e| e.id)
1567 .collect(); 1563 .collect();
1568 1564
1569 if !revision_roots.is_empty() { 1565 if !revision_roots.is_empty() {
@@ -1584,7 +1580,7 @@ pub async fn get_all_proposal_patch_events_from_cache(
1584 1580
1585 Ok(commit_events 1581 Ok(commit_events
1586 .iter() 1582 .iter()
1587 .filter(|e| !event_is_cover_letter(e) && permissioned_users.contains(&e.author())) 1583 .filter(|e| !event_is_cover_letter(e) && permissioned_users.contains(&e.pubkey))
1588 .cloned() 1584 .cloned()
1589 .collect()) 1585 .collect())
1590} 1586}
@@ -1614,10 +1610,7 @@ pub async fn send_events(
1614) -> Result<()> { 1610) -> Result<()> {
1615 let fallback = [ 1611 let fallback = [
1616 client.get_fallback_relays().clone(), 1612 client.get_fallback_relays().clone(),
1617 if events 1613 if events.iter().any(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) {
1618 .iter()
1619 .any(|e| e.kind().eq(&Kind::GitRepoAnnouncement))
1620 {
1621 client.get_blaster_relays().clone() 1614 client.get_blaster_relays().clone()
1622 } else { 1615 } else {
1623 vec![] 1616 vec![]
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs
index b0576fd..875a336 100644
--- a/src/lib/git/mod.rs
+++ b/src/lib/git/mod.rs
@@ -842,9 +842,9 @@ fn extract_sig_from_patch_tags<'a>(
842) -> Result<git2::Signature<'a>> { 842) -> Result<git2::Signature<'a>> {
843 let v = tags 843 let v = tags
844 .iter() 844 .iter()
845 .find(|t| t.as_vec()[0].eq(tag_name)) 845 .find(|t| t.as_slice()[0].eq(tag_name))
846 .context(format!("tag '{tag_name}' not present in patch"))? 846 .context(format!("tag '{tag_name}' not present in patch"))?
847 .as_vec(); 847 .as_slice();
848 if v.len() != 5 { 848 if v.len() != 5 {
849 bail!("tag '{tag_name}' is incorrectly formatted") 849 bail!("tag '{tag_name}' is incorrectly formatted")
850 } 850 }
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index d818f4c..2adc205 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -19,9 +19,9 @@ pub fn tag_value(event: &Event, tag_name: &str) -> Result<String> {
19 Ok(event 19 Ok(event
20 .tags 20 .tags
21 .iter() 21 .iter()
22 .find(|t| t.as_vec()[0].eq(tag_name)) 22 .find(|t| t.as_slice()[0].eq(tag_name))
23 .context(format!("tag '{tag_name}'not present"))? 23 .context(format!("tag '{tag_name}'not present"))?
24 .as_vec()[1] 24 .as_slice()[1]
25 .clone()) 25 .clone())
26} 26}
27 27
@@ -40,11 +40,11 @@ pub fn get_commit_id_from_patch(event: &Event) -> Result<String> {
40pub fn get_event_root(event: &nostr::Event) -> Result<EventId> { 40pub fn get_event_root(event: &nostr::Event) -> Result<EventId> {
41 Ok(EventId::parse( 41 Ok(EventId::parse(
42 event 42 event
43 .tags() 43 .tags
44 .iter() 44 .iter()
45 .find(|t| t.is_root()) 45 .find(|t| t.is_root())
46 .context("no thread root in event")? 46 .context("no thread root in event")?
47 .as_vec() 47 .as_slice()
48 .get(1) 48 .get(1)
49 .unwrap(), 49 .unwrap(),
50 )?) 50 )?)
@@ -60,23 +60,23 @@ pub fn status_kinds() -> Vec<Kind> {
60} 60}
61 61
62pub fn event_is_patch_set_root(event: &Event) -> bool { 62pub fn event_is_patch_set_root(event: &Event) -> bool {
63 event.kind.eq(&Kind::GitPatch) && event.tags().iter().any(|t| t.as_vec()[1].eq("root")) 63 event.kind.eq(&Kind::GitPatch) && event.tags.iter().any(|t| t.as_slice()[1].eq("root"))
64} 64}
65 65
66pub fn event_is_revision_root(event: &Event) -> bool { 66pub fn event_is_revision_root(event: &Event) -> bool {
67 event.kind.eq(&Kind::GitPatch) 67 event.kind.eq(&Kind::GitPatch)
68 && event 68 && event
69 .tags() 69 .tags
70 .iter() 70 .iter()
71 .any(|t| t.as_vec()[1].eq("revision-root")) 71 .any(|t| t.as_slice()[1].eq("revision-root"))
72} 72}
73 73
74pub fn patch_supports_commit_ids(event: &Event) -> bool { 74pub fn patch_supports_commit_ids(event: &Event) -> bool {
75 event.kind.eq(&Kind::GitPatch) 75 event.kind.eq(&Kind::GitPatch)
76 && event 76 && event
77 .tags() 77 .tags
78 .iter() 78 .iter()
79 .any(|t| t.as_vec()[0].eq("commit-pgp-sig")) 79 .any(|t| t.as_slice()[0].eq("commit-pgp-sig"))
80} 80}
81 81
82#[allow(clippy::too_many_arguments)] 82#[allow(clippy::too_many_arguments)]
@@ -399,7 +399,7 @@ pub async fn generate_cover_letter_and_patch_events(
399 events.first().map(|event| event.id), 399 events.first().map(|event| event.id),
400 signer, 400 signer,
401 repo_ref, 401 repo_ref,
402 events.last().map(nostr::Event::id), 402 events.last().map(|e| e.id),
403 if events.is_empty() && commits.len().eq(&1) { 403 if events.is_empty() && commits.len().eq(&1) {
404 None 404 None
405 } else { 405 } else {
@@ -461,11 +461,11 @@ pub fn event_is_cover_letter(event: &nostr::Event) -> bool {
461 // [PATCH v1 0/n ] or 461 // [PATCH v1 0/n ] or
462 // [PATCH subsystem v2 0/n ] 462 // [PATCH subsystem v2 0/n ]
463 event.kind.eq(&Kind::GitPatch) 463 event.kind.eq(&Kind::GitPatch)
464 && event.tags().iter().any(|t| t.as_vec()[1].eq("root")) 464 && event.tags.iter().any(|t| t.as_slice()[1].eq("root"))
465 && event 465 && event
466 .tags() 466 .tags
467 .iter() 467 .iter()
468 .any(|t| t.as_vec()[1].eq("cover-letter")) 468 .any(|t| t.as_slice()[1].eq("cover-letter"))
469} 469}
470 470
471pub fn commit_msg_from_patch(patch: &nostr::Event) -> Result<String> { 471pub fn commit_msg_from_patch(patch: &nostr::Event) -> Result<String> {
@@ -529,7 +529,7 @@ pub fn event_to_cover_letter(event: &nostr::Event) -> Result<CoverLetter> {
529 .collect(); 529 .collect();
530 s 530 s
531 }, 531 },
532 event_id: Some(event.id()), 532 event_id: Some(event.id),
533 }) 533 })
534} 534}
535 535
@@ -580,17 +580,17 @@ fn get_event_parent_id(event: &nostr::Event) -> Result<String> {
580 Ok(if let Some(reply_tag) = event 580 Ok(if let Some(reply_tag) = event
581 .tags 581 .tags
582 .iter() 582 .iter()
583 .find(|t| t.as_vec().len().gt(&3) && t.as_vec()[3].eq("reply")) 583 .find(|t| t.as_slice().len().gt(&3) && t.as_slice()[3].eq("reply"))
584 { 584 {
585 reply_tag 585 reply_tag
586 } else { 586 } else {
587 event 587 event
588 .tags 588 .tags
589 .iter() 589 .iter()
590 .find(|t| t.as_vec().len().gt(&3) && t.as_vec()[3].eq("root")) 590 .find(|t| t.as_slice().len().gt(&3) && t.as_slice()[3].eq("root"))
591 .context("no reply or root e tag present".to_string())? 591 .context("no reply or root e tag present".to_string())?
592 } 592 }
593 .as_vec()[1] 593 .as_slice()[1]
594 .clone()) 594 .clone())
595} 595}
596 596
@@ -601,7 +601,7 @@ pub fn is_event_proposal_root_for_branch(
601) -> Result<bool> { 601) -> Result<bool> {
602 let branch_name = branch_name_or_refstr.replace("refs/heads/", ""); 602 let branch_name = branch_name_or_refstr.replace("refs/heads/", "");
603 Ok(event_to_cover_letter(e).is_ok_and(|cl| { 603 Ok(event_to_cover_letter(e).is_ok_and(|cl| {
604 (logged_in_user.is_some_and(|public_key| e.author().eq(&public_key)) 604 (logged_in_user.is_some_and(|public_key| e.pubkey.eq(&public_key))
605 && (branch_name.eq(&format!("pr/{}", cl.branch_name)) 605 && (branch_name.eq(&format!("pr/{}", cl.branch_name))
606 || cl.branch_name.eq(&branch_name))) 606 || cl.branch_name.eq(&branch_name)))
607 || cl.get_branch_name().is_ok_and(|s| s.eq(&branch_name)) 607 || cl.get_branch_name().is_ok_and(|s| s.eq(&branch_name))
diff --git a/src/lib/login/key_encryption.rs b/src/lib/login/key_encryption.rs
index 3841d50..b50b507 100644
--- a/src/lib/login/key_encryption.rs
+++ b/src/lib/login/key_encryption.rs
@@ -11,7 +11,7 @@ pub fn encrypt_key(keys: &Keys, password: &str) -> Result<String> {
11 15 11 15
12 }; 12 };
13 Ok(nostr::nips::nip49::EncryptedSecretKey::new( 13 Ok(nostr::nips::nip49::EncryptedSecretKey::new(
14 keys.secret_key()?, 14 keys.secret_key(),
15 password, 15 password,
16 log2_rounds, 16 log2_rounds,
17 KeySecurity::Medium, 17 KeySecurity::Medium,
@@ -47,14 +47,8 @@ mod tests {
47 let decrypted_key = decrypt_key(TEST_KEY_1_ENCRYPTED, TEST_PASSWORD)?; 47 let decrypted_key = decrypt_key(TEST_KEY_1_ENCRYPTED, TEST_PASSWORD)?;
48 48
49 assert_eq!( 49 assert_eq!(
50 format!( 50 format!("{}", TEST_KEY_1_KEYS.secret_key().to_bech32().unwrap()),
51 "{}", 51 format!("{}", decrypted_key.secret_key().to_bech32().unwrap()),
52 TEST_KEY_1_KEYS.secret_key().unwrap().to_bech32().unwrap()
53 ),
54 format!(
55 "{}",
56 decrypted_key.secret_key().unwrap().to_bech32().unwrap()
57 ),
58 ); 52 );
59 Ok(()) 53 Ok(())
60 } 54 }
@@ -65,14 +59,8 @@ mod tests {
65 let decrypted_key = decrypt_key(TEST_KEY_1_ENCRYPTED_WEAK, TEST_WEAK_PASSWORD)?; 59 let decrypted_key = decrypt_key(TEST_KEY_1_ENCRYPTED_WEAK, TEST_WEAK_PASSWORD)?;
66 60
67 assert_eq!( 61 assert_eq!(
68 format!( 62 format!("{}", TEST_KEY_1_KEYS.secret_key().to_bech32().unwrap()),
69 "{}", 63 format!("{}", decrypted_key.secret_key().to_bech32().unwrap()),
70 TEST_KEY_1_KEYS.secret_key().unwrap().to_bech32().unwrap()
71 ),
72 format!(
73 "{}",
74 decrypted_key.secret_key().unwrap().to_bech32().unwrap()
75 ),
76 ); 64 );
77 Ok(()) 65 Ok(())
78 } 66 }
@@ -84,8 +72,8 @@ mod tests {
84 let newkey = decrypt_key(s.as_str(), TEST_PASSWORD)?; 72 let newkey = decrypt_key(s.as_str(), TEST_PASSWORD)?;
85 73
86 assert_eq!( 74 assert_eq!(
87 format!("{}", key.secret_key().unwrap().to_bech32().unwrap()), 75 format!("{}", key.secret_key().to_bech32().unwrap()),
88 format!("{}", newkey.secret_key().unwrap().to_bech32().unwrap()), 76 format!("{}", newkey.secret_key().to_bech32().unwrap()),
89 ); 77 );
90 Ok(()) 78 Ok(())
91 } 79 }
@@ -97,8 +85,8 @@ mod tests {
97 let newkey = decrypt_key(s.as_str(), TEST_PASSWORD)?; 85 let newkey = decrypt_key(s.as_str(), TEST_PASSWORD)?;
98 86
99 assert_eq!( 87 assert_eq!(
100 format!("{}", key.secret_key().unwrap().to_bech32().unwrap()), 88 format!("{}", key.secret_key().to_bech32().unwrap()),
101 format!("{}", newkey.secret_key().unwrap().to_bech32().unwrap()), 89 format!("{}", newkey.secret_key().to_bech32().unwrap()),
102 ); 90 );
103 Ok(()) 91 Ok(())
104 } 92 }
diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs
index 825ec30..f262bda 100644
--- a/src/lib/login/mod.rs
+++ b/src/lib/login/mod.rs
@@ -363,7 +363,7 @@ async fn fresh_login(
363 always_save: bool, 363 always_save: bool,
364) -> Result<(NostrSigner, UserRef)> { 364) -> Result<(NostrSigner, UserRef)> {
365 let app_key = Keys::generate(); 365 let app_key = Keys::generate();
366 let app_key_secret = app_key.secret_key()?.to_secret_hex(); 366 let app_key_secret = app_key.secret_key().to_secret_hex();
367 let relays = if let Some(client) = client { 367 let relays = if let Some(client) = client {
368 client 368 client
369 .get_fallback_signer_relays() 369 .get_fallback_signer_relays()
@@ -652,7 +652,7 @@ fn save_keys(git_repo: &Repo, keys: &nostr::Keys, always_save: bool) -> Result<(
652 .context("failed to get password input from interactor.password")?; 652 .context("failed to get password input from interactor.password")?;
653 encrypt_key(keys, &password)? 653 encrypt_key(keys, &password)?
654 } else { 654 } else {
655 keys.secret_key()?.to_bech32()? 655 keys.secret_key().to_bech32()?
656 }; 656 };
657 657
658 if let Err(error) = 658 if let Err(error) =
@@ -745,9 +745,9 @@ fn extract_user_relays(public_key: &nostr::PublicKey, events: &[nostr::Event]) -
745 ))) 745 )))
746 }) 746 })
747 .map(|t| UserRelayRef { 747 .map(|t| UserRelayRef {
748 url: t.as_vec()[1].clone(), 748 url: t.as_slice()[1].clone(),
749 read: t.as_vec().len() == 2 || t.as_vec()[2].eq("read"), 749 read: t.as_slice().len() == 2 || t.as_slice()[2].eq("read"),
750 write: t.as_vec().len() == 2 || t.as_vec()[2].eq("write"), 750 write: t.as_slice().len() == 2 || t.as_slice()[2].eq("write"),
751 }) 751 })
752 .collect() 752 .collect()
753 } else { 753 } else {
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs
index e498c86..2468d4d 100644
--- a/src/lib/repo_ref.rs
+++ b/src/lib/repo_ref.rs
@@ -42,42 +42,50 @@ impl TryFrom<nostr::Event> for RepoRef {
42 } 42 }
43 let mut r = Self::default(); 43 let mut r = Self::default();
44 44
45 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("d")) { 45 if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("d")) {
46 r.identifier = t.as_vec()[1].clone(); 46 r.identifier = t.as_slice()[1].clone();
47 } 47 }
48 48
49 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("name")) { 49 if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("name")) {
50 r.name = t.as_vec()[1].clone(); 50 r.name = t.as_slice()[1].clone();
51 } 51 }
52 52
53 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("description")) { 53 if let Some(t) = event
54 r.description = t.as_vec()[1].clone(); 54 .tags
55 .iter()
56 .find(|t| t.as_slice()[0].eq("description"))
57 {
58 r.description = t.as_slice()[1].clone();
55 } 59 }
56 60
57 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("clone")) { 61 if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("clone")) {
58 r.git_server = t.clone().to_vec(); 62 r.git_server = t.clone().to_vec();
59 r.git_server.remove(0); 63 r.git_server.remove(0);
60 } 64 }
61 65
62 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("web")) { 66 if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("web")) {
63 r.web = t.clone().to_vec(); 67 r.web = t.clone().to_vec();
64 r.web.remove(0); 68 r.web.remove(0);
65 } 69 }
66 70
67 if let Some(t) = event.tags.iter().find(|t| { 71 if let Some(t) = event.tags.iter().find(|t| {
68 t.as_vec()[0].eq("r") 72 t.as_slice()[0].eq("r")
69 && t.as_vec()[1].len().eq(&40) 73 && t.as_slice()[1].len().eq(&40)
70 && git2::Oid::from_str(t.as_vec()[1].as_str()).is_ok() 74 && git2::Oid::from_str(t.as_slice()[1].as_str()).is_ok()
71 }) { 75 }) {
72 r.root_commit = t.as_vec()[1].clone(); 76 r.root_commit = t.as_slice()[1].clone();
73 } 77 }
74 78
75 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("relays")) { 79 if let Some(t) = event.tags.iter().find(|t| t.as_slice()[0].eq("relays")) {
76 r.relays = t.clone().to_vec(); 80 r.relays = t.clone().to_vec();
77 r.relays.remove(0); 81 r.relays.remove(0);
78 } 82 }
79 83
80 if let Some(t) = event.tags.iter().find(|t| t.as_vec()[0].eq("maintainers")) { 84 if let Some(t) = event
85 .tags
86 .iter()
87 .find(|t| t.as_slice()[0].eq("maintainers"))
88 {
81 let mut maintainers = t.clone().to_vec(); 89 let mut maintainers = t.clone().to_vec();
82 maintainers.remove(0); 90 maintainers.remove(0);
83 if !maintainers.contains(&event.pubkey.to_string()) { 91 if !maintainers.contains(&event.pubkey.to_string()) {
@@ -98,7 +106,7 @@ impl TryFrom<nostr::Event> for RepoRef {
98 Coordinate { 106 Coordinate {
99 kind: event.kind, 107 kind: event.kind,
100 identifier: event.identifier().unwrap().to_string(), 108 identifier: event.identifier().unwrap().to_string(),
101 public_key: event.author(), 109 public_key: event.pubkey,
102 relays: vec![], 110 relays: vec![],
103 }, 111 },
104 event, 112 event,
@@ -606,7 +614,7 @@ mod tests {
606 .await 614 .await
607 .tags 615 .tags
608 .iter() 616 .iter()
609 .any(|t| t.as_vec()[0].eq("d") && t.as_vec()[1].eq("123412341")) 617 .any(|t| t.as_slice()[0].eq("d") && t.as_slice()[1].eq("123412341"))
610 ) 618 )
611 } 619 }
612 620
@@ -617,36 +625,44 @@ mod tests {
617 .await 625 .await
618 .tags 626 .tags
619 .iter() 627 .iter()
620 .any(|t| t.as_vec()[0].eq("name") && t.as_vec()[1].eq("test name")) 628 .any(|t| t.as_slice()[0].eq("name") && t.as_slice()[1].eq("test name"))
621 ) 629 )
622 } 630 }
623 631
624 #[tokio::test] 632 #[tokio::test]
625 async fn alt() { 633 async fn alt() {
626 assert!( 634 assert!(create().await.tags.iter().any(|t| t.as_slice()[0].eq("alt")
627 create().await.tags.iter().any(|t| t.as_vec()[0].eq("alt") 635 && t.as_slice()[1].eq("git repository: test name")))
628 && t.as_vec()[1].eq("git repository: test name"))
629 )
630 } 636 }
631 637
632 #[tokio::test] 638 #[tokio::test]
633 async fn description() { 639 async fn description() {
634 assert!(create().await.tags.iter().any( 640 assert!(
635 |t| t.as_vec()[0].eq("description") && t.as_vec()[1].eq("test description") 641 create()
636 )) 642 .await
643 .tags
644 .iter()
645 .any(|t| t.as_slice()[0].eq("description")
646 && t.as_slice()[1].eq("test description"))
647 )
637 } 648 }
638 649
639 #[tokio::test] 650 #[tokio::test]
640 async fn root_commit_as_reference() { 651 async fn root_commit_as_reference() {
641 assert!(create().await.tags.iter().any(|t| t.as_vec()[0].eq("r") 652 assert!(create().await.tags.iter().any(|t| t.as_slice()[0].eq("r")
642 && t.as_vec()[1].eq("5e664e5a7845cd1373c79f580ca4fe29ab5b34d2"))) 653 && t.as_slice()[1].eq("5e664e5a7845cd1373c79f580ca4fe29ab5b34d2")))
643 } 654 }
644 655
645 #[tokio::test] 656 #[tokio::test]
646 async fn git_server() { 657 async fn git_server() {
647 assert!(create().await.tags.iter().any( 658 assert!(
648 |t| t.as_vec()[0].eq("clone") && t.as_vec()[1].eq("https://localhost:1000") 659 create()
649 )) 660 .await
661 .tags
662 .iter()
663 .any(|t| t.as_slice()[0].eq("clone")
664 && t.as_slice()[1].eq("https://localhost:1000"))
665 )
650 } 666 }
651 667
652 #[tokio::test] 668 #[tokio::test]
@@ -655,21 +671,24 @@ mod tests {
655 let relays_tag: &nostr::Tag = event 671 let relays_tag: &nostr::Tag = event
656 .tags 672 .tags
657 .iter() 673 .iter()
658 .find(|t| t.as_vec()[0].eq("relays")) 674 .find(|t| t.as_slice()[0].eq("relays"))
659 .unwrap(); 675 .unwrap();
660 assert_eq!(relays_tag.as_vec().len(), 3); 676 assert_eq!(relays_tag.as_slice().len(), 3);
661 assert_eq!(relays_tag.as_vec()[1], "ws://relay1.io"); 677 assert_eq!(relays_tag.as_slice()[1], "ws://relay1.io");
662 assert_eq!(relays_tag.as_vec()[2], "ws://relay2.io"); 678 assert_eq!(relays_tag.as_slice()[2], "ws://relay2.io");
663 } 679 }
664 680
665 #[tokio::test] 681 #[tokio::test]
666 async fn web() { 682 async fn web() {
667 let event = create().await; 683 let event = create().await;
668 let web_tag: &nostr::Tag = 684 let web_tag: &nostr::Tag = event
669 event.tags.iter().find(|t| t.as_vec()[0].eq("web")).unwrap(); 685 .tags
670 assert_eq!(web_tag.as_vec().len(), 3); 686 .iter()
671 assert_eq!(web_tag.as_vec()[1], "https://exampleproject.xyz"); 687 .find(|t| t.as_slice()[0].eq("web"))
672 assert_eq!(web_tag.as_vec()[2], "https://gitworkshop.dev/123"); 688 .unwrap();
689 assert_eq!(web_tag.as_slice().len(), 3);
690 assert_eq!(web_tag.as_slice()[1], "https://exampleproject.xyz");
691 assert_eq!(web_tag.as_slice()[2], "https://gitworkshop.dev/123");
673 } 692 }
674 693
675 #[tokio::test] 694 #[tokio::test]
@@ -678,15 +697,15 @@ mod tests {
678 let maintainers_tag: &nostr::Tag = event 697 let maintainers_tag: &nostr::Tag = event
679 .tags 698 .tags
680 .iter() 699 .iter()
681 .find(|t| t.as_vec()[0].eq("maintainers")) 700 .find(|t| t.as_slice()[0].eq("maintainers"))
682 .unwrap(); 701 .unwrap();
683 assert_eq!(maintainers_tag.as_vec().len(), 3); 702 assert_eq!(maintainers_tag.as_slice().len(), 3);
684 assert_eq!( 703 assert_eq!(
685 maintainers_tag.as_vec()[1], 704 maintainers_tag.as_slice()[1],
686 TEST_KEY_1_KEYS.public_key().to_string() 705 TEST_KEY_1_KEYS.public_key().to_string()
687 ); 706 );
688 assert_eq!( 707 assert_eq!(
689 maintainers_tag.as_vec()[2], 708 maintainers_tag.as_slice()[2],
690 TEST_KEY_2_KEYS.public_key().to_string() 709 TEST_KEY_2_KEYS.public_key().to_string()
691 ); 710 );
692 } 711 }
diff --git a/src/lib/repo_state.rs b/src/lib/repo_state.rs
index a5cebab..c39db34 100644
--- a/src/lib/repo_state.rs
+++ b/src/lib/repo_state.rs
@@ -15,12 +15,12 @@ impl RepoState {
15 let event = state_events.first().context("no state events")?; 15 let event = state_events.first().context("no state events")?;
16 let mut state = HashMap::new(); 16 let mut state = HashMap::new();
17 for tag in &event.tags { 17 for tag in &event.tags {
18 if let Some(name) = tag.as_vec().first() { 18 if let Some(name) = tag.as_slice().first() {
19 if ["refs/heads/", "refs/tags", "HEAD"] 19 if ["refs/heads/", "refs/tags", "HEAD"]
20 .iter() 20 .iter()
21 .any(|s| name.starts_with(*s)) 21 .any(|s| name.starts_with(*s))
22 { 22 {
23 if let Some(value) = tag.as_vec().get(1) { 23 if let Some(value) = tag.as_slice().get(1) {
24 if Oid::from_str(value).is_ok() || value.contains("ref: refs/") { 24 if Oid::from_str(value).is_ok() || value.contains("ref: refs/") {
25 state.insert(name.to_owned(), value.to_owned()); 25 state.insert(name.to_owned(), value.to_owned());
26 } 26 }