use super::deferral::Deferral;
use super::{CrateInfo, CrateRef, Pipeline, PromoteError, PublishOpts, Registry, Stage};
pub trait Publisher {
fn publish(
&self,
krate: &CrateRef,
registry: &Registry,
opts: &PublishOpts,
) -> Result<(), PromoteError>;
}
impl<T: Publisher> Publisher for &T {
fn publish(
&self,
krate: &CrateRef,
registry: &Registry,
opts: &PublishOpts,
) -> Result<(), PromoteError> {
(**self).publish(krate, registry, opts)
}
}
pub trait RegistryQuery {
fn list_crates(&self, registry: &Registry) -> Result<Vec<CrateInfo>, PromoteError>;
fn crate_exists(
&self,
registry: &Registry,
name: &str,
version: &str,
) -> Result<bool, PromoteError> {
let _ = (registry, name, version);
Ok(false)
}
}
pub trait BranchMerger {
fn fast_forward(&self, source: &str, target: &str) -> Result<(), PromoteError>;
}
impl<T: BranchMerger> BranchMerger for &T {
fn fast_forward(&self, source: &str, target: &str) -> Result<(), PromoteError> {
(**self).fast_forward(source, target)
}
}
pub trait RemotePusher {
fn push_branch(&self, branch: &str) -> Result<(), PromoteError>;
fn push_tag(&self, tag: &str) -> Result<(), PromoteError>;
}
impl<T: RemotePusher> RemotePusher for &T {
fn push_branch(&self, branch: &str) -> Result<(), PromoteError> {
(**self).push_branch(branch)
}
fn push_tag(&self, tag: &str) -> Result<(), PromoteError> {
(**self).push_tag(tag)
}
}
pub trait Tagger {
fn create_tag(&self, name: &str, message: &str) -> Result<(), PromoteError>;
}
impl<T: Tagger> Tagger for &T {
fn create_tag(&self, name: &str, message: &str) -> Result<(), PromoteError> {
(**self).create_tag(name, message)
}
}
pub trait PipelineRunner {
fn run_stage(
&self,
krate: &CrateRef,
stage: &Stage,
opts: &PublishOpts,
) -> Result<(), PromoteError>;
fn run_full(
&self,
krate: &CrateRef,
pipeline: &Pipeline,
opts: &PublishOpts,
) -> Result<(), PromoteError>;
fn promote_next(
&self,
krate: &CrateRef,
pipeline: &Pipeline,
current_stage: &str,
opts: &PublishOpts,
) -> Result<(), PromoteError>;
}
pub trait TokenResolver {
fn resolve(&self, registry_name: &str) -> Result<Option<secrecy::SecretString>, PromoteError>;
}
pub trait Notifier {
fn on_deferred(&self, deferral: &Deferral) -> Result<(), PromoteError>;
}
pub trait Forge {
fn create_release(&self, tag: &str, name: &str, body: &str) -> Result<(), PromoteError>;
fn create_pr(
&self,
title: &str,
body: &str,
head: &str,
base: &str,
) -> Result<u64, PromoteError>;
fn comment_pr(&self, pr_number: u64, body: &str) -> Result<(), PromoteError>;
fn close_pr(&self, pr_number: u64) -> Result<(), PromoteError>;
}
pub struct NoopForge;
impl Forge for NoopForge {
fn create_release(&self, _tag: &str, _name: &str, _body: &str) -> Result<(), PromoteError> {
Ok(())
}
fn create_pr(
&self,
_title: &str,
_body: &str,
_head: &str,
_base: &str,
) -> Result<u64, PromoteError> {
Ok(0)
}
fn comment_pr(&self, _pr_number: u64, _body: &str) -> Result<(), PromoteError> {
Ok(())
}
fn close_pr(&self, _pr_number: u64) -> Result<(), PromoteError> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn noop_forge_create_release_returns_ok() {
let forge = NoopForge;
assert!(
forge
.create_release("v0.1.0", "Release 0.1.0", "body")
.is_ok()
);
}
#[test]
fn noop_forge_create_pr_returns_zero() {
let forge = NoopForge;
let pr = forge.create_pr("title", "body", "head", "base").unwrap();
assert_eq!(pr, 0);
}
#[test]
fn noop_forge_comment_pr_returns_ok() {
let forge = NoopForge;
assert!(forge.comment_pr(1, "comment").is_ok());
}
#[test]
fn noop_forge_close_pr_returns_ok() {
let forge = NoopForge;
assert!(forge.close_pr(1).is_ok());
}
}