diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-09-06 10:45:21 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-09-06 11:05:11 +0100 |
| commit | 6e7e7bd3497d2a77fda34e27f65955b8ac09b3be (patch) | |
| tree | 7d36f9feb568e63823e017b85d5a84443b1bb20c /src | |
| parent | 935bc0ca630d7964082966e4c0caeb255f5a4f57 (diff) | |
fix(remote): `list` apply protocols selection
used in fetch and tweak the error reporting
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/git_remote_nostr/list.rs | 138 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/main.rs | 18 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 16 | ||||
| -rw-r--r-- | src/lib/git/nostr_url.rs | 171 |
4 files changed, 229 insertions, 114 deletions
diff --git a/src/bin/git_remote_nostr/list.rs b/src/bin/git_remote_nostr/list.rs index 097f070..26f699d 100644 --- a/src/bin/git_remote_nostr/list.rs +++ b/src/bin/git_remote_nostr/list.rs | |||
| @@ -1,25 +1,35 @@ | |||
| 1 | use core::str; | 1 | use core::str; |
| 2 | use std::collections::HashMap; | 2 | use std::collections::HashMap; |
| 3 | 3 | ||
| 4 | use anyhow::{Context, Result}; | 4 | use anyhow::{anyhow, Context, Result}; |
| 5 | use auth_git2::GitAuthenticator; | 5 | use auth_git2::GitAuthenticator; |
| 6 | use client::get_state_from_cache; | 6 | use client::get_state_from_cache; |
| 7 | use git::RepoActions; | 7 | use git::RepoActions; |
| 8 | use git_events::{event_to_cover_letter, get_commit_id_from_patch}; | 8 | use git_events::{event_to_cover_letter, get_commit_id_from_patch}; |
| 9 | use ngit::{client, git, git_events, login::get_curent_user, repo_ref}; | 9 | use ngit::{ |
| 10 | client, | ||
| 11 | git::{ | ||
| 12 | self, | ||
| 13 | nostr_url::{CloneUrl, NostrUrlDecoded, ServerProtocol}, | ||
| 14 | }, | ||
| 15 | git_events, | ||
| 16 | login::get_curent_user, | ||
| 17 | repo_ref, | ||
| 18 | }; | ||
| 10 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; | 19 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; |
| 11 | use repo_ref::RepoRef; | 20 | use repo_ref::RepoRef; |
| 12 | 21 | ||
| 13 | use crate::{ | 22 | use crate::{ |
| 14 | git::Repo, | 23 | git::Repo, |
| 15 | utils::{ | 24 | utils::{ |
| 16 | get_open_proposals, get_short_git_server_name, switch_clone_url_between_ssh_and_https, | 25 | get_open_proposals, get_read_protocols_to_try, get_short_git_server_name, join_with_and, |
| 17 | }, | 26 | }, |
| 18 | }; | 27 | }; |
| 19 | 28 | ||
| 20 | pub async fn run_list( | 29 | pub async fn run_list( |
| 21 | git_repo: &Repo, | 30 | git_repo: &Repo, |
| 22 | repo_ref: &RepoRef, | 31 | repo_ref: &RepoRef, |
| 32 | decoded_nostr_url: &NostrUrlDecoded, | ||
| 23 | for_push: bool, | 33 | for_push: bool, |
| 24 | ) -> Result<HashMap<String, HashMap<String, String>>> { | 34 | ) -> Result<HashMap<String, HashMap<String, String>>> { |
| 25 | let nostr_state = | 35 | let nostr_state = |
| @@ -31,7 +41,7 @@ pub async fn run_list( | |||
| 31 | 41 | ||
| 32 | let term = console::Term::stderr(); | 42 | let term = console::Term::stderr(); |
| 33 | 43 | ||
| 34 | let remote_states = list_from_remotes(&term, git_repo, &repo_ref.git_server)?; | 44 | let remote_states = list_from_remotes(&term, git_repo, &repo_ref.git_server, decoded_nostr_url); |
| 35 | 45 | ||
| 36 | let mut state = if let Some(nostr_state) = nostr_state { | 46 | let mut state = if let Some(nostr_state) = nostr_state { |
| 37 | for (name, value) in &nostr_state.state { | 47 | for (name, value) in &nostr_state.state { |
| @@ -122,41 +132,115 @@ pub fn list_from_remotes( | |||
| 122 | term: &console::Term, | 132 | term: &console::Term, |
| 123 | git_repo: &Repo, | 133 | git_repo: &Repo, |
| 124 | git_servers: &Vec<String>, | 134 | git_servers: &Vec<String>, |
| 125 | ) -> Result<HashMap<String, HashMap<String, String>>> { | 135 | decoded_nostr_url: &NostrUrlDecoded, // Add this parameter |
| 136 | ) -> HashMap<String, HashMap<String, String>> { | ||
| 126 | let mut remote_states = HashMap::new(); | 137 | let mut remote_states = HashMap::new(); |
| 138 | let mut errors = HashMap::new(); | ||
| 127 | for url in git_servers { | 139 | for url in git_servers { |
| 128 | let short_name = get_short_git_server_name(git_repo, url); | 140 | match list_from_remote(term, git_repo, url, decoded_nostr_url) { |
| 129 | term.write_line(format!("fetching refs list: {short_name}...").as_str())?; | 141 | Err(error) => { |
| 130 | match list_from_remote(git_repo, url) { | 142 | errors.insert(url, error); |
| 131 | Ok(remote_state) => { | ||
| 132 | remote_states.insert(url.clone(), remote_state); | ||
| 133 | } | 143 | } |
| 134 | Err(error1) => { | 144 | Ok(state) => { |
| 135 | if let Ok(alternative_url) = switch_clone_url_between_ssh_and_https(url) { | 145 | remote_states.insert(url.to_string(), state); |
| 136 | match list_from_remote(git_repo, &alternative_url) { | 146 | } |
| 137 | Ok(remote_state) => { | 147 | } |
| 138 | remote_states.insert(url.clone(), remote_state); | 148 | } |
| 139 | } | 149 | remote_states |
| 140 | Err(error2) => { | 150 | } |
| 141 | term.write_line( | 151 | |
| 142 | format!("WARNING: {short_name} failed to list refs error: {error1}\r\nand alternative protocol {alternative_url}: {error2}").as_str(), | 152 | pub fn list_from_remote( |
| 143 | )?; | 153 | term: &console::Term, |
| 144 | } | 154 | git_repo: &Repo, |
| 145 | } | 155 | git_server_url: &str, |
| 146 | } else { | 156 | decoded_nostr_url: &NostrUrlDecoded, // Add this parameter |
| 157 | ) -> Result<HashMap<String, String>> { | ||
| 158 | let server_url = git_server_url.parse::<CloneUrl>()?; | ||
| 159 | let protocols_to_attempt = get_read_protocols_to_try(&server_url, decoded_nostr_url); | ||
| 160 | |||
| 161 | let mut failed_protocols = vec![]; | ||
| 162 | let mut remote_state: Option<HashMap<String, String>> = None; | ||
| 163 | |||
| 164 | for protocol in &protocols_to_attempt { | ||
| 165 | term.write_line( | ||
| 166 | format!( | ||
| 167 | "fetching ref list from {} over {protocol}...", | ||
| 168 | server_url.domain(), | ||
| 169 | ) | ||
| 170 | .as_str(), | ||
| 171 | )?; | ||
| 172 | |||
| 173 | let formatted_url = server_url.format_as(protocol, &decoded_nostr_url.user)?; | ||
| 174 | let res = if [ServerProtocol::UnauthHttps, ServerProtocol::UnauthHttp].contains(protocol) { | ||
| 175 | list_from_remote_url_unauthenticated(git_repo, &formatted_url) | ||
| 176 | } else { | ||
| 177 | list_from_remote_url(git_repo, &formatted_url) | ||
| 178 | }; | ||
| 179 | |||
| 180 | match res { | ||
| 181 | Ok(state) => { | ||
| 182 | remote_state = Some(state); | ||
| 183 | if !failed_protocols.is_empty() { | ||
| 147 | term.write_line( | 184 | term.write_line( |
| 148 | format!("WARNING: {short_name} failed to list refs error: {error1}",) | 185 | format!( |
| 149 | .as_str(), | 186 | "list: succeeded over {protocol} for {}", |
| 187 | server_url.domain(), | ||
| 188 | ) | ||
| 189 | .as_str(), | ||
| 150 | )?; | 190 | )?; |
| 151 | } | 191 | } |
| 192 | break; | ||
| 193 | } | ||
| 194 | Err(error) => { | ||
| 195 | term.write_line( | ||
| 196 | format!("list: {formatted_url} failed over {protocol}: {error}").as_str(), | ||
| 197 | )?; | ||
| 198 | failed_protocols.push(protocol); | ||
| 152 | } | 199 | } |
| 153 | } | 200 | } |
| 154 | term.clear_last_lines(1)?; | 201 | term.clear_last_lines(1)?; |
| 155 | } | 202 | } |
| 156 | Ok(remote_states) | 203 | if let Some(remote_state) = remote_state { |
| 204 | Ok(remote_state) | ||
| 205 | } else { | ||
| 206 | let error = anyhow!( | ||
| 207 | "{} failed over {}{}", | ||
| 208 | server_url.domain(), | ||
| 209 | join_with_and(&failed_protocols), | ||
| 210 | if decoded_nostr_url.protocol.is_some() { | ||
| 211 | " and nostr url contains protocol override so no other protocols were attempted" | ||
| 212 | } else { | ||
| 213 | "" | ||
| 214 | }, | ||
| 215 | ); | ||
| 216 | term.write_line(format!("list: {error}").as_str())?; | ||
| 217 | Err(error) | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | fn list_from_remote_url_unauthenticated( | ||
| 222 | git_repo: &Repo, | ||
| 223 | git_server_remote_url: &str, | ||
| 224 | ) -> Result<HashMap<String, String>> { | ||
| 225 | let mut git_server_remote = git_repo.git_repo.remote_anonymous(git_server_remote_url)?; | ||
| 226 | let remote_callbacks = git2::RemoteCallbacks::new(); | ||
| 227 | git_server_remote.connect_auth(git2::Direction::Fetch, Some(remote_callbacks), None)?; | ||
| 228 | let mut state = HashMap::new(); | ||
| 229 | for head in git_server_remote.list()? { | ||
| 230 | if let Some(symbolic_reference) = head.symref_target() { | ||
| 231 | state.insert( | ||
| 232 | head.name().to_string(), | ||
| 233 | format!("ref: {symbolic_reference}"), | ||
| 234 | ); | ||
| 235 | } else { | ||
| 236 | state.insert(head.name().to_string(), head.oid().to_string()); | ||
| 237 | } | ||
| 238 | } | ||
| 239 | git_server_remote.disconnect()?; | ||
| 240 | Ok(state) | ||
| 157 | } | 241 | } |
| 158 | 242 | ||
| 159 | fn list_from_remote( | 243 | fn list_from_remote_url( |
| 160 | git_repo: &Repo, | 244 | git_repo: &Repo, |
| 161 | git_server_remote_url: &str, | 245 | git_server_remote_url: &str, |
| 162 | ) -> Result<HashMap<String, String>> { | 246 | ) -> Result<HashMap<String, String>> { |
diff --git a/src/bin/git_remote_nostr/main.rs b/src/bin/git_remote_nostr/main.rs index a3fc5f8..e2738d2 100644 --- a/src/bin/git_remote_nostr/main.rs +++ b/src/bin/git_remote_nostr/main.rs | |||
| @@ -75,13 +75,21 @@ async fn main() -> Result<()> { | |||
| 75 | println!("unsupported"); | 75 | println!("unsupported"); |
| 76 | } | 76 | } |
| 77 | ["fetch", oid, refstr] => { | 77 | ["fetch", oid, refstr] => { |
| 78 | fetch::run_fetch(&git_repo, &repo_ref, &decoded_nostr_url, &stdin, oid, refstr).await?; | 78 | fetch::run_fetch( |
| 79 | &git_repo, | ||
| 80 | &repo_ref, | ||
| 81 | &decoded_nostr_url, | ||
| 82 | &stdin, | ||
| 83 | oid, | ||
| 84 | refstr, | ||
| 85 | ) | ||
| 86 | .await?; | ||
| 79 | } | 87 | } |
| 80 | ["push", refspec] => { | 88 | ["push", refspec] => { |
| 81 | push::run_push( | 89 | push::run_push( |
| 82 | &git_repo, | 90 | &git_repo, |
| 83 | &repo_ref, | 91 | &repo_ref, |
| 84 | nostr_remote_url, | 92 | &decoded_nostr_url, |
| 85 | &stdin, | 93 | &stdin, |
| 86 | refspec, | 94 | refspec, |
| 87 | &client, | 95 | &client, |
| @@ -90,10 +98,12 @@ async fn main() -> Result<()> { | |||
| 90 | .await?; | 98 | .await?; |
| 91 | } | 99 | } |
| 92 | ["list"] => { | 100 | ["list"] => { |
| 93 | list_outputs = Some(list::run_list(&git_repo, &repo_ref, false).await?); | 101 | list_outputs = |
| 102 | Some(list::run_list(&git_repo, &repo_ref, &decoded_nostr_url, false).await?); | ||
| 94 | } | 103 | } |
| 95 | ["list", "for-push"] => { | 104 | ["list", "for-push"] => { |
| 96 | list_outputs = Some(list::run_list(&git_repo, &repo_ref, true).await?); | 105 | list_outputs = |
| 106 | Some(list::run_list(&git_repo, &repo_ref, &decoded_nostr_url, true).await?); | ||
| 97 | } | 107 | } |
| 98 | [] => { | 108 | [] => { |
| 99 | return Ok(()); | 109 | return Ok(()); |
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index 441c341..2c9c7e1 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs | |||
| @@ -15,7 +15,7 @@ use git_events::{ | |||
| 15 | }; | 15 | }; |
| 16 | use ngit::{ | 16 | use ngit::{ |
| 17 | client::{self, get_event_from_cache_by_id}, | 17 | client::{self, get_event_from_cache_by_id}, |
| 18 | git, | 18 | git::{self, nostr_url::NostrUrlDecoded}, |
| 19 | git_events::{self, get_event_root}, | 19 | git_events::{self, get_event_root}, |
| 20 | login::{self, get_curent_user}, | 20 | login::{self, get_curent_user}, |
| 21 | repo_ref, repo_state, | 21 | repo_ref, repo_state, |
| @@ -42,7 +42,7 @@ use crate::{ | |||
| 42 | pub async fn run_push( | 42 | pub async fn run_push( |
| 43 | git_repo: &Repo, | 43 | git_repo: &Repo, |
| 44 | repo_ref: &RepoRef, | 44 | repo_ref: &RepoRef, |
| 45 | nostr_remote_url: &str, | 45 | decoded_nostr_url: &NostrUrlDecoded, |
| 46 | stdin: &Stdin, | 46 | stdin: &Stdin, |
| 47 | initial_refspec: &str, | 47 | initial_refspec: &str, |
| 48 | client: &Client, | 48 | client: &Client, |
| @@ -66,7 +66,7 @@ pub async fn run_push( | |||
| 66 | 66 | ||
| 67 | let list_outputs = match list_outputs { | 67 | let list_outputs = match list_outputs { |
| 68 | Some(outputs) => outputs, | 68 | Some(outputs) => outputs, |
| 69 | _ => list_from_remotes(&term, git_repo, &repo_ref.git_server)?, | 69 | _ => list_from_remotes(&term, git_repo, &repo_ref.git_server, decoded_nostr_url), |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | let nostr_state = get_state_from_cache(git_repo.get_path()?, repo_ref).await; | 72 | let nostr_state = get_state_from_cache(git_repo.get_path()?, repo_ref).await; |
| @@ -154,7 +154,7 @@ pub async fn run_push( | |||
| 154 | &term, | 154 | &term, |
| 155 | repo_ref, | 155 | repo_ref, |
| 156 | git_repo, | 156 | git_repo, |
| 157 | nostr_remote_url, | 157 | &decoded_nostr_url.original_string, |
| 158 | &signer, | 158 | &signer, |
| 159 | &git_server_refspecs, | 159 | &git_server_refspecs, |
| 160 | ) | 160 | ) |
| @@ -306,8 +306,12 @@ pub async fn run_push( | |||
| 306 | } | 306 | } |
| 307 | let (_, to) = refspec_to_from_to(refspec)?; | 307 | let (_, to) = refspec_to_from_to(refspec)?; |
| 308 | println!("ok {to}"); | 308 | println!("ok {to}"); |
| 309 | update_remote_refs_pushed(&git_repo.git_repo, refspec, nostr_remote_url) | 309 | update_remote_refs_pushed( |
| 310 | .context("could not update remote_ref locally")?; | 310 | &git_repo.git_repo, |
| 311 | refspec, | ||
| 312 | &decoded_nostr_url.original_string, | ||
| 313 | ) | ||
| 314 | .context("could not update remote_ref locally")?; | ||
| 311 | } | 315 | } |
| 312 | 316 | ||
| 313 | // TODO make async - check gitlib2 callbacks work async | 317 | // TODO make async - check gitlib2 callbacks work async |
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index ea8d221..2717916 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs | |||
| @@ -36,6 +36,7 @@ impl fmt::Display for ServerProtocol { | |||
| 36 | 36 | ||
| 37 | #[derive(Debug, PartialEq)] | 37 | #[derive(Debug, PartialEq)] |
| 38 | pub struct NostrUrlDecoded { | 38 | pub struct NostrUrlDecoded { |
| 39 | pub original_string: String, | ||
| 39 | pub coordinates: HashSet<Coordinate>, | 40 | pub coordinates: HashSet<Coordinate>, |
| 40 | pub protocol: Option<ServerProtocol>, | 41 | pub protocol: Option<ServerProtocol>, |
| 41 | pub user: Option<String>, | 42 | pub user: Option<String>, |
| @@ -145,6 +146,7 @@ impl std::str::FromStr for NostrUrlDecoded { | |||
| 145 | } | 146 | } |
| 146 | 147 | ||
| 147 | Ok(Self { | 148 | Ok(Self { |
| 149 | original_string: url.to_string(), | ||
| 148 | coordinates, | 150 | coordinates, |
| 149 | protocol, | 151 | protocol, |
| 150 | user, | 152 | user, |
| @@ -831,11 +833,11 @@ mod tests { | |||
| 831 | 833 | ||
| 832 | #[test] | 834 | #[test] |
| 833 | fn from_naddr() -> Result<()> { | 835 | fn from_naddr() -> Result<()> { |
| 836 | let url = "nostr://naddr1qqzxuemfwsqs6amnwvaz7tmwdaejumr0dspzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqvzqqqrhnym0k2qj".to_string(); | ||
| 834 | assert_eq!( | 837 | assert_eq!( |
| 835 | NostrUrlDecoded::from_str( | 838 | NostrUrlDecoded::from_str(&url)?, |
| 836 | "nostr://naddr1qqzxuemfwsqs6amnwvaz7tmwdaejumr0dspzpgqgmmc409hm4xsdd74sf68a2uyf9pwel4g9mfdg8l5244t6x4jdqvzqqqrhnym0k2qj" | ||
| 837 | )?, | ||
| 838 | NostrUrlDecoded { | 839 | NostrUrlDecoded { |
| 840 | original_string: url.clone(), | ||
| 839 | coordinates: HashSet::from([Coordinate { | 841 | coordinates: HashSet::from([Coordinate { |
| 840 | identifier: "ngit".to_string(), | 842 | identifier: "ngit".to_string(), |
| 841 | public_key: PublicKey::parse( | 843 | public_key: PublicKey::parse( |
| @@ -851,16 +853,19 @@ mod tests { | |||
| 851 | ); | 853 | ); |
| 852 | Ok(()) | 854 | Ok(()) |
| 853 | } | 855 | } |
| 856 | |||
| 854 | mod from_npub_slash_identifier { | 857 | mod from_npub_slash_identifier { |
| 855 | use super::*; | 858 | use super::*; |
| 856 | 859 | ||
| 857 | #[test] | 860 | #[test] |
| 858 | fn without_relay() -> Result<()> { | 861 | fn without_relay() -> Result<()> { |
| 862 | let url = | ||
| 863 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit" | ||
| 864 | .to_string(); | ||
| 859 | assert_eq!( | 865 | assert_eq!( |
| 860 | NostrUrlDecoded::from_str( | 866 | NostrUrlDecoded::from_str(&url)?, |
| 861 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit" | ||
| 862 | )?, | ||
| 863 | NostrUrlDecoded { | 867 | NostrUrlDecoded { |
| 868 | original_string: url.clone(), | ||
| 864 | coordinates: HashSet::from([get_model_coordinate(false)]), | 869 | coordinates: HashSet::from([get_model_coordinate(false)]), |
| 865 | protocol: None, | 870 | protocol: None, |
| 866 | user: None, | 871 | user: None, |
| @@ -870,16 +875,15 @@ mod tests { | |||
| 870 | } | 875 | } |
| 871 | 876 | ||
| 872 | mod with_url_parameters { | 877 | mod with_url_parameters { |
| 873 | |||
| 874 | use super::*; | 878 | use super::*; |
| 875 | 879 | ||
| 876 | #[test] | 880 | #[test] |
| 877 | fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { | 881 | fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { |
| 882 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay=nos.lol".to_string(); | ||
| 878 | assert_eq!( | 883 | assert_eq!( |
| 879 | NostrUrlDecoded::from_str( | 884 | NostrUrlDecoded::from_str(&url)?, |
| 880 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay=nos.lol" | ||
| 881 | )?, | ||
| 882 | NostrUrlDecoded { | 885 | NostrUrlDecoded { |
| 886 | original_string: url.clone(), | ||
| 883 | coordinates: HashSet::from([get_model_coordinate(true)]), | 887 | coordinates: HashSet::from([get_model_coordinate(true)]), |
| 884 | protocol: None, | 888 | protocol: None, |
| 885 | user: None, | 889 | user: None, |
| @@ -890,12 +894,14 @@ mod tests { | |||
| 890 | 894 | ||
| 891 | #[test] | 895 | #[test] |
| 892 | fn with_encoded_relay() -> Result<()> { | 896 | fn with_encoded_relay() -> Result<()> { |
| 897 | let url = format!( | ||
| 898 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}", | ||
| 899 | urlencoding::encode("wss://nos.lol") | ||
| 900 | ); | ||
| 893 | assert_eq!( | 901 | assert_eq!( |
| 894 | NostrUrlDecoded::from_str(&format!( | 902 | NostrUrlDecoded::from_str(&url)?, |
| 895 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}", | ||
| 896 | urlencoding::encode("wss://nos.lol") | ||
| 897 | ))?, | ||
| 898 | NostrUrlDecoded { | 903 | NostrUrlDecoded { |
| 904 | original_string: url.clone(), | ||
| 899 | coordinates: HashSet::from([get_model_coordinate(true)]), | 905 | coordinates: HashSet::from([get_model_coordinate(true)]), |
| 900 | protocol: None, | 906 | protocol: None, |
| 901 | user: None, | 907 | user: None, |
| @@ -903,41 +909,44 @@ mod tests { | |||
| 903 | ); | 909 | ); |
| 904 | Ok(()) | 910 | Ok(()) |
| 905 | } | 911 | } |
| 912 | |||
| 906 | #[test] | 913 | #[test] |
| 907 | fn with_multiple_encoded_relays() -> Result<()> { | 914 | fn with_multiple_encoded_relays() -> Result<()> { |
| 908 | assert_eq!( | 915 | let url = format!( |
| 909 | NostrUrlDecoded::from_str(&format!( | 916 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}&relay1={}", |
| 910 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?relay={}&relay1={}", | 917 | urlencoding::encode("wss://nos.lol"), |
| 911 | urlencoding::encode("wss://nos.lol"), | 918 | urlencoding::encode("wss://relay.damus.io"), |
| 912 | urlencoding::encode("wss://relay.damus.io"), | ||
| 913 | ))?, | ||
| 914 | NostrUrlDecoded { | ||
| 915 | coordinates: HashSet::from([Coordinate { | ||
| 916 | identifier: "ngit".to_string(), | ||
| 917 | public_key: PublicKey::parse( | ||
| 918 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 919 | ) | ||
| 920 | .unwrap(), | ||
| 921 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 922 | relays: vec![ | ||
| 923 | "wss://nos.lol/".to_string(), | ||
| 924 | "wss://relay.damus.io/".to_string(), | ||
| 925 | ], | ||
| 926 | }]), | ||
| 927 | protocol: None, | ||
| 928 | user: None, | ||
| 929 | }, | ||
| 930 | ); | 919 | ); |
| 920 | assert_eq!( | ||
| 921 | NostrUrlDecoded::from_str(&url)?, | ||
| 922 | NostrUrlDecoded { | ||
| 923 | original_string: url.clone(), | ||
| 924 | coordinates: HashSet::from([Coordinate { | ||
| 925 | identifier: "ngit".to_string(), | ||
| 926 | public_key: PublicKey::parse( | ||
| 927 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 928 | ) | ||
| 929 | .unwrap(), | ||
| 930 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 931 | relays: vec![ | ||
| 932 | "wss://nos.lol/".to_string(), | ||
| 933 | "wss://relay.damus.io/".to_string(), | ||
| 934 | ], | ||
| 935 | }]), | ||
| 936 | protocol: None, | ||
| 937 | user: None, | ||
| 938 | }, | ||
| 939 | ); | ||
| 931 | Ok(()) | 940 | Ok(()) |
| 932 | } | 941 | } |
| 933 | 942 | ||
| 934 | #[test] | 943 | #[test] |
| 935 | fn with_server_protocol() -> Result<()> { | 944 | fn with_server_protocol() -> Result<()> { |
| 945 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh".to_string(); | ||
| 936 | assert_eq!( | 946 | assert_eq!( |
| 937 | NostrUrlDecoded::from_str( | 947 | NostrUrlDecoded::from_str(&url)?, |
| 938 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh" | ||
| 939 | )?, | ||
| 940 | NostrUrlDecoded { | 948 | NostrUrlDecoded { |
| 949 | original_string: url.clone(), | ||
| 941 | coordinates: HashSet::from([get_model_coordinate(false)]), | 950 | coordinates: HashSet::from([get_model_coordinate(false)]), |
| 942 | protocol: Some(ServerProtocol::Ssh), | 951 | protocol: Some(ServerProtocol::Ssh), |
| 943 | user: None, | 952 | user: None, |
| @@ -945,13 +954,14 @@ mod tests { | |||
| 945 | ); | 954 | ); |
| 946 | Ok(()) | 955 | Ok(()) |
| 947 | } | 956 | } |
| 957 | |||
| 948 | #[test] | 958 | #[test] |
| 949 | fn with_server_protocol_and_user() -> Result<()> { | 959 | fn with_server_protocol_and_user() -> Result<()> { |
| 960 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh&user=fred".to_string(); | ||
| 950 | assert_eq!( | 961 | assert_eq!( |
| 951 | NostrUrlDecoded::from_str( | 962 | NostrUrlDecoded::from_str(&url)?, |
| 952 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit?protocol=ssh&user=fred" | ||
| 953 | )?, | ||
| 954 | NostrUrlDecoded { | 963 | NostrUrlDecoded { |
| 964 | original_string: url.clone(), | ||
| 955 | coordinates: HashSet::from([get_model_coordinate(false)]), | 965 | coordinates: HashSet::from([get_model_coordinate(false)]), |
| 956 | protocol: Some(ServerProtocol::Ssh), | 966 | protocol: Some(ServerProtocol::Ssh), |
| 957 | user: Some("fred".to_string()), | 967 | user: Some("fred".to_string()), |
| @@ -960,16 +970,17 @@ mod tests { | |||
| 960 | Ok(()) | 970 | Ok(()) |
| 961 | } | 971 | } |
| 962 | } | 972 | } |
| 973 | |||
| 963 | mod with_parameters_embedded_with_slashes { | 974 | mod with_parameters_embedded_with_slashes { |
| 964 | use super::*; | 975 | use super::*; |
| 965 | 976 | ||
| 966 | #[test] | 977 | #[test] |
| 967 | fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { | 978 | fn with_relay_without_scheme_defaults_to_wss() -> Result<()> { |
| 979 | let url = "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit".to_string(); | ||
| 968 | assert_eq!( | 980 | assert_eq!( |
| 969 | NostrUrlDecoded::from_str( | 981 | NostrUrlDecoded::from_str(&url)?, |
| 970 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/nos.lol/ngit" | ||
| 971 | )?, | ||
| 972 | NostrUrlDecoded { | 982 | NostrUrlDecoded { |
| 983 | original_string: url.clone(), | ||
| 973 | coordinates: HashSet::from([get_model_coordinate(true)]), | 984 | coordinates: HashSet::from([get_model_coordinate(true)]), |
| 974 | protocol: None, | 985 | protocol: None, |
| 975 | user: None, | 986 | user: None, |
| @@ -980,12 +991,14 @@ mod tests { | |||
| 980 | 991 | ||
| 981 | #[test] | 992 | #[test] |
| 982 | fn with_encoded_relay() -> Result<()> { | 993 | fn with_encoded_relay() -> Result<()> { |
| 994 | let url = format!( | ||
| 995 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/ngit", | ||
| 996 | urlencoding::encode("wss://nos.lol") | ||
| 997 | ); | ||
| 983 | assert_eq!( | 998 | assert_eq!( |
| 984 | NostrUrlDecoded::from_str(&format!( | 999 | NostrUrlDecoded::from_str(&url)?, |
| 985 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/ngit", | ||
| 986 | urlencoding::encode("wss://nos.lol") | ||
| 987 | ))?, | ||
| 988 | NostrUrlDecoded { | 1000 | NostrUrlDecoded { |
| 1001 | original_string: url.clone(), | ||
| 989 | coordinates: HashSet::from([get_model_coordinate(true)]), | 1002 | coordinates: HashSet::from([get_model_coordinate(true)]), |
| 990 | protocol: None, | 1003 | protocol: None, |
| 991 | user: None, | 1004 | user: None, |
| @@ -993,41 +1006,44 @@ mod tests { | |||
| 993 | ); | 1006 | ); |
| 994 | Ok(()) | 1007 | Ok(()) |
| 995 | } | 1008 | } |
| 1009 | |||
| 996 | #[test] | 1010 | #[test] |
| 997 | fn with_multiple_encoded_relays() -> Result<()> { | 1011 | fn with_multiple_encoded_relays() -> Result<()> { |
| 998 | assert_eq!( | 1012 | let url = format!( |
| 999 | NostrUrlDecoded::from_str(&format!( | 1013 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/{}/ngit", |
| 1000 | "nostr://npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/{}/{}/ngit", | 1014 | urlencoding::encode("wss://nos.lol"), |
| 1001 | urlencoding::encode("wss://nos.lol"), | 1015 | urlencoding::encode("wss://relay.damus.io"), |
| 1002 | urlencoding::encode("wss://relay.damus.io"), | ||
| 1003 | ))?, | ||
| 1004 | NostrUrlDecoded { | ||
| 1005 | coordinates: HashSet::from([Coordinate { | ||
| 1006 | identifier: "ngit".to_string(), | ||
| 1007 | public_key: PublicKey::parse( | ||
| 1008 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 1009 | ) | ||
| 1010 | .unwrap(), | ||
| 1011 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1012 | relays: vec![ | ||
| 1013 | "wss://nos.lol/".to_string(), | ||
| 1014 | "wss://relay.damus.io/".to_string(), | ||
| 1015 | ], | ||
| 1016 | }]), | ||
| 1017 | protocol: None, | ||
| 1018 | user: None, | ||
| 1019 | }, | ||
| 1020 | ); | 1016 | ); |
| 1017 | assert_eq!( | ||
| 1018 | NostrUrlDecoded::from_str(&url)?, | ||
| 1019 | NostrUrlDecoded { | ||
| 1020 | original_string: url.clone(), | ||
| 1021 | coordinates: HashSet::from([Coordinate { | ||
| 1022 | identifier: "ngit".to_string(), | ||
| 1023 | public_key: PublicKey::parse( | ||
| 1024 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | ||
| 1025 | ) | ||
| 1026 | .unwrap(), | ||
| 1027 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1028 | relays: vec![ | ||
| 1029 | "wss://nos.lol/".to_string(), | ||
| 1030 | "wss://relay.damus.io/".to_string(), | ||
| 1031 | ], | ||
| 1032 | }]), | ||
| 1033 | protocol: None, | ||
| 1034 | user: None, | ||
| 1035 | }, | ||
| 1036 | ); | ||
| 1021 | Ok(()) | 1037 | Ok(()) |
| 1022 | } | 1038 | } |
| 1023 | 1039 | ||
| 1024 | #[test] | 1040 | #[test] |
| 1025 | fn with_server_protocol() -> Result<()> { | 1041 | fn with_server_protocol() -> Result<()> { |
| 1042 | let url = "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | ||
| 1026 | assert_eq!( | 1043 | assert_eq!( |
| 1027 | NostrUrlDecoded::from_str( | 1044 | NostrUrlDecoded::from_str(&url)?, |
| 1028 | "nostr://ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit" | ||
| 1029 | )?, | ||
| 1030 | NostrUrlDecoded { | 1045 | NostrUrlDecoded { |
| 1046 | original_string: url.clone(), | ||
| 1031 | coordinates: HashSet::from([get_model_coordinate(false)]), | 1047 | coordinates: HashSet::from([get_model_coordinate(false)]), |
| 1032 | protocol: Some(ServerProtocol::Ssh), | 1048 | protocol: Some(ServerProtocol::Ssh), |
| 1033 | user: None, | 1049 | user: None, |
| @@ -1035,13 +1051,14 @@ mod tests { | |||
| 1035 | ); | 1051 | ); |
| 1036 | Ok(()) | 1052 | Ok(()) |
| 1037 | } | 1053 | } |
| 1054 | |||
| 1038 | #[test] | 1055 | #[test] |
| 1039 | fn with_server_protocol_and_user() -> Result<()> { | 1056 | fn with_server_protocol_and_user() -> Result<()> { |
| 1057 | let url = "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit".to_string(); | ||
| 1040 | assert_eq!( | 1058 | assert_eq!( |
| 1041 | NostrUrlDecoded::from_str( | 1059 | NostrUrlDecoded::from_str(&url)?, |
| 1042 | "nostr://fred@ssh/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit" | ||
| 1043 | )?, | ||
| 1044 | NostrUrlDecoded { | 1060 | NostrUrlDecoded { |
| 1061 | original_string: url.clone(), | ||
| 1045 | coordinates: HashSet::from([get_model_coordinate(false)]), | 1062 | coordinates: HashSet::from([get_model_coordinate(false)]), |
| 1046 | protocol: Some(ServerProtocol::Ssh), | 1063 | protocol: Some(ServerProtocol::Ssh), |
| 1047 | user: Some("fred".to_string()), | 1064 | user: Some("fred".to_string()), |