mirror of
https://codeberg.org/Cyborus/forgejo-cli.git
synced 2024-11-23 18:31:46 +01:00
feat!: add branch guessing on pr creation
This commit is contained in:
parent
4a9c9b7301
commit
af40eb32ba
1 changed files with 108 additions and 24 deletions
110
src/prs.rs
110
src/prs.rs
|
@ -45,9 +45,11 @@ pub enum PrSubcommand {
|
|||
/// Create a new pull request
|
||||
Create {
|
||||
/// The branch to merge onto.
|
||||
base: String,
|
||||
#[clap(long)]
|
||||
base: Option<String>,
|
||||
/// The branch to pull changes from.
|
||||
head: String,
|
||||
#[clap(long)]
|
||||
head: Option<String>,
|
||||
/// What to name the new pull request.
|
||||
///
|
||||
/// Prefix with "WIP: " to mark this PR as a draft.
|
||||
|
@ -788,33 +790,115 @@ async fn create_pr(
|
|||
repo: &RepoName,
|
||||
api: &Forgejo,
|
||||
title: String,
|
||||
base: String,
|
||||
head: String,
|
||||
base: Option<String>,
|
||||
head: Option<String>,
|
||||
body: Option<String>,
|
||||
) -> eyre::Result<()> {
|
||||
let (repo_owner, repo_name, base, head) = match base.strip_prefix("^") {
|
||||
Some(parent_base) => {
|
||||
let mut repo_data = api.repo_get(repo.owner(), repo.name()).await?;
|
||||
let parent = *repo_data
|
||||
|
||||
let head = match head {
|
||||
Some(head) => head,
|
||||
None => {
|
||||
let local_repo = git2::Repository::open(".")?;
|
||||
let head = local_repo.head()?;
|
||||
eyre::ensure!(
|
||||
head.is_branch(),
|
||||
"HEAD is not on branch, can't guess head branch"
|
||||
);
|
||||
|
||||
let branch_ref = head
|
||||
.name()
|
||||
.ok_or_eyre("current branch does not have utf8 name")?;
|
||||
let upstream_remote = local_repo.branch_upstream_remote(branch_ref)?;
|
||||
let remote_name = upstream_remote
|
||||
.as_str()
|
||||
.ok_or_eyre("remote does not have utf8 name")?;
|
||||
|
||||
let remote = local_repo.find_remote(remote_name)?;
|
||||
let remote_url_s = remote.url().ok_or_eyre("remote does not have utf8 url")?;
|
||||
let remote_url = url::Url::parse(remote_url_s)?;
|
||||
|
||||
let clone_url = repo_data
|
||||
.clone_url
|
||||
.as_ref()
|
||||
.ok_or_eyre("repo does not have git url")?;
|
||||
let html_url = repo_data
|
||||
.html_url
|
||||
.as_ref()
|
||||
.ok_or_eyre("repo does not have html url")?;
|
||||
let ssh_url = repo_data
|
||||
.ssh_url
|
||||
.as_ref()
|
||||
.ok_or_eyre("repo does not have ssh url")?;
|
||||
eyre::ensure!(
|
||||
&remote_url == clone_url || &remote_url == html_url || &remote_url == ssh_url,
|
||||
"branch does not track that repo"
|
||||
);
|
||||
|
||||
let upstream_branch = local_repo.branch_upstream_name(branch_ref)?;
|
||||
let upstream_branch = upstream_branch
|
||||
.as_str()
|
||||
.ok_or_eyre("remote branch does not have utf8 name")?;
|
||||
upstream_branch
|
||||
.rsplit_once("/")
|
||||
.map(|(_, b)| b)
|
||||
.unwrap_or(upstream_branch)
|
||||
.to_owned()
|
||||
}
|
||||
};
|
||||
|
||||
let (base, base_is_parent) = match base {
|
||||
Some(base) => match base.strip_prefix("^") {
|
||||
Some(stripped) if stripped.is_empty() => (None, true),
|
||||
Some(stripped) => (Some(stripped.to_owned()), true),
|
||||
None => (Some(base), false),
|
||||
},
|
||||
None => (None, false),
|
||||
};
|
||||
|
||||
let (repo_owner, repo_name, base_repo, head) = if base_is_parent {
|
||||
let parent_repo = *repo_data
|
||||
.parent
|
||||
.take()
|
||||
.ok_or_eyre("cannot create pull request upstream, there is no upstream")?;
|
||||
let parent_owner = parent
|
||||
let parent_owner = parent_repo
|
||||
.owner
|
||||
.as_ref()
|
||||
.ok_or_eyre("parent has no owner")?
|
||||
.login
|
||||
.ok_or_eyre("parent owner has no login")?;
|
||||
let parent_name = parent.name.ok_or_eyre("parent has no name")?;
|
||||
.as_deref()
|
||||
.ok_or_eyre("parent owner has no login")?
|
||||
.to_owned();
|
||||
let parent_name = parent_repo
|
||||
.name
|
||||
.as_deref()
|
||||
.ok_or_eyre("parent has no name")?
|
||||
.to_owned();
|
||||
|
||||
(
|
||||
parent_owner,
|
||||
parent_name,
|
||||
parent_base.to_owned(),
|
||||
parent_repo,
|
||||
format!("{}:{}", repo.owner(), head),
|
||||
)
|
||||
}
|
||||
None => (repo.owner().to_owned(), repo.name().to_owned(), base, head),
|
||||
} else {
|
||||
(
|
||||
repo.owner().to_owned(),
|
||||
repo.name().to_owned(),
|
||||
repo_data,
|
||||
head,
|
||||
)
|
||||
};
|
||||
|
||||
let base = match base {
|
||||
Some(base) => base,
|
||||
None => base_repo
|
||||
.default_branch
|
||||
.as_deref()
|
||||
.ok_or_eyre("repo does not have default branch")?
|
||||
.to_owned(),
|
||||
};
|
||||
|
||||
let body = match body {
|
||||
Some(body) => body,
|
||||
None => {
|
||||
|
|
Loading…
Reference in a new issue