ngit compatible
This commit is contained in:
@@ -20,7 +20,9 @@ pub use history::{
|
||||
CommitList, FileCommit, MAX_LISTED_COMMITS, all_commits, head_commit, worktree_all_commits,
|
||||
worktree_commit, worktree_commit_range_commits, worktree_last_commits,
|
||||
};
|
||||
pub use nip34::{GraspSignals, Nip34Binding, Nip34Kind, detect_nip34, is_grasp_url};
|
||||
pub use nip34::{
|
||||
GraspSignals, Nip34Binding, Nip34Kind, detect_nip34, is_grasp_url, set_nostr_repo,
|
||||
};
|
||||
pub use patch::{
|
||||
apply_patch, format_patch_between, patch_commits, patch_diffs, split_patch_series,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
use gix::bstr::ByteSlice;
|
||||
use nostr::prelude::*;
|
||||
|
||||
@@ -182,6 +183,16 @@ pub fn detect_nip34(repo_path: &Path) -> Option<Nip34Binding> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Record a repository's NIP-34 coordinate in its local `nostr.repo` config.
|
||||
pub fn set_nostr_repo(repo_path: &Path, naddr: &str) -> Result<()> {
|
||||
let repo = gix::open(repo_path)?;
|
||||
|
||||
crate::remote::edit_local_config(&repo, |config| {
|
||||
config.set_raw_value("nostr.repo", naddr)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Mirrors `nak`'s `IsGraspURL`: two path segments, a path of at least 65 bytes,
|
||||
/// and a first segment that decodes as an `npub`.
|
||||
pub fn is_grasp_url(url: &str) -> bool {
|
||||
@@ -360,6 +371,21 @@ mod tests {
|
||||
assert_eq!(binding.identifier.as_deref(), Some("my-repo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_written_nostr_repo_marker_is_detected() {
|
||||
let (_dir, path) = init_repo();
|
||||
let owner = key();
|
||||
let naddr = naddr(Kind::GitRepoAnnouncement, owner, "my-repo");
|
||||
|
||||
set_nostr_repo(&path, &naddr).expect("write marker");
|
||||
|
||||
let binding = detect_nip34(&path).expect("binding");
|
||||
assert_eq!(binding.kind, Nip34Kind::Initialized);
|
||||
assert!(binding.signals.nostr_repo_config);
|
||||
assert_eq!(binding.owner, Some(owner));
|
||||
assert_eq!(binding.identifier.as_deref(), Some("my-repo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nostr_remote_is_a_nip34_clone() {
|
||||
let (_dir, path) = init_repo();
|
||||
|
||||
@@ -252,10 +252,7 @@ pub fn set_origin(repo_path: &Path, url: &str) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Apply `edit` to the repository-local configuration and persist it.
|
||||
///
|
||||
/// The config file is locked while it is read, edited and written back,
|
||||
/// like git would when running `git config` or `git remote`.
|
||||
fn edit_local_config(
|
||||
pub(crate) fn edit_local_config(
|
||||
repo: &gix::Repository,
|
||||
edit: impl FnOnce(&mut gix::config::File) -> Result<()>,
|
||||
) -> Result<()> {
|
||||
|
||||
@@ -7,10 +7,11 @@ use anyhow::{Error, anyhow, bail};
|
||||
use bitcoin_hashes::sha1::Hash as Sha1Hash;
|
||||
use gpui::{App, AppContext, BackgroundExecutor, Context, Entity, EventEmitter, Global, Task};
|
||||
use nostr::event::IntoEventBuilder;
|
||||
use nostr::nips::nip19::Nip19Coordinate;
|
||||
use nostr_connect::prelude::*;
|
||||
use nostr_sdk::client::SyncSummary;
|
||||
use nostr_sdk::prelude::*;
|
||||
use signed_core::{Announcement, RepoAddr, build_state, filters, identifier_from_name};
|
||||
use signed_core::{Announcement, RepoAddr, build_state, filters, identifier_from_name, repo_addr};
|
||||
use signed_nostr::{SignedAuthUrlHandler, UniversalSigner, Update};
|
||||
|
||||
use crate::git_store::repo_mirror_path;
|
||||
@@ -743,6 +744,25 @@ impl Backend {
|
||||
.await;
|
||||
}
|
||||
|
||||
// Record the ngit-compatible `nostr.repo` marker,
|
||||
// so the next scan detects the repository instead of offering to publish it again.
|
||||
let coordinate = repo_addr(event.pubkey, repo_id.clone());
|
||||
match Nip19Coordinate::new(coordinate, servers.clone()).to_bech32() {
|
||||
Ok(naddr) => {
|
||||
let path = path.clone();
|
||||
cx.background_spawn(async move {
|
||||
if let Err(error) = signed_git::set_nostr_repo(&path, &naddr) {
|
||||
log::warn!(
|
||||
"failed to record the NIP-34 marker for {}: {error}",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
Err(error) => log::warn!("failed to encode the repository coordinate: {error}"),
|
||||
}
|
||||
|
||||
Announcement::from_event(&event).ok_or_else(|| anyhow!("failed to parse announcement"))
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user