upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/funcs/create_patches.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2023-05-21 11:14:47 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2023-05-21 11:14:47 +0000
commit0067804cc00e94ce2b7043e67f9ff50968525479 (patch)
tree2accdc6d4e9b73df4f20499238ec24f24a52a1b8 /src/funcs/create_patches.rs
parent5c5feaa732363e32e2a980a887fa42b4394b1a5e (diff)
v0.0.1-alpha funcs
Diffstat (limited to 'src/funcs/create_patches.rs')
-rw-r--r--src/funcs/create_patches.rs122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/funcs/create_patches.rs b/src/funcs/create_patches.rs
new file mode 100644
index 0000000..2a877a0
--- /dev/null
+++ b/src/funcs/create_patches.rs
@@ -0,0 +1,122 @@
1use git2::{Email, EmailCreateOptions};
2use indicatif::ProgressBar;
3use nostr::{Keys, Event};
4
5use crate::{repos::repo::Repo, utils::{create_client, load_event, save_event}, ngit_tag::{tag_is_commit, tag_extract_value}, patch::initialize_patch, repo_config::RepoConfig};
6
7pub fn create_and_broadcast_patches_from_oid(
8 oids_ancestors_first: Vec<git2::Oid>,
9 git_repo: &git2::Repository,
10 repo_dir_path: &std::path::PathBuf,
11 repo: &Repo,
12 branch_id: &String,
13 keys: &Keys,
14) {
15 let mut patches: Vec<Event> = vec![];
16 for oid in oids_ancestors_first {
17 patches.push(
18 create_and_save_patch_from_oid(
19 &oid,
20 &patches,
21 &git_repo,
22 &repo_dir_path.join(".ngit"),
23 &repo,
24 &branch_id,
25 &keys,
26 )
27 );
28 }
29
30 // update branch update timestamp
31 match patches.last() {
32 Some(p) => {
33 let mut repo_config = RepoConfig::open(&repo_dir_path);
34 repo_config.set_last_patch_update_time(
35 branch_id.clone(),
36 p.created_at.clone(),
37 );
38 }
39 None => (),
40 };
41
42
43 // broadcast patches
44 let spinner = ProgressBar::new_spinner();
45 spinner.set_message(format!("Broadcasting... if this takes 20s+, there was a problem broadcasting to one or more relays even if it says 'Pushed {} patches!'.",patches.len()));
46
47 let client = create_client(&keys, repo.relays.clone())
48 .expect("create_client to return client for create_and_broadcast_patches");
49 for e in &patches {
50 match client.send_event(e.clone()) {
51 Ok(_) => (),
52 // TODO: this isn't working - if a relay is specified with a type it will wait 30ish secs and then return successful
53 Err(e) => { println!("error broadcasting patch event: {}",e); },
54 }
55 // TODO: better error handling here / reporting. potentially warn if taking a while and report on troublesome relays
56 }
57 spinner.finish_with_message(format!("Pushed {} commits!.",patches.len()));
58}
59
60pub fn create_and_save_patch_from_oid(
61 oid: &git2::Oid,
62 patches: &Vec<Event>,
63 git_repo: &git2::Repository,
64 ngit_path: &std::path::PathBuf,
65 repo: &Repo,
66 branch_id: &String,
67 keys: &Keys,
68) -> Event {
69 let commit_id = format!("{}",oid);
70 let commit = git_repo.find_commit(*oid)
71 .expect("revwalk returns oid that matches a comit in the repository");
72 let message = match commit.message() {
73 None => "",
74 Some(m) => m
75 }.to_string();
76 let email = Email::from_commit(
77 &commit,
78 &mut EmailCreateOptions::default(),
79 ).expect("renders a commit as an email diff");
80 let parent_commit_id: Option<String> = match &commit.parent_id(0) {
81 Ok(parent_oid) => Some(format!("{}",parent_oid)),
82 Err(_) => None,
83 };
84 let parent_patch_id = match &parent_commit_id {
85 None => None,
86 Some(id) => Some({
87 // search for parent in current batch of patches
88 match patches.iter().find(|p|
89 p.tags.iter().find(|t|tag_is_commit(t) && id.clone() == tag_extract_value(&t)).is_some()
90 ) {
91 Some(p) => p.id.to_string(),
92 None => {
93 let parent_patch_path = ngit_path.join(format!("patches/{}.json",id));
94 if parent_patch_path.exists() {
95 load_event(parent_patch_path)
96 .expect("patch in json file that exists produces valid event")
97 .id.to_string()
98 } else {
99 panic!("cannot find parent patch. ngit may have ordered ancestors without patches incorrectly");
100 }
101 },
102 }
103 }),
104 };
105 let event = initialize_patch(
106 &keys,
107 &repo.id.to_string(),
108 &branch_id,
109 &email.as_slice(),
110 &message,
111 &vec![commit_id.to_string()],
112 parent_patch_id,
113 parent_commit_id,
114 );
115 // save patch
116 save_event(ngit_path.join(
117 // TODO: consider what happens if a commit gets published twice, which one would get priority? The one from a maintiner?
118 format!("patches/{}.json",commit_id),
119 ), &event)
120 .expect("save_event to store event in /patches");
121 event
122}