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/create_branch_and_pr.rs | 212 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 src/funcs/create_branch_and_pr.rs (limited to 'src/funcs/create_branch_and_pr.rs') diff --git a/src/funcs/create_branch_and_pr.rs b/src/funcs/create_branch_and_pr.rs new file mode 100644 index 0000000..f67dfb3 --- /dev/null +++ b/src/funcs/create_branch_and_pr.rs @@ -0,0 +1,212 @@ +use std::{path::PathBuf}; + +use dialoguer::{Input, theme::ColorfulTheme, Confirm}; +use nostr::{Keys, prelude::{Nip19Event, ToBech32}}; +use nostr_sdk::blocking::Client; + +use crate::{repos::{repo::Repo, init::InitializeRepo}, branch_refs::BranchRefs, cli_helpers::multi_select_with_add, groups::{init::{InitializeGroup}, group::{Group}}, config::{MyConfig, save_conifg}, repo_config::RepoConfig, pull_request::initialize_pull_request}; + +struct PullRequest { + pub title: String, + pub description: String, + pub tags: Vec +} +/// returns branch_id +pub fn create_branch_and_pr( + local_branch_name: &String, + commits_to_push: usize, + repo_dir_path: &PathBuf, + repo: &Repo, + branch_refs: &mut BranchRefs, + keys: &Keys, + cfg: &mut MyConfig, + client: &Client, +) -> String { + let new_branch_name: String = Input::with_theme(&ColorfulTheme::default()) + .with_prompt(format!( + "push {} commits to a branch named", + commits_to_push, + )) + .with_initial_text(&local_branch_name.to_string()) + .interact_text() + .unwrap(); + let pr_details = match Confirm::with_theme(&ColorfulTheme::default()) + .with_prompt("open a pull request?") + .default(true) + .interact() + .unwrap() { + false => None, + true => { + let title = Input::with_theme(&ColorfulTheme::default()) + .with_prompt("title") + .with_initial_text(&new_branch_name) + .interact_text() + .unwrap(); + let tags = multi_select_with_add( + vec![ + "bugfix".to_string(), + "feature".to_string(), + ], + vec![ + false, + false, + ], + "tags", + "new tag", + ); + let description = Input::with_theme(&ColorfulTheme::default()) + .with_prompt("description") + .interact_text() + .unwrap(); + // into main / master (lookup (yes/no) - if no select from existing branches with mapping + Some( + PullRequest { + title, + tags, + description, + } + ) + }, + }; + // create it now immediately before pushing the patches + let mut events_to_broadcast = vec![]; + + // create/store admin group + let admin_group = match &cfg.default_admin_group_event_serialized { + None => { + let new_admin_group = Group::new( + &InitializeGroup::new() + .members( + vec![ + keys.public_key().to_string(), + ], + vec![], + ) + .relays(&repo.relays), + &keys, + ).unwrap(); + cfg.default_admin_group_event_serialized = Some(new_admin_group.events[0].as_json()); + save_conifg(&cfg); + new_admin_group + }, + Some(admin) => Group::new_from_json_event(admin.clone()) + .expect("admin group event in MyConfig loads into Group"), + }; + events_to_broadcast.push(admin_group.events[0].clone()); + branch_refs.update(admin_group.events[0].clone()); + + + // create group + let branch_group_ref = match branch_refs.is_authorized( + None, + &keys.public_key(), + ) + .expect("main repo maintainers group is cached in .ngit") + { + // use repo maintainers group + true => branch_refs.maintainers_group(None) + .expect("main repo maintainers group is cached in .ngit") + .get_ref(), + // create branch group + false => { + let new_group = Group::new( + &InitializeGroup::new() + .name( + format!( + "branch-of:{},named:{}", + match &repo.name { + None => "untitled", + Some(s) => s.as_str(), + }, + &new_branch_name, + ), + ) + .admin(admin_group.get_ref()) + .members( + vec![keys.public_key().to_string()], + vec![ + branch_refs.maintainers_group(None) + .expect("repo maintainers group to exist in .ngit directory") + .get_ref() + ] + ) + .relays(&repo.relays) + , + &keys, + ) + .expect("new branch group to be created"); + + events_to_broadcast.push(new_group.events[0].clone()); + branch_refs.update(new_group.events[0].clone()); + new_group.get_ref() + } + }; + + // create branch + let branch_init = InitializeRepo::new() + .name(&new_branch_name) + .relays(&repo.relays) + .root_repo(repo.id.to_string()) + .maintainers_group(branch_group_ref) + .initialize(&keys); + events_to_broadcast.push(branch_init.clone()); + branch_refs.update(branch_init.clone()); + + // TODO: create PR + match pr_details { + None => (), + Some(pr_details) => { + let pull_request_init = initialize_pull_request( + &keys, + &repo.id.to_string(), + &repo.id.to_string(), + &branch_init.id.to_string(), + &pr_details.title, + &pr_details.description, + pr_details.tags + ); + events_to_broadcast.push(pull_request_init.clone()); + branch_refs.update(pull_request_init.clone()); + println!( + "pull request '{}' created with id: {}", + &pr_details.title, + Nip19Event::new( + pull_request_init.id.clone(), + vec![&repo.relays[0]], + ) + .to_bech32() + .expect("Nip19Event to convert to to_bech32") + ); + }, + } + + // add mapping to conifg.json + RepoConfig::open(repo_dir_path).set_mapping( + local_branch_name, + &branch_init.id.to_string(), + ); + + println!( + "branch '{}' created with id: {}", + &new_branch_name, + Nip19Event::new( + branch_init.id.clone(), + vec![&repo.relays[0]], + ) + .to_bech32() + .expect("Nip19Event to convert to to_bech32") + ); + + // broadcast events + for e in &events_to_broadcast { + match client.send_event(e.clone()) { + Ok(_) => (), + // TODO: this isn't working - if a relay is specified with a type it will wait 30ish secs and then return successful + Err(e) => { println!("error broadcasting event: {}",e); }, + } + // TODO: better error handling here / reporting. potentially warn if taking a while and report on troublesome relays + } + + // return branch_id + branch_init.id.to_string() +} -- cgit v1.2.3