use std::time::Duration;
use crate::contract::schema::Adapter;
use crate::protocol::release::{
BuildArtifacts, DryRunReport, PlannedCommand, PublishReceipt, VerifyOutcome,
};
use super::{make_receipt, run_all, AdapterError, AdapterTarget, EffectCtx, ReleaseAdapter};
pub struct HomebrewAdapter {
adapter: Adapter,
}
impl HomebrewAdapter {
#[must_use]
pub fn new(adapter: Adapter) -> Self {
debug_assert!(matches!(
adapter,
Adapter::HomebrewTap | Adapter::HomebrewCore
));
Self { adapter }
}
}
impl ReleaseAdapter for HomebrewAdapter {
fn adapter(&self) -> Adapter {
self.adapter
}
fn dry_run(
&self,
_ctx: &EffectCtx<'_>,
t: &AdapterTarget,
) -> Result<DryRunReport, AdapterError> {
Ok(DryRunReport {
adapter: self.adapter,
planned_commands: vec![PlannedCommand::new(
"brew",
&["audit", "--strict", &t.package],
)],
notes: vec![
"a formula is a downstream bump of an already-published artifact; \
there is no separate build step"
.to_string(),
],
})
}
fn build(
&self,
_ctx: &EffectCtx<'_>,
_t: &AdapterTarget,
) -> Result<BuildArtifacts, AdapterError> {
Ok(BuildArtifacts {
adapter: self.adapter,
artifacts: vec![],
notes: vec!["homebrew has no build phase (formula update only)".to_string()],
})
}
fn publish(
&self,
ctx: &EffectCtx<'_>,
t: &AdapterTarget,
) -> Result<PublishReceipt, AdapterError> {
let mut args: Vec<&str> = match self.adapter {
Adapter::HomebrewCore => vec!["bump-formula-pr", "--no-fork"],
_ => vec!["bump-formula-pr"],
};
if let Some(tarball) = &ctx.artifacts.source_tarball {
args.push("--url");
args.push(tarball.url.as_str());
if let Some(sha256) = &tarball.sha256 {
args.push("--sha256");
args.push(sha256.as_str());
}
}
args.push("--");
args.push(t.package.as_str());
run_all(ctx, &[PlannedCommand::new("brew", &args)])?;
Ok(make_receipt(ctx, t, None, None))
}
fn verify(
&self,
_ctx: &EffectCtx<'_>,
_receipt: &PublishReceipt,
) -> Result<VerifyOutcome, AdapterError> {
Ok(VerifyOutcome::Unknown)
}
fn timeout(&self) -> Duration {
Duration::from_secs(600)
}
}