From 0067804cc00e94ce2b7043e67f9ff50968525479 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sun, 21 May 2023 11:14:47 +0000 Subject: v0.0.1-alpha funcs --- src/funcs/find_latest_patch.rs | 137 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/funcs/find_latest_patch.rs (limited to 'src/funcs/find_latest_patch.rs') diff --git a/src/funcs/find_latest_patch.rs b/src/funcs/find_latest_patch.rs new file mode 100644 index 0000000..717d6c1 --- /dev/null +++ b/src/funcs/find_latest_patch.rs @@ -0,0 +1,137 @@ +use std::path::PathBuf; + +use nostr::{ Event }; + +use crate::{ngit_tag::{tag_is_branch, tag_extract_value, tag_is_commit}, branch_refs::BranchRefs, utils::load_event, kind::Kind}; + +/// finds latest patch that needs applying. It might not be the latest created_at date if an earlier patch was 'merged' more recently +pub fn find_latest_patch( + branch_id: &String, + patch_events:&Vec, + merges_into_branch: &Vec, + branch_refs:&BranchRefs, + repo_dir_path: &PathBuf, +) -> Option { + + // ensure only patch events make it into patch_events - we cant rely on relays for this + let patch_events:Vec = patch_events.iter().filter(|p| + // kind is patch + p.kind == nostr_sdk::Kind::Custom(u64::from(Kind::Patch)) + ).map(|p|p.clone()).collect(); + + let directly_authorised_patches: Vec = patch_events.iter().filter(|p| + // kind is patch + p.kind == nostr_sdk::Kind::Custom(u64::from(Kind::Patch)) + // on branch + && p.tags.iter().any( + |t|tag_is_branch(t) + && tag_extract_value(t) == branch_id.clone() + ) + // authorized + && match &branch_refs.is_authorized(Some(&branch_id), &p.pubkey) { + None => { false }, + Some(is_authorized) => { is_authorized.clone() } + } + ).map(|p|p.clone()).collect(); + + let latest_authorized_patch = find_latest_event(&directly_authorised_patches); + + let authorised_merges: Vec = merges_into_branch.iter().filter(|m| + // kind is merge + m.kind == nostr_sdk::Kind::Custom(u64::from(Kind::Merge)) + // into branch + && m.tags.iter().any( + |t|tag_is_branch(t) + && tag_extract_value(t) == branch_id.clone() + ) + // merge authorized + && match &branch_refs.is_authorized(Some(&branch_id), &m.pubkey) { + None => { false }, + Some(is_authorized) => { is_authorized.clone() } + } + ).map(|p|p.clone()).collect(); + + let latest_authorised_merge = find_latest_event(&authorised_merges); + + // find latest patch + + match latest_authorised_merge { + // no merge - return patch or None + None => latest_authorized_patch, + Some(m) => { + match latest_authorized_patch { + // merge but no patch, return the patch related to the merge + None => { + Some(get_merge_patch( + &m, + &patch_events, + repo_dir_path, + )) + }, + // a merge and a patch + Some(p) => { + // return the patch if it is later than merge + if m.created_at < p.created_at { + Some(p.clone()) + } + // return the patch related to the merge if the merge is later + else { + Some(get_merge_patch( + &m, + &patch_events, + repo_dir_path, + )) + } + } + } + } + } +} + +fn find_latest_event(events:&Vec) -> Option { + let mut latest = match events.get(0) { + None => { return None }, + Some(e) => e.clone(), + }; + for e in events.iter() { + if e.created_at > latest.created_at { + latest = e.clone(); + } + } + Some(latest) +} + +fn get_merge_patch( + merge: &Event, + patch_events: &Vec, + repo_dir_path: &PathBuf, +) -> Event{ + let commit_id = tag_extract_value( + merge.tags.iter().find(|tag| tag_is_commit(tag)) + .expect("merge event will have a commit tag") + ); + // search in patch_events vector + match patch_events.iter().find(|p| + tag_extract_value( + p.tags.iter().find(|tag| tag_is_commit(tag)) + .expect("patch event will have a commit tag") + ) == *commit_id + ) { + // found merge patch in patch_events + Some(patch) => patch.clone(), + None => { + let patch_path = repo_dir_path.join(format!( + ".ngit/patches/{}.json", + commit_id + )); + if patch_path.exists() { + // found merge patch in .ngit/patches + load_event(patch_path) + .expect("patch at path that exists renders as event") + } + else { + panic!("cannot find patch from merge event in event vector or .ngit folder"); + } + }, + } +} -- cgit v1.2.3