reorganize signed_core into method-based APIs
This commit is contained in:
@@ -9,7 +9,8 @@ use nostr::event::IntoEventBuilder;
|
||||
use nostr_sdk::prelude::*;
|
||||
use settings::{EventFetchingStrategy, SettingsStore};
|
||||
use signed_core::{
|
||||
Announcement, Deletions, RepoAddr, RepoStatus, filters, parse_state, pull_request_patches,
|
||||
Announcement, Deletions, Filters, GitEvent, PullRequest, RepoAddr, RepoState, RepoStatus,
|
||||
filters,
|
||||
};
|
||||
use signed_git::Nip34Binding;
|
||||
use signed_nostr::UniversalSigner;
|
||||
@@ -210,8 +211,8 @@ impl RepoStore {
|
||||
let deletion =
|
||||
update.kind == Kind::EventDeletion || update.kind == Kind::RequestToVanish;
|
||||
|
||||
let coordinate = update.coordinate.as_ref() == Some(addr);
|
||||
let author = update.author == addr.public_key;
|
||||
let coordinate = update.coordinate.as_ref() == Some(addr.coordinate());
|
||||
let author = update.author == addr.public_key();
|
||||
|
||||
let authored = (update.kind == Kind::GitRepoAnnouncement
|
||||
|| update.kind == Kind::RepoState)
|
||||
@@ -251,12 +252,12 @@ impl RepoStore {
|
||||
let mut filters = vec![
|
||||
Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.author(addr.public_key)
|
||||
.identifier(addr.identifier.clone()),
|
||||
filters::activity(addr),
|
||||
.author(addr.public_key())
|
||||
.identifier(addr.identifier()),
|
||||
addr.activity_filter(),
|
||||
];
|
||||
// Deletion requests, NIP-09/62, must be known before any event is shown.
|
||||
filters.extend(filters::deletions_for_repo(addr));
|
||||
filters.extend(addr.deletion_filters());
|
||||
filters
|
||||
}
|
||||
|
||||
@@ -290,8 +291,8 @@ impl RepoStore {
|
||||
let mut pubkeys = maintainers.to_vec();
|
||||
// NIP-34 events tag the announcement author,
|
||||
// which may not be a maintainer for subordinate forks.
|
||||
if !pubkeys.contains(&addr.public_key) {
|
||||
pubkeys.push(addr.public_key);
|
||||
if !pubkeys.contains(&addr.public_key()) {
|
||||
pubkeys.push(addr.public_key());
|
||||
}
|
||||
|
||||
vec![
|
||||
@@ -299,16 +300,16 @@ impl RepoStore {
|
||||
Filter::new()
|
||||
.kinds([Kind::GitRepoAnnouncement, Kind::RepoState])
|
||||
.authors(pubkeys.clone())
|
||||
.identifier(addr.identifier.clone()),
|
||||
.identifier(addr.identifier()),
|
||||
// Activity tagging a maintainer, resolved to their read relays.
|
||||
Filter::new()
|
||||
.kinds(filters::ACTIVITY_KINDS)
|
||||
.coordinate(addr)
|
||||
.coordinate(addr.coordinate())
|
||||
.pubkeys(pubkeys.clone()),
|
||||
// Activity authored by a maintainer, resolved to their write relays.
|
||||
Filter::new()
|
||||
.kinds(filters::ACTIVITY_KINDS)
|
||||
.coordinate(addr)
|
||||
.coordinate(addr.coordinate())
|
||||
.authors(pubkeys.clone()),
|
||||
// Deletions authored by a maintainer.
|
||||
Filter::new()
|
||||
@@ -377,10 +378,10 @@ impl RepoStore {
|
||||
let work = cx.background_spawn(async move {
|
||||
let (announcements, states, activity, deletion_events) = async {
|
||||
let db = client.database();
|
||||
let announcements = db.query(filters::announcement(&addr)).await?;
|
||||
let states = db.query(filters::state(&addr)).await?;
|
||||
let activity = db.query(filters::activity(&addr)).await?;
|
||||
let deletion_events = db.query(filters::deletions()).await?;
|
||||
let announcements = db.query(addr.announcement_filter()).await?;
|
||||
let states = db.query(addr.state_filter()).await?;
|
||||
let activity = db.query(addr.activity_filter()).await?;
|
||||
let deletion_events = db.query(Filters::deletions()).await?;
|
||||
|
||||
Ok::<_, Error>((announcements, states, activity, deletion_events))
|
||||
}
|
||||
@@ -397,7 +398,7 @@ impl RepoStore {
|
||||
.and_then(Announcement::from_event);
|
||||
|
||||
let all_states = states.into_iter().filter(|e| !deletions.is_deleted(e));
|
||||
let state = utils::latest(all_states).map(|state| parse_state(&state));
|
||||
let state = utils::latest(all_states).map(|state| RepoState::parse(&state));
|
||||
|
||||
let (mut issues, mut patches, mut pull_requests, mut statuses, mut comments) =
|
||||
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
|
||||
@@ -425,7 +426,7 @@ impl RepoStore {
|
||||
.chain(&pull_requests)
|
||||
.map(|e| e.id);
|
||||
|
||||
for filter in filters::comments_for(roots) {
|
||||
for filter in Filters::comments_for(roots) {
|
||||
for event in db.query(filter).await? {
|
||||
if seen_comments.insert(event.id) {
|
||||
comments.push(event);
|
||||
@@ -443,7 +444,7 @@ impl RepoStore {
|
||||
.map(|e| e.id);
|
||||
|
||||
for root in roots {
|
||||
for event in db.query(filters::statuses_for([root])).await? {
|
||||
for event in db.query(Filters::statuses_for([root])).await? {
|
||||
if seen_statuses.insert(event.id) {
|
||||
statuses.push(event);
|
||||
}
|
||||
@@ -516,7 +517,7 @@ impl RepoStore {
|
||||
|
||||
let head_changed = state
|
||||
.as_ref()
|
||||
.is_some_and(|(_, head)| this.head.as_deref() != head.as_deref());
|
||||
.is_some_and(|state| this.head.as_deref() != state.head.as_deref());
|
||||
|
||||
let changed = first_pass
|
||||
|| (!keep_hint && this.announcement != announcement)
|
||||
@@ -549,8 +550,8 @@ impl RepoStore {
|
||||
|
||||
this.sync_maintainer_relays(&maintainers, cx);
|
||||
|
||||
if let Some((_, head)) = state {
|
||||
this.head = head;
|
||||
if let Some(state) = state {
|
||||
this.head = state.head;
|
||||
}
|
||||
|
||||
this.issues = issues;
|
||||
@@ -579,8 +580,8 @@ impl RepoStore {
|
||||
if !new_roots.is_empty() {
|
||||
this.root_fetches.extend(new_roots.iter().copied());
|
||||
|
||||
let mut root_filters = filters::comments_for(new_roots.clone());
|
||||
root_filters.push(filters::statuses_for(new_roots.iter().copied()));
|
||||
let mut root_filters = Filters::comments_for(new_roots.clone());
|
||||
root_filters.push(Filters::statuses_for(new_roots.iter().copied()));
|
||||
|
||||
let announced: Vec<RelayUrl> = this.repo_relays.iter().cloned().collect();
|
||||
let backend = Backend::global(cx);
|
||||
@@ -621,7 +622,7 @@ impl RepoStore {
|
||||
pub fn is_author(&self, user: &PublicKey) -> bool {
|
||||
self.addr
|
||||
.as_ref()
|
||||
.is_some_and(|addr| &addr.public_key == user)
|
||||
.is_some_and(|addr| addr.public_key() == *user)
|
||||
}
|
||||
|
||||
pub fn open_issue(&mut self, subject: Option<String>, content: String, cx: &mut Context<Self>) {
|
||||
@@ -631,7 +632,7 @@ impl RepoStore {
|
||||
};
|
||||
|
||||
let builder = GitIssue {
|
||||
repository: addr,
|
||||
repository: addr.into(),
|
||||
content,
|
||||
subject,
|
||||
labels: Vec::new(),
|
||||
@@ -644,7 +645,7 @@ impl RepoStore {
|
||||
pub fn comments_of(&self, root: &EventId) -> impl Iterator<Item = &Event> {
|
||||
self.comments
|
||||
.iter()
|
||||
.filter(move |e| signed_core::references_root(e, root))
|
||||
.filter(move |e| e.references_root(root))
|
||||
}
|
||||
|
||||
/// Comment on a root event, an issue or PR, per NIP-34, kind 1111.
|
||||
@@ -745,9 +746,9 @@ impl RepoStore {
|
||||
// The author's npub names their GRASP-06 namespace, `/prs/...`.
|
||||
let author_npub = user.to_bech32().unwrap();
|
||||
|
||||
let owner = addr.public_key;
|
||||
let owner = addr.public_key();
|
||||
let euc = self.announcement.as_ref().and_then(|a| a.euc.clone());
|
||||
let repo_id = addr.identifier.clone();
|
||||
let repo_id = addr.identifier().to_owned();
|
||||
let base_npub = owner.to_bech32().unwrap();
|
||||
let push_relays = self
|
||||
.announcement
|
||||
@@ -857,7 +858,7 @@ impl RepoStore {
|
||||
let clone = pr_clone_urls(prs_urls, base_clone);
|
||||
|
||||
let builder = GitPullRequest {
|
||||
repository: addr.clone(),
|
||||
repository: addr.clone().into(),
|
||||
content: description,
|
||||
subject,
|
||||
labels: Vec::new(),
|
||||
@@ -1069,7 +1070,8 @@ impl RepoStore {
|
||||
// The first revision patch replies to the original root patch, NIP-34.
|
||||
// Use the PR's `e` tag, or the oldest patch of the linked set if the PR has none.
|
||||
let root_patch_id = root.tags.event_ids().next().or_else(|| {
|
||||
pull_request_patches(root, self.patches.iter())
|
||||
PullRequest::new(root)
|
||||
.patches(self.patches.iter())
|
||||
.first()
|
||||
.map(|p| p.id)
|
||||
});
|
||||
@@ -1079,7 +1081,7 @@ impl RepoStore {
|
||||
return;
|
||||
};
|
||||
|
||||
let owner = addr.public_key;
|
||||
let owner = addr.public_key();
|
||||
let euc = self.announcement.as_ref().and_then(|a| a.euc.clone());
|
||||
let root = root.clone();
|
||||
|
||||
@@ -1110,7 +1112,7 @@ impl RepoStore {
|
||||
|
||||
let builder = {
|
||||
let builder = GitPullRequestUpdate {
|
||||
repository: addr.clone(),
|
||||
repository: addr.clone().into(),
|
||||
pull_request_event: root.id,
|
||||
pull_request_author: root.pubkey,
|
||||
current_commit,
|
||||
@@ -1182,9 +1184,9 @@ impl RepoStore {
|
||||
|
||||
let builder = EventBuilder::new(status.kind(), "").tags([
|
||||
root_ref,
|
||||
Tag::public_key(addr.public_key),
|
||||
Tag::public_key(addr.public_key()),
|
||||
Tag::public_key(root.pubkey),
|
||||
Tag::coordinate(addr, None),
|
||||
Tag::coordinate(addr.clone().into(), None),
|
||||
]);
|
||||
|
||||
self.publish(builder, cx);
|
||||
@@ -1479,7 +1481,7 @@ fn resolve_statuses(
|
||||
.map(|root| {
|
||||
let events = by_root.get(&root.id).map(Vec::as_slice).unwrap_or(&[]);
|
||||
let status =
|
||||
signed_core::resolve_status(events.iter().copied(), &root.pubkey, maintainers);
|
||||
signed_core::RepoStatus::resolve(events.iter().copied(), &root.pubkey, maintainers);
|
||||
(root.id, status)
|
||||
})
|
||||
.collect()
|
||||
@@ -1518,7 +1520,10 @@ async fn publish_patch_series(
|
||||
));
|
||||
};
|
||||
|
||||
let mut tags = vec![Tag::coordinate(addr.clone(), None), Tag::public_key(owner)];
|
||||
let mut tags = vec![
|
||||
Tag::coordinate(addr.clone().into(), None),
|
||||
Tag::public_key(owner),
|
||||
];
|
||||
|
||||
if ix == 0 {
|
||||
if let Ok(tag) = Tag::parse(["t", first_marker]) {
|
||||
@@ -1586,11 +1591,13 @@ fn comment_builder(
|
||||
CommentBuilder::new(content, parent_target)
|
||||
.root(root_target)
|
||||
.into_event_builder()
|
||||
.tags([Tag::coordinate(addr.clone(), None)])
|
||||
.tags([Tag::coordinate(addr.clone().into(), None)])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use signed_core::GitEvent;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use nostr_sdk::prelude::*;
|
||||
@@ -1612,7 +1619,7 @@ mod tests {
|
||||
let root = EventBuilder::new(Kind::GitIssue, "issue body")
|
||||
.finalize(&keys)
|
||||
.expect("signed event");
|
||||
let addr = Coordinate::new(Kind::GitRepoAnnouncement, root.pubkey).identifier("my-repo");
|
||||
let addr = signed_core::RepoAddr::new(root.pubkey, "my-repo");
|
||||
let relay = RelayUrl::parse("wss://relay.example.com").expect("valid relay URL");
|
||||
|
||||
let event = comment_builder(&root, None, Some(&relay), &addr, "hi".into())
|
||||
@@ -1639,14 +1646,14 @@ mod tests {
|
||||
assert_eq!(e.as_slice()[1], root.id.to_hex());
|
||||
|
||||
// Signed's own `references_root` must keep matching the comment.
|
||||
assert!(signed_core::references_root(&event, &root.id));
|
||||
assert!(event.references_root(&root.id));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maintainer_filters_name_owner_and_maintainers() {
|
||||
let owner = Keys::generate().public_key();
|
||||
let maintainer = Keys::generate().public_key();
|
||||
let addr = Coordinate::new(Kind::GitRepoAnnouncement, owner).identifier("my-repo");
|
||||
let addr = signed_core::RepoAddr::new(owner, "my-repo");
|
||||
|
||||
// The owner is not among the maintainers, as on a subordinate fork.
|
||||
let filters = RepoStore::maintainer_filters(&addr, &[maintainer]);
|
||||
|
||||
Reference in New Issue
Block a user