use clap::builder::NonEmptyStringValueParser;
use clap::ValueEnum;
use release_plz_core::{GitBackend, GitHub, GitLab, Gitea, RepoUrl};
use secrecy::SecretString;
use super::{update::Update, OutputType};
#[derive(clap::Parser, Debug)]
pub struct ReleasePr {
#[command(flatten)]
pub update: Update,
#[arg(long, value_parser = NonEmptyStringValueParser::new(), visible_alias = "github-token", env, hide_env_values=true)]
git_token: String,
#[arg(long, value_enum, default_value_t = GitBackendKind::Github)]
backend: GitBackendKind,
#[arg(short, long, value_enum)]
pub output: Option<OutputType>,
}
#[derive(ValueEnum, Clone, Copy, Debug, Eq, PartialEq)]
pub enum GitBackendKind {
#[value(name = "github")]
Github,
#[value(name = "gitea")]
Gitea,
#[value(name = "gitlab")]
Gitlab,
}
impl ReleasePr {
pub fn git_backend(&self, repo: RepoUrl) -> anyhow::Result<GitBackend> {
let token = SecretString::from(self.git_token.clone());
Ok(match self.backend {
GitBackendKind::Github => {
anyhow::ensure!(
repo.is_on_github(),
"Can't create PR: the repository is not hosted in GitHub. Please select a different backend."
);
GitBackend::Github(GitHub::new(repo.owner, repo.name, token))
}
GitBackendKind::Gitea => GitBackend::Gitea(Gitea::new(repo, token)?),
GitBackendKind::Gitlab => GitBackend::Gitlab(GitLab::new(repo, token)?),
})
}
}
#[cfg(test)]
mod tests {
use release_plz_core::RepoUrl;
const GITHUB_COM: &str = "github.com";
#[test]
fn https_github_url_is_parsed() {
let expected_owner = "MarcoIeni";
let expected_repo = "release-plz";
let url = format!("https://{GITHUB_COM}/{expected_owner}/{expected_repo}");
let repo = RepoUrl::new(&url).unwrap();
assert_eq!(expected_owner, repo.owner);
assert_eq!(expected_repo, repo.name);
assert_eq!(GITHUB_COM, repo.host);
assert!(repo.is_on_github());
}
#[test]
fn git_github_url_is_parsed() {
let expected_owner = "MarcoIeni";
let expected_repo = "release-plz";
let url = format!("git@github.com:{expected_owner}/{expected_repo}.git");
let repo = RepoUrl::new(&url).unwrap();
assert_eq!(expected_owner, repo.owner);
assert_eq!(expected_repo, repo.name);
assert_eq!(GITHUB_COM, repo.host);
assert!(repo.is_on_github());
}
#[test]
fn gitea_url_is_parsed() {
let host = "example.com";
let expected_owner = "MarcoIeni";
let expected_repo = "release-plz";
let url = format!("https://{host}/{expected_owner}/{expected_repo}");
let repo = RepoUrl::new(&url).unwrap();
assert_eq!(expected_owner, repo.owner);
assert_eq!(expected_repo, repo.name);
assert_eq!(host, repo.host);
assert_eq!("https", repo.scheme);
assert!(!repo.is_on_github());
assert_eq!(format!("https://{host}/api/v1/"), repo.gitea_api_url());
}
}