use std::env;
use config::Config;
use git2::Repository;
use crate::Error;
#[derive(Debug)]
pub(crate) struct PullRequest {
pub(crate) pull_request: String,
pub(crate) title: String,
pub(crate) body: String,
#[allow(dead_code)]
pub(crate) owner: String,
#[allow(dead_code)]
pub(crate) repo: String,
#[allow(dead_code)]
pub(crate) repo_url: String,
pub(crate) pr_number: i64,
}
impl PullRequest {
pub async fn new_pull_request_opt(
settings: &Config,
graphql: &gql_client::Client,
) -> Result<Option<Self>, Error> {
log::trace!("command: {:?}", settings.get::<String>("command"));
let command: String = settings.get("command").map_err(|_| Error::CommandNotSet)?;
log::trace!("command: {command:?}");
if command != "pr" {
return Ok(None);
}
log::trace!("pull_request: {:?}", settings.get::<String>("pull_request"));
let pcu_pull_request: String = settings
.get("pull_request")
.map_err(|_| Error::EnvVarPullRequestNotSet)?;
log::trace!("pcu_pull_request: {pcu_pull_request:?}");
let pull_request =
env::var(pcu_pull_request).map_err(|_| Error::EnvVarPullRequestNotFound)?;
let (owner, repo, pr_number, repo_url) = PullRequest::get_keys(&pull_request)?;
log::debug!("Owner: {owner}, repo: {repo}, pr_number: {pr_number}, repo_url: {repo_url}");
let pr_number = pr_number.parse::<i64>()?;
log::debug!("********* Using GraphQL");
let (title, body) =
super::graphql::get_pull_request_title(graphql, &owner, &repo, pr_number).await?;
Ok(Some(Self {
pull_request,
title,
body,
owner,
repo,
repo_url,
pr_number,
}))
}
pub async fn from_head_commit(
git_repo: &Repository,
graphql: &gql_client::Client,
owner: &str,
repo: &str,
) -> Result<Self, Error> {
let head = git_repo.head()?;
let commit = head.peel_to_commit()?;
let commit_sha = commit.id().to_string();
log::debug!("Looking up PR for commit: {commit_sha}");
let (pr_number, title, pull_request, body) =
super::graphql::get_pull_request_by_commit(graphql, owner, repo, &commit_sha).await?;
log::debug!("Found PR #{pr_number}: {title}");
let repo_url = format!("https://github.com/{owner}/{repo}");
Ok(Self {
pull_request,
title,
body,
owner: owner.to_string(),
repo: repo.to_string(),
repo_url,
pr_number,
})
}
fn get_keys(pull_request: &str) -> Result<(String, String, String, String), Error> {
if pull_request.contains("github.com") {
let parts = pull_request.splitn(7, '/').collect::<Vec<&str>>();
Ok((
parts[3].to_string(),
parts[4].to_string(),
parts[6].to_string(),
format!("https://github.com/{}/{}", parts[3], parts[4]),
))
} else {
Err(Error::UnknownPullRequestFormat(pull_request.to_string()))
}
}
}