Skip to content

Commit

Permalink
improvements to pr workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Bendzae committed Nov 23, 2024
1 parent 648c472 commit 2dcb67f
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 44 deletions.
66 changes: 44 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ clap = { version = "4.5.11", features = ["derive"] }
console = "0.15.8"
dialoguer = "0.11.0"
indicatif = "0.17.8"
octocrab = "0.38.0"
octocrab = "0.41.2"
ron = "0.8.1"
toml = "0.8.16"
rustygit = "0.5.0"
Expand Down
77 changes: 57 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::{path::PathBuf, str::FromStr, sync::Arc};
use clap::Parser;
use console::{pad_str, style};
use dialoguer::{theme::ColorfulTheme, Input, Select};
use octocrab::{models::pulls::PullRequest, Octocrab, Page};
use octocrab::{
models::pulls::PullRequest, params::pulls::Sort, pulls::PullRequestHandler, Octocrab, Page,
};
use rustygit::types::BranchName;

use crate::{
Expand Down Expand Up @@ -48,7 +50,7 @@ async fn main() -> Result<()> {
Some(Commands::Add { name }) => ctx.add_to_stack(name)?,
Some(Commands::List {}) => ctx.list()?,
Some(Commands::Change {}) => ctx.change()?,
Some(Commands::Sync {}) => ctx.sync()?,
Some(Commands::Sync {}) => ctx.sync().await?,
Some(Commands::Up {}) => ctx.checkout_above()?,
Some(Commands::Down {}) => ctx.checkout_below()?,
Some(Commands::Base {}) => ctx.checkout_base()?,
Expand All @@ -59,7 +61,7 @@ async fn main() -> Result<()> {
Some(Commands::Reset {}) => ctx.reset()?,
None => println!(
"Welcome to {}! Run {} to see available commands.",
style("G-Stack").bold().cyan(),
style("G-Stack v0.0.3").bold().cyan(),
style("gs help").italic().green(),
),
}
Expand Down Expand Up @@ -282,7 +284,7 @@ impl GsContext {
Ok(())
}

fn sync(&self) -> Result<()> {
async fn sync(&self) -> Result<()> {
let current_branch = self.repo.current_branch()?;
let branches = &self.current_stack().unwrap().branches;
self.repo.pull_all(branches).ok();
Expand All @@ -296,8 +298,13 @@ impl GsContext {
BranchName::from_str(rebase_on)?,
)?;
self.repo
.push_to_upstream("origin", &BranchName::from_str(branch)?)?;
.force_push_to_upstream("origin", &BranchName::from_str(branch)?)?;
}
let open_pulls = self.get_pull_requests().await?;
let remote = self.repo.remote_repo_info()?;
let pulls = self.github.pulls(remote.owner, remote.name);
self.update_pr_descriptions(&pulls, open_pulls).await?;

self.repo.switch_branch(&current_branch)?;
Ok(())
}
Expand All @@ -322,25 +329,43 @@ impl GsContext {
);

println!("base: {}, title: {}", base, title);
let pr = pulls
.create(title, branch, base)
.body("Created by [gstack](https://github.com/Bendzae/gstack)")
.send()
.await?;
let pr = pulls.create(title, branch, base).body("---").send().await?;
println!("#{}: {}", pr.number, pr.html_url.clone().unwrap());
created_pulls.push(pr);
}

for pr in &created_pulls {
let mut body = "".to_string();
created_pulls
.iter()
.for_each(|p| body = body.clone() + format!("#{} \n", p.number).as_str());
body = body.clone() + "\nCreated by [gstack](https://github.com/Bendzae/gstack)";
self.update_pr_descriptions(&pulls, created_pulls).await?;
Ok(())
}

async fn update_pr_descriptions(
&self,
pulls: &PullRequestHandler<'_>,
prs: Vec<PullRequest>,
) -> Result<()> {
for pr in &prs {
let mut body = pr
.body
.clone()
.unwrap_or("".to_string())
.lines()
.take_while(|line| !line.contains("---"))
.collect::<Vec<&str>>()
.join("\n");

body.push_str("\n---\n");
prs.iter().for_each(|p| {
body.push_str(format!("- #{}", p.number).as_str());
if pr.number == p.number {
body.push_str(" (This PR)");
}
body.push('\n');
});
body = body.clone() + "\n**Created by [gstack](https://github.com/Bendzae/gstack)**";

// println!("Updating: {:?}", body);
pulls.update(pr.number).body(body).send().await?;
}

Ok(())
}

Expand All @@ -349,23 +374,35 @@ impl GsContext {
println!(
"{:?}",
open_pulls
.items
.iter()
.map(|pr| pr.title.clone().unwrap())
.collect::<Vec<String>>()
);
Ok(())
}

async fn get_pull_requests(&self) -> Result<Page<PullRequest>> {
async fn get_pull_requests(&self) -> Result<Vec<PullRequest>> {
let remote = self.repo.remote_repo_info()?;
let pulls = self.github.pulls(remote.owner, remote.name);
let open_pulls = pulls
.list()
.state(octocrab::params::State::Open)
.sort(Sort::Created)
.send()
.await?;
Ok(open_pulls)
let stack = &self.current_stack().unwrap();
let branches = &stack.branches;
let stack_pulls = branches
.iter()
.filter_map(|branch| {
open_pulls
.items
.iter()
.find(|&pr| pr.head.sha == self.repo.head_sha(branch).unwrap_or("".to_string()))
})
.cloned()
.collect::<Vec<PullRequest>>();
Ok(stack_pulls)
}

fn reset(&mut self) -> Result<()> {
Expand Down
21 changes: 20 additions & 1 deletion src/repo_extensions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::Result;
use anyhow::{bail, Ok};
use regex::Regex;
use std::fmt::Debug;
use std::{ops::Rem, str::FromStr};

use rustygit::{types::BranchName, Repository};
Expand All @@ -16,6 +17,8 @@ pub trait RepoExtenstions {
fn pull_all(&self, branches: &Vec<String>) -> Result<()>;
fn remote_repo_url(&self) -> Result<String>;
fn remote_repo_info(&self) -> Result<RemoteRepoInfo>;
fn force_push_to_upstream(&self, upstream: &str, upstream_branch: &BranchName) -> Result<()>;
fn head_sha(&self, branch_name: &String) -> Result<String>;
}

impl RepoExtenstions for Repository {
Expand All @@ -28,7 +31,6 @@ impl RepoExtenstions for Repository {
self.switch_branch(&branch)?;
let output = self.cmd_out(&["rebase", "--update-refs", on.to_string().as_str()])?;
println!("{:?}", output);
println!("{:?}", output);
Ok(())
}

Expand Down Expand Up @@ -63,4 +65,21 @@ impl RepoExtenstions for Repository {
bail!("Malformed remote url")
}
}

///Force push the curent branch to its associated remote, specifying the upstream branch
fn force_push_to_upstream(&self, upstream: &str, upstream_branch: &BranchName) -> Result<()> {
self.cmd_out(&[
"push",
"-u",
upstream,
upstream_branch.to_string().as_str(),
"--force",
]);
Ok(())
}

fn head_sha(&self, branch_name: &String) -> Result<String> {
let output = self.cmd_out(&["rev-parse", branch_name])?;
Ok(output.first().unwrap().clone())
}
}

0 comments on commit 2dcb67f

Please sign in to comment.