mirror of
https://codeberg.org/Cyborus/forgejo-cli.git
synced 2024-11-14 05:59:27 +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 a new pull request
|
||||||
Create {
|
Create {
|
||||||
/// The branch to merge onto.
|
/// The branch to merge onto.
|
||||||
base: String,
|
#[clap(long)]
|
||||||
|
base: Option<String>,
|
||||||
/// The branch to pull changes from.
|
/// The branch to pull changes from.
|
||||||
head: String,
|
#[clap(long)]
|
||||||
|
head: Option<String>,
|
||||||
/// What to name the new pull request.
|
/// What to name the new pull request.
|
||||||
///
|
///
|
||||||
/// Prefix with "WIP: " to mark this PR as a draft.
|
/// Prefix with "WIP: " to mark this PR as a draft.
|
||||||
|
@ -788,33 +790,115 @@ async fn create_pr(
|
||||||
repo: &RepoName,
|
repo: &RepoName,
|
||||||
api: &Forgejo,
|
api: &Forgejo,
|
||||||
title: String,
|
title: String,
|
||||||
base: String,
|
base: Option<String>,
|
||||||
head: String,
|
head: Option<String>,
|
||||||
body: Option<String>,
|
body: Option<String>,
|
||||||
) -> eyre::Result<()> {
|
) -> 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 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
|
.parent
|
||||||
.take()
|
.take()
|
||||||
.ok_or_eyre("cannot create pull request upstream, there is no upstream")?;
|
.ok_or_eyre("cannot create pull request upstream, there is no upstream")?;
|
||||||
let parent_owner = parent
|
let parent_owner = parent_repo
|
||||||
.owner
|
.owner
|
||||||
|
.as_ref()
|
||||||
.ok_or_eyre("parent has no owner")?
|
.ok_or_eyre("parent has no owner")?
|
||||||
.login
|
.login
|
||||||
.ok_or_eyre("parent owner has no login")?;
|
.as_deref()
|
||||||
let parent_name = parent.name.ok_or_eyre("parent has no name")?;
|
.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_owner,
|
||||||
parent_name,
|
parent_name,
|
||||||
parent_base.to_owned(),
|
parent_repo,
|
||||||
format!("{}:{}", repo.owner(), head),
|
format!("{}:{}", repo.owner(), head),
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
None => (repo.owner().to_owned(), repo.name().to_owned(), base, head),
|
(
|
||||||
|
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 {
|
let body = match body {
|
||||||
Some(body) => body,
|
Some(body) => body,
|
||||||
None => {
|
None => {
|
||||||
|
|
Loading…
Reference in a new issue