diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-08-19 08:47:53 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-08-19 08:47:53 +0100 |
| commit | 4291428c714b8cc7b7a5f3c1a1504b0098e00455 (patch) | |
| tree | 537d200bcc06c835fd02231f811ede743cb00241 /src/git.rs | |
| parent | 6b46ad9809b42d355c883ff2c75f8ac75d4bd989 (diff) | |
refactor(remote): move url_to_repo_coordinates
so it can be used by repo_ref which doesnt import git_remote_helper
Diffstat (limited to 'src/git.rs')
| -rw-r--r-- | src/git.rs | 58 |
1 files changed, 57 insertions, 1 deletions
| @@ -1,11 +1,16 @@ | |||
| 1 | use std::{ | 1 | use std::{ |
| 2 | collections::HashSet, | ||
| 2 | env::current_dir, | 3 | env::current_dir, |
| 3 | path::{Path, PathBuf}, | 4 | path::{Path, PathBuf}, |
| 4 | }; | 5 | }; |
| 5 | 6 | ||
| 6 | use anyhow::{bail, Context, Result}; | 7 | use anyhow::{bail, Context, Result}; |
| 7 | use git2::{DiffOptions, Oid, Revwalk}; | 8 | use git2::{DiffOptions, Oid, Revwalk}; |
| 8 | use nostr_sdk::hashes::{sha1::Hash as Sha1Hash, Hash}; | 9 | use nostr::nips::nip01::Coordinate; |
| 10 | use nostr_sdk::{ | ||
| 11 | hashes::{sha1::Hash as Sha1Hash, Hash}, | ||
| 12 | PublicKey, Url, | ||
| 13 | }; | ||
| 9 | 14 | ||
| 10 | use crate::sub_commands::list::{get_commit_id_from_patch, tag_value}; | 15 | use crate::sub_commands::list::{get_commit_id_from_patch, tag_value}; |
| 11 | 16 | ||
| @@ -830,6 +835,57 @@ fn extract_sig_from_patch_tags<'a>( | |||
| 830 | .context("failed to create git signature") | 835 | .context("failed to create git signature") |
| 831 | } | 836 | } |
| 832 | 837 | ||
| 838 | pub fn nostr_git_url_to_repo_coordinates(url: &str) -> Result<HashSet<Coordinate>> { | ||
| 839 | let mut repo_coordinattes = HashSet::new(); | ||
| 840 | let url = Url::parse(url)?; | ||
| 841 | |||
| 842 | if url.scheme().ne("nostr") { | ||
| 843 | bail!("nostr git url must start with nostr://") | ||
| 844 | } | ||
| 845 | |||
| 846 | if let Ok(coordinate) = Coordinate::parse(url.domain().context("no naddr")?) { | ||
| 847 | if coordinate.kind.eq(&nostr_sdk::Kind::GitRepoAnnouncement) { | ||
| 848 | repo_coordinattes.insert(coordinate); | ||
| 849 | return Ok(repo_coordinattes); | ||
| 850 | } | ||
| 851 | bail!("naddr doesnt point to a git repository announcement"); | ||
| 852 | } | ||
| 853 | |||
| 854 | if let Some(domain) = url.domain() { | ||
| 855 | if let Ok(public_key) = PublicKey::parse(domain) { | ||
| 856 | if url.path().len() < 2 { | ||
| 857 | bail!( | ||
| 858 | "nostr git url should include the repo identifier eg nostr://npub123/the-repo-identifer" | ||
| 859 | ); | ||
| 860 | } | ||
| 861 | let mut relays = vec![]; | ||
| 862 | for (name, value) in url.query_pairs() { | ||
| 863 | if name.contains("relay") { | ||
| 864 | let mut decoded = urlencoding::decode(&value) | ||
| 865 | .context("could not parse relays in nostr git url")? | ||
| 866 | .to_string(); | ||
| 867 | if !decoded.starts_with("ws://") && !decoded.starts_with("wss://") { | ||
| 868 | decoded = format!("wss://{decoded}"); | ||
| 869 | } | ||
| 870 | let url = | ||
| 871 | Url::parse(&decoded).context("could not parse relays in nostr git url")?; | ||
| 872 | relays.push(url.to_string()); | ||
| 873 | } | ||
| 874 | } | ||
| 875 | repo_coordinattes.insert(Coordinate { | ||
| 876 | identifier: url.path()[1..].to_string(), | ||
| 877 | public_key, | ||
| 878 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 879 | relays, | ||
| 880 | }); | ||
| 881 | return Ok(repo_coordinattes); | ||
| 882 | } | ||
| 883 | } | ||
| 884 | bail!( | ||
| 885 | "nostr git url must be in format nostr://naddr123 or nostr://npub123/identifer?relay=wss://relay-example.com&relay1=wss://relay-example.org" | ||
| 886 | ); | ||
| 887 | } | ||
| 888 | |||
| 833 | #[cfg(test)] | 889 | #[cfg(test)] |
| 834 | mod tests { | 890 | mod tests { |
| 835 | use std::fs; | 891 | use std::fs; |