refactor: Support more than one naddr instead of one
This commit supports multiple naddrs for sending issues to and searching for repositories by extracting the embedded relays, and appending to the address file instead of overwriting its previous contents. A header has also been added to the `nostr-address` file to clarify its purpose. This enhancement accommodates maintainers who distribute issue tracking across multiple repositories, preventing confusion if the primary maintainer steps down. Now, issues and patches will reference all relevant repositories, not just one. Note that repositories won't automatically include all maintainers' addresses unless explicitly specified. Maintainers may manage a repository under a project-specific public key rather than individual keys. Addresses are only added to issues and patches when explicitly provided via the command or written to the address file. This prevents unintended inclusions and ensures clarity. Suggested-by: DanConwayDev <DanConwayDev@protonmail.com> Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/gpl-3.0.html>.
|
||||
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use nostr::{
|
||||
Kind,
|
||||
nips::{
|
||||
@@ -24,6 +26,8 @@ use nostr::{
|
||||
};
|
||||
use tokio::runtime::Handle;
|
||||
|
||||
use crate::error::{N34Error, N34Result};
|
||||
|
||||
fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<Nip19Coordinate, String> {
|
||||
let (username, domain) = nip5.split_once("@").unwrap_or(("_", nip5));
|
||||
|
||||
@@ -42,6 +46,34 @@ fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<Nip19Coordinate, String>
|
||||
.expect("The relays is `RelayUrl`"))
|
||||
}
|
||||
|
||||
fn parse_repo_naddr(repo_naddr: &str) -> Result<Nip19Coordinate, String> {
|
||||
let naddr = Nip19Coordinate::from_bech32(repo_naddr).map_err(|err| err.to_string())?;
|
||||
if naddr.relays.is_empty() {
|
||||
tracing::warn!("The repository naddr does not contain any relay hints");
|
||||
}
|
||||
|
||||
(naddr.kind == Kind::GitRepoAnnouncement)
|
||||
.then_some(naddr)
|
||||
.ok_or_else(|| "Invalid naddr: must be of kind 30617 (GitRepoAnnouncement)".to_owned())
|
||||
}
|
||||
|
||||
/// Parses a nostr-address file into a NIP-19 coordinates. Expects the file to
|
||||
/// contain a repository announcements.
|
||||
pub fn parse_nostr_address_file(file_path: &Path) -> N34Result<Vec<Nip19Coordinate>> {
|
||||
let addresses = fs::read_to_string(file_path)
|
||||
.map_err(N34Error::CanNotReadNostrAddressFile)?
|
||||
.split("\n")
|
||||
.filter_map(|line| {
|
||||
(!line.starts_with("#") && !line.trim().is_empty())
|
||||
.then_some(parse_repo_naddr(line).map_err(N34Error::InvalidNostrAddressFileContent))
|
||||
})
|
||||
.collect::<N34Result<Vec<Nip19Coordinate>>>()?;
|
||||
if addresses.is_empty() {
|
||||
return Err(N34Error::EmptyNostrAddressFile);
|
||||
}
|
||||
Ok(addresses)
|
||||
}
|
||||
|
||||
/// Parses a Git repository address which can be either:
|
||||
/// - A bech32-encoded naddr (e.g. "naddr1...") for Git repository announcements
|
||||
/// (kind 30617)
|
||||
@@ -50,20 +82,19 @@ fn parse_nip5_repo(nip5: &str, repo_id: &str) -> Result<Nip19Coordinate, String>
|
||||
///
|
||||
/// Returns an error for invalid formats, failed bech32 decoding, wrong event
|
||||
/// kind.
|
||||
pub fn repo_naddr(repo_address: &str) -> Result<Nip19Coordinate, String> {
|
||||
if repo_address.contains("/") {
|
||||
let (nip5, repo_id) = repo_address.split_once("/").expect("There is a `/`");
|
||||
return parse_nip5_repo(nip5, repo_id);
|
||||
}
|
||||
pub fn repo_naddr(repo: &str) -> Result<Nip19Coordinate, String> {
|
||||
let repo = repo.trim();
|
||||
|
||||
let naddr = Nip19Coordinate::from_bech32(repo_address).map_err(|err| err.to_string())?;
|
||||
if naddr.kind != Kind::GitRepoAnnouncement {
|
||||
return Err("The naddr is not repo announcement address".to_owned());
|
||||
if repo.contains("/") {
|
||||
let (nip5, repo_id) = repo.split_once("/").expect("There is a `/`");
|
||||
parse_nip5_repo(nip5, repo_id)
|
||||
} else if repo.starts_with("naddr1") {
|
||||
parse_repo_naddr(repo)
|
||||
} else {
|
||||
Err(
|
||||
"Invalid repository address format. It can be A NIP-05 identifier with repository ID \
|
||||
in format `<nip5>/<repo_id>` or A valid naddr1 string (NIP-19)"
|
||||
.to_owned(),
|
||||
)
|
||||
}
|
||||
|
||||
if naddr.relays.is_empty() {
|
||||
tracing::warn!("The repository naddr does not contain any relay hints");
|
||||
}
|
||||
|
||||
Ok(naddr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user