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/cli_interactor.rs2
-rw-r--r--src/lib/client.rs140
-rw-r--r--src/lib/git/identify_ahead_behind.rs8
-rw-r--r--src/lib/git/mod.rs87
-rw-r--r--src/lib/git/nostr_url.rs136
-rw-r--r--src/lib/git_events.rs22
-rw-r--r--src/lib/login/existing.rs8
-rw-r--r--src/lib/login/fresh.rs10
-rw-r--r--src/lib/login/mod.rs14
-rw-r--r--src/lib/login/user.rs4
-rw-r--r--src/lib/mod.rs2
-rw-r--r--src/lib/repo_ref.rs46
12 files changed, 213 insertions, 266 deletions
diff --git a/src/lib/cli_interactor.rs b/src/lib/cli_interactor.rs
index 50a0f0c..1b74101 100644
--- a/src/lib/cli_interactor.rs
+++ b/src/lib/cli_interactor.rs
@@ -1,5 +1,5 @@
1use anyhow::{Context, Result}; 1use anyhow::{Context, Result};
2use dialoguer::{theme::ColorfulTheme, Confirm, Input, Password}; 2use dialoguer::{Confirm, Input, Password, theme::ColorfulTheme};
3use indicatif::TermLike; 3use indicatif::TermLike;
4#[cfg(test)] 4#[cfg(test)]
5use mockall::*; 5use mockall::*;
diff --git a/src/lib/client.rs b/src/lib/client.rs
index 32f5bd7..59ec583 100644
--- a/src/lib/client.rs
+++ b/src/lib/client.rs
@@ -19,7 +19,7 @@ use std::{
19 time::Duration, 19 time::Duration,
20}; 20};
21 21
22use anyhow::{bail, Context, Result}; 22use anyhow::{Context, Result, bail};
23use async_trait::async_trait; 23use async_trait::async_trait;
24use console::Style; 24use console::Style;
25use futures::{ 25use futures::{
@@ -29,12 +29,12 @@ use futures::{
29use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle}; 29use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle};
30#[cfg(test)] 30#[cfg(test)]
31use mockall::*; 31use mockall::*;
32use nostr::{nips::nip01::Coordinate, signer::SignerBackend, Event}; 32use nostr::{Event, nips::nip01::Coordinate, signer::SignerBackend};
33use nostr_database::NostrEventsDatabase; 33use nostr_database::NostrEventsDatabase;
34use nostr_lmdb::NostrLMDB; 34use nostr_lmdb::NostrLMDB;
35use nostr_sdk::{ 35use nostr_sdk::{
36 prelude::RelayLimits, EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, 36 EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, SingleLetterTag,
37 SingleLetterTag, Timestamp, 37 Timestamp, prelude::RelayLimits,
38}; 38};
39 39
40use crate::{ 40use crate::{
@@ -894,18 +894,16 @@ pub async fn get_state_from_cache(
894) -> Result<RepoState> { 894) -> Result<RepoState> {
895 if let Some(git_repo_path) = git_repo_path { 895 if let Some(git_repo_path) = git_repo_path {
896 RepoState::try_from( 896 RepoState::try_from(
897 get_events_from_local_cache( 897 get_events_from_local_cache(git_repo_path, vec![get_filter_state_events(
898 git_repo_path, 898 &repo_ref.coordinates(),
899 vec![get_filter_state_events(&repo_ref.coordinates())], 899 )])
900 )
901 .await?, 900 .await?,
902 ) 901 )
903 } else { 902 } else {
904 RepoState::try_from( 903 RepoState::try_from(
905 get_event_from_global_cache( 904 get_event_from_global_cache(git_repo_path, vec![get_filter_state_events(
906 git_repo_path, 905 &repo_ref.coordinates(),
907 vec![get_filter_state_events(&repo_ref.coordinates())], 906 )])
908 )
909 .await?, 907 .await?,
910 ) 908 )
911 } 909 }
@@ -975,20 +973,17 @@ async fn create_relays_request(
975 } 973 }
976 974
977 if let Some(git_repo_path) = git_repo_path { 975 if let Some(git_repo_path) = git_repo_path {
978 for event in &get_events_from_local_cache( 976 for event in &get_events_from_local_cache(git_repo_path, vec![
979 git_repo_path, 977 nostr::Filter::default()
980 vec![ 978 .kinds(vec![Kind::GitPatch])
981 nostr::Filter::default() 979 .custom_tag(
982 .kinds(vec![Kind::GitPatch]) 980 SingleLetterTag::lowercase(nostr_sdk::Alphabet::A),
983 .custom_tag( 981 repo_coordinates_without_relays
984 SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), 982 .iter()
985 repo_coordinates_without_relays 983 .map(std::string::ToString::to_string)
986 .iter() 984 .collect::<Vec<String>>(),
987 .map(std::string::ToString::to_string) 985 ),
988 .collect::<Vec<String>>(), 986 ])
989 ),
990 ],
991 )
992 .await? 987 .await?
993 { 988 {
994 if event_is_patch_set_root(event) || event_is_revision_root(event) { 989 if event_is_patch_set_root(event) || event_is_revision_root(event) {
@@ -998,11 +993,11 @@ async fn create_relays_request(
998 } 993 }
999 } 994 }
1000 995
1001 let profile_events = get_event_from_global_cache( 996 let profile_events =
1002 git_repo_path, 997 get_event_from_global_cache(git_repo_path, vec![get_filter_contributor_profiles(
1003 vec![get_filter_contributor_profiles(contributors.clone())], 998 contributors.clone(),
1004 ) 999 )])
1005 .await?; 1000 .await?;
1006 for c in &contributors { 1001 for c in &contributors {
1007 if let Some(event) = profile_events 1002 if let Some(event) = profile_events
1008 .iter() 1003 .iter()
@@ -1564,20 +1559,17 @@ pub async fn get_proposals_and_revisions_from_cache(
1564 git_repo_path: &Path, 1559 git_repo_path: &Path,
1565 repo_coordinates: HashSet<Coordinate>, 1560 repo_coordinates: HashSet<Coordinate>,
1566) -> Result<Vec<nostr::Event>> { 1561) -> Result<Vec<nostr::Event>> {
1567 let mut proposals = get_events_from_local_cache( 1562 let mut proposals = get_events_from_local_cache(git_repo_path, vec![
1568 git_repo_path, 1563 nostr::Filter::default()
1569 vec![ 1564 .kind(nostr::Kind::GitPatch)
1570 nostr::Filter::default() 1565 .custom_tag(
1571 .kind(nostr::Kind::GitPatch) 1566 nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A),
1572 .custom_tag( 1567 repo_coordinates
1573 nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), 1568 .iter()
1574 repo_coordinates 1569 .map(std::string::ToString::to_string)
1575 .iter() 1570 .collect::<Vec<String>>(),
1576 .map(std::string::ToString::to_string) 1571 ),
1577 .collect::<Vec<String>>(), 1572 ])
1578 ),
1579 ],
1580 )
1581 .await? 1573 .await?
1582 .iter() 1574 .iter()
1583 .filter(|e| event_is_patch_set_root(e)) 1575 .filter(|e| event_is_patch_set_root(e))
@@ -1593,29 +1585,23 @@ pub async fn get_all_proposal_patch_events_from_cache(
1593 repo_ref: &RepoRef, 1585 repo_ref: &RepoRef,
1594 proposal_id: &nostr::EventId, 1586 proposal_id: &nostr::EventId,
1595) -> Result<Vec<nostr::Event>> { 1587) -> Result<Vec<nostr::Event>> {
1596 let mut commit_events = get_events_from_local_cache( 1588 let mut commit_events = get_events_from_local_cache(git_repo_path, vec![
1597 git_repo_path, 1589 nostr::Filter::default()
1598 vec![ 1590 .kind(nostr::Kind::GitPatch)
1599 nostr::Filter::default() 1591 .event(*proposal_id),
1600 .kind(nostr::Kind::GitPatch) 1592 nostr::Filter::default()
1601 .event(*proposal_id), 1593 .kind(nostr::Kind::GitPatch)
1602 nostr::Filter::default() 1594 .id(*proposal_id),
1603 .kind(nostr::Kind::GitPatch) 1595 ])
1604 .id(*proposal_id),
1605 ],
1606 )
1607 .await?; 1596 .await?;
1608 1597
1609 let permissioned_users: HashSet<PublicKey> = [ 1598 let permissioned_users: HashSet<PublicKey> = [repo_ref.maintainers.clone(), vec![
1610 repo_ref.maintainers.clone(), 1599 commit_events
1611 vec![ 1600 .iter()
1612 commit_events 1601 .find(|e| e.id.eq(proposal_id))
1613 .iter() 1602 .context("proposal not in cache")?
1614 .find(|e| e.id.eq(proposal_id)) 1603 .pubkey,
1615 .context("proposal not in cache")? 1604 ]]
1616 .pubkey,
1617 ],
1618 ]
1619 .concat() 1605 .concat()
1620 .iter() 1606 .iter()
1621 .copied() 1607 .copied()
@@ -1629,15 +1615,12 @@ pub async fn get_all_proposal_patch_events_from_cache(
1629 .collect(); 1615 .collect();
1630 1616
1631 if !revision_roots.is_empty() { 1617 if !revision_roots.is_empty() {
1632 for event in get_events_from_local_cache( 1618 for event in get_events_from_local_cache(git_repo_path, vec![
1633 git_repo_path, 1619 nostr::Filter::default()
1634 vec![ 1620 .kind(nostr::Kind::GitPatch)
1635 nostr::Filter::default() 1621 .events(revision_roots)
1636 .kind(nostr::Kind::GitPatch) 1622 .authors(permissioned_users.clone()),
1637 .events(revision_roots) 1623 ])
1638 .authors(permissioned_users.clone()),
1639 ],
1640 )
1641 .await? 1624 .await?
1642 { 1625 {
1643 commit_events.push(event); 1626 commit_events.push(event);
@@ -1652,10 +1635,9 @@ pub async fn get_all_proposal_patch_events_from_cache(
1652} 1635}
1653 1636
1654pub async fn get_event_from_cache_by_id(git_repo: &Repo, event_id: &EventId) -> Result<Event> { 1637pub async fn get_event_from_cache_by_id(git_repo: &Repo, event_id: &EventId) -> Result<Event> {
1655 Ok(get_events_from_local_cache( 1638 Ok(get_events_from_local_cache(git_repo.get_path()?, vec![
1656 git_repo.get_path()?, 1639 nostr::Filter::default().id(*event_id),
1657 vec![nostr::Filter::default().id(*event_id)], 1640 ])
1658 )
1659 .await? 1641 .await?
1660 .first() 1642 .first()
1661 .context("failed to find event in cache")? 1643 .context("failed to find event in cache")?
diff --git a/src/lib/git/identify_ahead_behind.rs b/src/lib/git/identify_ahead_behind.rs
index d736522..baea687 100644
--- a/src/lib/git/identify_ahead_behind.rs
+++ b/src/lib/git/identify_ahead_behind.rs
@@ -184,10 +184,10 @@ mod tests {
184 identify_ahead_behind(&git_repo, &Some("feature".to_string()), &None)?; 184 identify_ahead_behind(&git_repo, &Some("feature".to_string()), &None)?;
185 185
186 assert_eq!(from_branch, "feature"); 186 assert_eq!(from_branch, "feature");
187 assert_eq!( 187 assert_eq!(ahead, vec![
188 ahead, 188 oid_to_sha1(&feature_oid),
189 vec![oid_to_sha1(&feature_oid), oid_to_sha1(&dev_oid_first)] 189 oid_to_sha1(&dev_oid_first)
190 ); 190 ]);
191 assert_eq!(to_branch, "main"); 191 assert_eq!(to_branch, "main");
192 assert_eq!(behind, vec![]); 192 assert_eq!(behind, vec![]);
193 193
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs
index 7a7ad5d..2b78f38 100644
--- a/src/lib/git/mod.rs
+++ b/src/lib/git/mod.rs
@@ -3,12 +3,12 @@ use std::{
3 path::{Path, PathBuf}, 3 path::{Path, PathBuf},
4}; 4};
5 5
6use anyhow::{bail, Context, Result}; 6use anyhow::{Context, Result, bail};
7use git2::{DiffOptions, Oid, Revwalk}; 7use git2::{DiffOptions, Oid, Revwalk};
8pub use identify_ahead_behind::identify_ahead_behind; 8pub use identify_ahead_behind::identify_ahead_behind;
9use nostr_sdk::{ 9use nostr_sdk::{
10 hashes::{sha1::Hash as Sha1Hash, Hash},
11 Tags, 10 Tags,
11 hashes::{Hash, sha1::Hash as Sha1Hash},
12}; 12};
13 13
14use crate::git_events::{get_commit_id_from_patch, tag_value}; 14use crate::git_events::{get_commit_id_from_patch, tag_value};
@@ -1493,10 +1493,10 @@ mod tests {
1493 &oid_to_sha1(&feature_oid), 1493 &oid_to_sha1(&feature_oid),
1494 )?; 1494 )?;
1495 assert_eq!(ahead, vec![]); 1495 assert_eq!(ahead, vec![]);
1496 assert_eq!( 1496 assert_eq!(behind, vec![
1497 behind, 1497 oid_to_sha1(&behind_2_oid),
1498 vec![oid_to_sha1(&behind_2_oid), oid_to_sha1(&behind_1_oid),], 1498 oid_to_sha1(&behind_1_oid),
1499 ); 1499 ],);
1500 Ok(()) 1500 Ok(())
1501 } 1501 }
1502 1502
@@ -1518,10 +1518,10 @@ mod tests {
1518 &oid_to_sha1(&main_oid), 1518 &oid_to_sha1(&main_oid),
1519 &oid_to_sha1(&ahead_2_oid), 1519 &oid_to_sha1(&ahead_2_oid),
1520 )?; 1520 )?;
1521 assert_eq!( 1521 assert_eq!(ahead, vec![
1522 ahead, 1522 oid_to_sha1(&ahead_2_oid),
1523 vec![oid_to_sha1(&ahead_2_oid), oid_to_sha1(&ahead_1_oid),], 1523 oid_to_sha1(&ahead_1_oid),
1524 ); 1524 ],);
1525 assert_eq!(behind, vec![]); 1525 assert_eq!(behind, vec![]);
1526 Ok(()) 1526 Ok(())
1527 } 1527 }
@@ -1550,14 +1550,14 @@ mod tests {
1550 &oid_to_sha1(&behind_2_oid), 1550 &oid_to_sha1(&behind_2_oid),
1551 &oid_to_sha1(&ahead_2_oid), 1551 &oid_to_sha1(&ahead_2_oid),
1552 )?; 1552 )?;
1553 assert_eq!( 1553 assert_eq!(ahead, vec![
1554 ahead, 1554 oid_to_sha1(&ahead_2_oid),
1555 vec![oid_to_sha1(&ahead_2_oid), oid_to_sha1(&ahead_1_oid)], 1555 oid_to_sha1(&ahead_1_oid)
1556 ); 1556 ],);
1557 assert_eq!( 1557 assert_eq!(behind, vec![
1558 behind, 1558 oid_to_sha1(&behind_2_oid),
1559 vec![oid_to_sha1(&behind_2_oid), oid_to_sha1(&behind_1_oid)], 1559 oid_to_sha1(&behind_1_oid)
1560 ); 1560 ],);
1561 Ok(()) 1561 Ok(())
1562 } 1562 }
1563 } 1563 }
@@ -2212,10 +2212,9 @@ mod tests {
2212 test_repo.populate_with_test_branch()?; 2212 test_repo.populate_with_test_branch()?;
2213 test_repo.checkout("main")?; 2213 test_repo.checkout("main")?;
2214 2214
2215 assert_eq!( 2215 assert_eq!(git_repo.parse_starting_commits("HEAD~1")?, vec![
2216 git_repo.parse_starting_commits("HEAD~1")?, 2216 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?
2217 vec![str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?], 2217 ],);
2218 );
2219 Ok(()) 2218 Ok(())
2220 } 2219 }
2221 2220
@@ -2225,10 +2224,9 @@ mod tests {
2225 let git_repo = Repo::from_path(&test_repo.dir)?; 2224 let git_repo = Repo::from_path(&test_repo.dir)?;
2226 test_repo.populate_with_test_branch()?; 2225 test_repo.populate_with_test_branch()?;
2227 2226
2228 assert_eq!( 2227 assert_eq!(git_repo.parse_starting_commits("HEAD~1")?, vec![
2229 git_repo.parse_starting_commits("HEAD~1")?, 2228 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?
2230 vec![str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?], 2229 ],);
2231 );
2232 Ok(()) 2230 Ok(())
2233 } 2231 }
2234 } 2232 }
@@ -2242,13 +2240,10 @@ mod tests {
2242 test_repo.populate_with_test_branch()?; 2240 test_repo.populate_with_test_branch()?;
2243 test_repo.checkout("main")?; 2241 test_repo.checkout("main")?;
2244 2242
2245 assert_eq!( 2243 assert_eq!(git_repo.parse_starting_commits("HEAD~2")?, vec![
2246 git_repo.parse_starting_commits("HEAD~2")?, 2244 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
2247 vec![ 2245 str_to_sha1("af474d8d271490e5c635aad337abdc050034b16a")?,
2248 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?, 2246 ],);
2249 str_to_sha1("af474d8d271490e5c635aad337abdc050034b16a")?,
2250 ],
2251 );
2252 Ok(()) 2247 Ok(())
2253 } 2248 }
2254 } 2249 }
@@ -2261,14 +2256,11 @@ mod tests {
2261 let git_repo = Repo::from_path(&test_repo.dir)?; 2256 let git_repo = Repo::from_path(&test_repo.dir)?;
2262 test_repo.populate_with_test_branch()?; 2257 test_repo.populate_with_test_branch()?;
2263 2258
2264 assert_eq!( 2259 assert_eq!(git_repo.parse_starting_commits("HEAD~3")?, vec![
2265 git_repo.parse_starting_commits("HEAD~3")?, 2260 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?,
2266 vec![ 2261 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
2267 str_to_sha1("82ff2bcc9aa94d1bd8faee723d4c8cc190d6061c")?, 2262 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
2268 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?, 2263 ],);
2269 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
2270 ],
2271 );
2272 Ok(()) 2264 Ok(())
2273 } 2265 }
2274 } 2266 }
@@ -2282,14 +2274,11 @@ mod tests {
2282 test_repo.populate_with_test_branch()?; 2274 test_repo.populate_with_test_branch()?;
2283 test_repo.checkout("main")?; 2275 test_repo.checkout("main")?;
2284 2276
2285 assert_eq!( 2277 assert_eq!(git_repo.parse_starting_commits("af474d8..a23e6b0")?, vec![
2286 git_repo.parse_starting_commits("af474d8..a23e6b0")?, 2278 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?,
2287 vec![ 2279 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?,
2288 str_to_sha1("a23e6b05aaeb7d1471b4a838b51f337d5644eeb0")?, 2280 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
2289 str_to_sha1("7ab82116068982671a8111f27dc10599172334b2")?, 2281 ],);
2290 str_to_sha1("431b84edc0d2fa118d63faa3c2db9c73d630a5ae")?,
2291 ],
2292 );
2293 Ok(()) 2282 Ok(())
2294 } 2283 }
2295 } 2284 }
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs
index 4fbc786..6b38a93 100644
--- a/src/lib/git/nostr_url.rs
+++ b/src/lib/git/nostr_url.rs
@@ -1,11 +1,11 @@
1use core::fmt; 1use core::fmt;
2use std::{collections::HashMap, str::FromStr}; 2use std::{collections::HashMap, str::FromStr};
3 3
4use anyhow::{anyhow, bail, Context, Error, Result}; 4use anyhow::{Context, Error, Result, anyhow, bail};
5use nostr::nips::{nip01::Coordinate, nip05}; 5use nostr::nips::{nip01::Coordinate, nip05};
6use nostr_sdk::{PublicKey, RelayUrl, ToBech32, Url}; 6use nostr_sdk::{PublicKey, RelayUrl, ToBech32, Url};
7 7
8use super::{get_git_config_item, save_git_config_item, Repo}; 8use super::{Repo, get_git_config_item, save_git_config_item};
9 9
10#[derive(Debug, PartialEq, Default, Clone)] 10#[derive(Debug, PartialEq, Default, Clone)]
11pub enum ServerProtocol { 11pub enum ServerProtocol {
@@ -961,24 +961,21 @@ mod tests {
961 #[test] 961 #[test]
962 fn standard() -> Result<()> { 962 fn standard() -> Result<()> {
963 assert_eq!( 963 assert_eq!(
964 format!( 964 format!("{}", NostrUrlDecoded {
965 "{}", 965 original_string: String::new(),
966 NostrUrlDecoded { 966 coordinate: Coordinate {
967 original_string: String::new(), 967 identifier: "ngit".to_string(),
968 coordinate: Coordinate { 968 public_key: PublicKey::parse(
969 identifier: "ngit".to_string(), 969 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr",
970 public_key: PublicKey::parse( 970 )
971 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", 971 .unwrap(),
972 ) 972 kind: nostr_sdk::Kind::GitRepoAnnouncement,
973 .unwrap(), 973 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()],
974 kind: nostr_sdk::Kind::GitRepoAnnouncement, 974 },
975 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], 975 protocol: None,
976 }, 976 user: None,
977 protocol: None, 977 nip05: None,
978 user: None, 978 }),
979 nip05: None,
980 }
981 ),
982 "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", 979 "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit",
983 ); 980 );
984 Ok(()) 981 Ok(())
@@ -987,24 +984,21 @@ mod tests {
987 #[test] 984 #[test]
988 fn no_relay() -> Result<()> { 985 fn no_relay() -> Result<()> {
989 assert_eq!( 986 assert_eq!(
990 format!( 987 format!("{}", NostrUrlDecoded {
991 "{}", 988 original_string: String::new(),
992 NostrUrlDecoded { 989 coordinate: Coordinate {
993 original_string: String::new(), 990 identifier: "ngit".to_string(),
994 coordinate: Coordinate { 991 public_key: PublicKey::parse(
995 identifier: "ngit".to_string(), 992 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr",
996 public_key: PublicKey::parse( 993 )
997 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", 994 .unwrap(),
998 ) 995 kind: nostr_sdk::Kind::GitRepoAnnouncement,
999 .unwrap(), 996 relays: vec![],
1000 kind: nostr_sdk::Kind::GitRepoAnnouncement, 997 },
1001 relays: vec![], 998 protocol: None,
1002 }, 999 user: None,
1003 protocol: None, 1000 nip05: None,
1004 user: None, 1001 }),
1005 nip05: None,
1006 }
1007 ),
1008 "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit", 1002 "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit",
1009 ); 1003 );
1010 Ok(()) 1004 Ok(())
@@ -1013,24 +1007,21 @@ mod tests {
1013 #[test] 1007 #[test]
1014 fn with_protocol() -> Result<()> { 1008 fn with_protocol() -> Result<()> {
1015 assert_eq!( 1009 assert_eq!(
1016 format!( 1010 format!("{}", NostrUrlDecoded {
1017 "{}", 1011 original_string: String::new(),
1018 NostrUrlDecoded { 1012 coordinate: Coordinate {
1019 original_string: String::new(), 1013 identifier: "ngit".to_string(),
1020 coordinate: Coordinate { 1014 public_key: PublicKey::parse(
1021 identifier: "ngit".to_string(), 1015 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr",
1022 public_key: PublicKey::parse( 1016 )
1023 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", 1017 .unwrap(),
1024 ) 1018 kind: nostr_sdk::Kind::GitRepoAnnouncement,
1025 .unwrap(), 1019 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()],
1026 kind: nostr_sdk::Kind::GitRepoAnnouncement, 1020 },
1027 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], 1021 protocol: Some(ServerProtocol::Ssh),
1028 }, 1022 user: None,
1029 protocol: Some(ServerProtocol::Ssh), 1023 nip05: None,
1030 user: None, 1024 }),
1031 nip05: None,
1032 }
1033 ),
1034 "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", 1025 "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit",
1035 ); 1026 );
1036 Ok(()) 1027 Ok(())
@@ -1039,24 +1030,21 @@ mod tests {
1039 #[test] 1030 #[test]
1040 fn with_protocol_and_user() -> Result<()> { 1031 fn with_protocol_and_user() -> Result<()> {
1041 assert_eq!( 1032 assert_eq!(
1042 format!( 1033 format!("{}", NostrUrlDecoded {
1043 "{}", 1034 original_string: String::new(),
1044 NostrUrlDecoded { 1035 coordinate: Coordinate {
1045 original_string: String::new(), 1036 identifier: "ngit".to_string(),
1046 coordinate: Coordinate { 1037 public_key: PublicKey::parse(
1047 identifier: "ngit".to_string(), 1038 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr",
1048 public_key: PublicKey::parse( 1039 )
1049 "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", 1040 .unwrap(),
1050 ) 1041 kind: nostr_sdk::Kind::GitRepoAnnouncement,
1051 .unwrap(), 1042 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()],
1052 kind: nostr_sdk::Kind::GitRepoAnnouncement, 1043 },
1053 relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], 1044 protocol: Some(ServerProtocol::Ssh),
1054 }, 1045 user: Some("bla".to_string()),
1055 protocol: Some(ServerProtocol::Ssh), 1046 nip05: None,
1056 user: Some("bla".to_string()), 1047 }),
1057 nip05: None,
1058 }
1059 ),
1060 "nostr://bla@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit", 1048 "nostr://bla@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit",
1061 ); 1049 );
1062 Ok(()) 1050 Ok(())
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs
index d8564ae..af469d3 100644
--- a/src/lib/git_events.rs
+++ b/src/lib/git_events.rs
@@ -1,10 +1,10 @@
1use std::{str::FromStr, sync::Arc}; 1use std::{str::FromStr, sync::Arc};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{Context, Result, bail};
4use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; 4use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19};
5use nostr_sdk::{ 5use nostr_sdk::{
6 hashes::sha1::Hash as Sha1Hash, Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, 6 Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, RelayUrl, Tag, TagKind,
7 PublicKey, RelayUrl, Tag, TagKind, TagStandard, 7 TagStandard, hashes::sha1::Hash as Sha1Hash,
8}; 8};
9 9
10use crate::{ 10use crate::{
@@ -131,15 +131,14 @@ pub async fn generate_patch_event(
131 // code that makes it into the main branch, assuming 131 // code that makes it into the main branch, assuming
132 // the commit id is correct 132 // the commit id is correct
133 Tag::from_standardized(TagStandard::Reference(commit.to_string())), 133 Tag::from_standardized(TagStandard::Reference(commit.to_string())),
134 Tag::custom( 134 Tag::custom(TagKind::Custom(std::borrow::Cow::Borrowed("alt")), vec![
135 TagKind::Custom(std::borrow::Cow::Borrowed("alt")), 135 format!(
136 vec![format!(
137 "git patch: {}", 136 "git patch: {}",
138 git_repo 137 git_repo
139 .get_commit_message_summary(commit) 138 .get_commit_message_summary(commit)
140 .unwrap_or_default() 139 .unwrap_or_default()
141 )], 140 ),
142 ), 141 ]),
143 ], 142 ],
144 if let Some(thread_event_id) = thread_event_id { 143 if let Some(thread_event_id) = thread_event_id {
145 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event { 144 vec![Tag::from_standardized(nostr_sdk::TagStandard::Event {
@@ -203,10 +202,9 @@ pub async fn generate_patch_event(
203 .collect(), 202 .collect(),
204 vec![ 203 vec![
205 // a fallback is now in place to extract this from the patch 204 // a fallback is now in place to extract this from the patch
206 Tag::custom( 205 Tag::custom(TagKind::Custom(std::borrow::Cow::Borrowed("commit")), vec![
207 TagKind::Custom(std::borrow::Cow::Borrowed("commit")), 206 commit.to_string(),
208 vec![commit.to_string()], 207 ]),
209 ),
210 // this is required as patches cannot be relied upon to include the 'base 208 // this is required as patches cannot be relied upon to include the 'base
211 // commit' 209 // commit'
212 Tag::custom( 210 Tag::custom(
diff --git a/src/lib/login/existing.rs b/src/lib/login/existing.rs
index 4606c22..efe187e 100644
--- a/src/lib/login/existing.rs
+++ b/src/lib/login/existing.rs
@@ -1,15 +1,15 @@
1use std::{str::FromStr, sync::Arc, time::Duration}; 1use std::{str::FromStr, sync::Arc, time::Duration};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{Context, Result, bail};
4use nostr::nips::nip46::NostrConnectURI; 4use nostr::nips::nip46::NostrConnectURI;
5use nostr_connect::client::NostrConnect; 5use nostr_connect::client::NostrConnect;
6use nostr_sdk::{NostrSigner, PublicKey}; 6use nostr_sdk::{NostrSigner, PublicKey};
7 7
8use super::{ 8use super::{
9 SignerInfo, SignerInfoSource,
9 key_encryption::decrypt_key, 10 key_encryption::decrypt_key,
10 print_logged_in_as, 11 print_logged_in_as,
11 user::{get_user_details, UserRef}, 12 user::{UserRef, get_user_details},
12 SignerInfo, SignerInfoSource,
13}; 13};
14#[cfg(not(test))] 14#[cfg(not(test))]
15use crate::client::Client; 15use crate::client::Client;
@@ -18,7 +18,7 @@ use crate::client::MockConnect;
18use crate::{ 18use crate::{
19 cli_interactor::{Interactor, InteractorPrompt, PromptPasswordParms}, 19 cli_interactor::{Interactor, InteractorPrompt, PromptPasswordParms},
20 client::fetch_public_key, 20 client::fetch_public_key,
21 git::{get_git_config_item, Repo, RepoActions}, 21 git::{Repo, RepoActions, get_git_config_item},
22}; 22};
23 23
24/// load signer from git config and UserProfile from cache or relays 24/// load signer from git config and UserProfile from cache or relays
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs
index 7cdbde8..635c0b3 100644
--- a/src/lib/login/fresh.rs
+++ b/src/lib/login/fresh.rs
@@ -1,6 +1,6 @@
1use std::{str::FromStr, sync::Arc, time::Duration}; 1use std::{str::FromStr, sync::Arc, time::Duration};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{Context, Result, bail};
4use console::Style; 4use console::Style;
5use dialoguer::theme::{ColorfulTheme, Theme}; 5use dialoguer::theme::{ColorfulTheme, Theme};
6use nostr::nips::{nip05, nip46::NostrConnectURI}; 6use nostr::nips::{nip05, nip46::NostrConnectURI};
@@ -10,11 +10,11 @@ use qrcode::QrCode;
10use tokio::{signal, sync::Mutex}; 10use tokio::{signal, sync::Mutex};
11 11
12use super::{ 12use super::{
13 SignerInfo, SignerInfoSource,
13 existing::load_existing_login, 14 existing::load_existing_login,
14 key_encryption::decrypt_key, 15 key_encryption::decrypt_key,
15 print_logged_in_as, 16 print_logged_in_as,
16 user::{get_user_details, UserRef}, 17 user::{UserRef, get_user_details},
17 SignerInfo, SignerInfoSource,
18}; 18};
19#[cfg(not(test))] 19#[cfg(not(test))]
20use crate::client::Client; 20use crate::client::Client;
@@ -25,8 +25,8 @@ use crate::{
25 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms, 25 Interactor, InteractorPrompt, Printer, PromptChoiceParms, PromptConfirmParms,
26 PromptInputParms, PromptPasswordParms, 26 PromptInputParms, PromptPasswordParms,
27 }, 27 },
28 client::{send_events, Connect}, 28 client::{Connect, send_events},
29 git::{remove_git_config_item, save_git_config_item, Repo, RepoActions}, 29 git::{Repo, RepoActions, remove_git_config_item, save_git_config_item},
30}; 30};
31 31
32pub async fn fresh_login_or_signup( 32pub async fn fresh_login_or_signup(
diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs
index 0be1e5d..a1c45d5 100644
--- a/src/lib/login/mod.rs
+++ b/src/lib/login/mod.rs
@@ -79,15 +79,11 @@ fn print_logged_in_as(
79 "failed to find your relay list. consider using another nostr client to create one to enhance your nostr experience." 79 "failed to find your relay list. consider using another nostr client to create one to enhance your nostr experience."
80 ); 80 );
81 } 81 }
82 eprintln!( 82 eprintln!("logged in as {}{}", user_ref.metadata.name, match source {
83 "logged in as {}{}", 83 SignerInfoSource::CommandLineArguments => " via cli arguments",
84 user_ref.metadata.name, 84 SignerInfoSource::GitLocal => " to local repository",
85 match source { 85 SignerInfoSource::GitGlobal => "",
86 SignerInfoSource::CommandLineArguments => " via cli arguments", 86 });
87 SignerInfoSource::GitLocal => " to local repository",
88 SignerInfoSource::GitGlobal => "",
89 }
90 );
91 Ok(()) 87 Ok(())
92} 88}
93 89
diff --git a/src/lib/login/user.rs b/src/lib/login/user.rs
index de4a2d9..107e765 100644
--- a/src/lib/login/user.rs
+++ b/src/lib/login/user.rs
@@ -1,6 +1,6 @@
1use std::{collections::HashSet, path::Path}; 1use std::{collections::HashSet, path::Path};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{Context, Result, bail};
4use nostr::PublicKey; 4use nostr::PublicKey;
5use nostr_sdk::{Alphabet, JsonUtil, Kind, SingleLetterTag, Timestamp, ToBech32}; 5use nostr_sdk::{Alphabet, JsonUtil, Kind, SingleLetterTag, Timestamp, ToBech32};
6use serde::{self, Deserialize, Serialize}; 6use serde::{self, Deserialize, Serialize};
@@ -9,7 +9,7 @@ use serde::{self, Deserialize, Serialize};
9use crate::client::Client; 9use crate::client::Client;
10#[cfg(test)] 10#[cfg(test)]
11use crate::client::MockConnect; 11use crate::client::MockConnect;
12use crate::client::{get_event_from_global_cache, Connect}; 12use crate::client::{Connect, get_event_from_global_cache};
13 13
14#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 14#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
15pub struct UserRef { 15pub struct UserRef {
diff --git a/src/lib/mod.rs b/src/lib/mod.rs
index 6e6f6fe..2072a80 100644
--- a/src/lib/mod.rs
+++ b/src/lib/mod.rs
@@ -6,7 +6,7 @@ pub mod login;
6pub mod repo_ref; 6pub mod repo_ref;
7pub mod repo_state; 7pub mod repo_state;
8 8
9use anyhow::{anyhow, Result}; 9use anyhow::{Result, anyhow};
10use directories::ProjectDirs; 10use directories::ProjectDirs;
11 11
12pub fn get_dirs() -> Result<ProjectDirs> { 12pub fn get_dirs() -> Result<ProjectDirs> {
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs
index 5d6f4eb..a9d1186 100644
--- a/src/lib/repo_ref.rs
+++ b/src/lib/repo_ref.rs
@@ -6,9 +6,9 @@ use std::{
6 sync::Arc, 6 sync::Arc,
7}; 7};
8 8
9use anyhow::{bail, Context, Result}; 9use anyhow::{Context, Result, bail};
10use console::Style; 10use console::Style;
11use nostr::{nips::nip01::Coordinate, FromBech32, PublicKey, Tag, TagStandard, ToBech32}; 11use nostr::{FromBech32, PublicKey, Tag, TagStandard, ToBech32, nips::nip01::Coordinate};
12use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; 12use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp};
13use serde::{Deserialize, Serialize}; 13use serde::{Deserialize, Serialize};
14 14
@@ -18,10 +18,10 @@ use crate::{
18 cli_interactor::{ 18 cli_interactor::{
19 Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms, PromptInputParms, 19 Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms, PromptInputParms,
20 }, 20 },
21 client::{consolidate_fetch_reports, get_repo_ref_from_cache, sign_event, Connect}, 21 client::{Connect, consolidate_fetch_reports, get_repo_ref_from_cache, sign_event},
22 git::{ 22 git::{
23 nostr_url::{use_nip05_git_config_cache_to_find_nip05_from_public_key, NostrUrlDecoded},
24 Repo, RepoActions, 23 Repo, RepoActions,
24 nostr_url::{NostrUrlDecoded, use_nip05_git_config_cache_to_find_nip05_from_public_key},
25 }, 25 },
26 login::user::get_user_details, 26 login::user::get_user_details,
27}; 27};
@@ -237,20 +237,17 @@ impl RepoRef {
237 237
238 pub fn to_nostr_git_url(&self, git_repo: &Option<&Repo>) -> String { 238 pub fn to_nostr_git_url(&self, git_repo: &Option<&Repo>) -> String {
239 let c = self.coordinate_with_hint(); 239 let c = self.coordinate_with_hint();
240 format!( 240 format!("{}", NostrUrlDecoded {
241 "{}", 241 original_string: String::new(),
242 NostrUrlDecoded { 242 nip05: use_nip05_git_config_cache_to_find_nip05_from_public_key(
243 original_string: String::new(), 243 &c.public_key,
244 nip05: use_nip05_git_config_cache_to_find_nip05_from_public_key( 244 git_repo,
245 &c.public_key, 245 )
246 git_repo, 246 .unwrap_or_default(),
247 ) 247 coordinate: c,
248 .unwrap_or_default(), 248 protocol: None,
249 coordinate: c, 249 user: None,
250 protocol: None, 250 })
251 user: None,
252 }
253 )
254 } 251 }
255} 252}
256 253
@@ -521,14 +518,11 @@ pub fn save_repo_config_to_yaml(
521 .context("failed to convert public key into npub")?, 518 .context("failed to convert public key into npub")?,
522 ); 519 );
523 } 520 }
524 serde_yaml::to_writer( 521 serde_yaml::to_writer(file, &RepoConfigYaml {
525 file, 522 identifier: Some(identifier),
526 &RepoConfigYaml { 523 maintainers: maintainers_npubs,
527 identifier: Some(identifier), 524 relays,
528 maintainers: maintainers_npubs, 525 })
529 relays,
530 },
531 )
532 .context("failed to write maintainers to maintainers.yaml file serde_yaml") 526 .context("failed to write maintainers to maintainers.yaml file serde_yaml")
533} 527}
534 528