ossctl_core/release/adapters/
homebrew.rs1use std::time::Duration;
10
11use crate::contract::schema::Adapter;
12use crate::protocol::release::{
13 BuildArtifacts, DryRunReport, PlannedCommand, PublishReceipt, VerifyOutcome,
14};
15
16use super::{make_receipt, run_all, AdapterError, AdapterTarget, EffectCtx, ReleaseAdapter};
17
18pub struct HomebrewAdapter {
21 adapter: Adapter,
22}
23
24impl HomebrewAdapter {
25 #[must_use]
27 pub fn new(adapter: Adapter) -> Self {
28 debug_assert!(matches!(
29 adapter,
30 Adapter::HomebrewTap | Adapter::HomebrewCore
31 ));
32 Self { adapter }
33 }
34}
35
36impl ReleaseAdapter for HomebrewAdapter {
37 fn adapter(&self) -> Adapter {
38 self.adapter
39 }
40
41 fn dry_run(
42 &self,
43 _ctx: &EffectCtx<'_>,
44 t: &AdapterTarget,
45 ) -> Result<DryRunReport, AdapterError> {
46 Ok(DryRunReport {
47 adapter: self.adapter,
48 planned_commands: vec![PlannedCommand::new(
49 "brew",
50 &["audit", "--strict", &t.package],
51 )],
52 notes: vec![
53 "a formula is a downstream bump of an already-published artifact; \
54 there is no separate build step"
55 .to_string(),
56 ],
57 })
58 }
59
60 fn build(
61 &self,
62 _ctx: &EffectCtx<'_>,
63 _t: &AdapterTarget,
64 ) -> Result<BuildArtifacts, AdapterError> {
65 Ok(BuildArtifacts {
68 adapter: self.adapter,
69 artifacts: vec![],
70 notes: vec!["homebrew has no build phase (formula update only)".to_string()],
71 })
72 }
73
74 fn publish(
75 &self,
76 ctx: &EffectCtx<'_>,
77 t: &AdapterTarget,
78 ) -> Result<PublishReceipt, AdapterError> {
79 let mut args: Vec<&str> = match self.adapter {
87 Adapter::HomebrewCore => vec!["bump-formula-pr", "--no-fork"],
88 _ => vec!["bump-formula-pr"],
89 };
90 if let Some(tarball) = &ctx.artifacts.source_tarball {
91 args.push("--url");
92 args.push(tarball.url.as_str());
93 if let Some(sha256) = &tarball.sha256 {
94 args.push("--sha256");
95 args.push(sha256.as_str());
96 }
97 }
98 args.push("--");
100 args.push(t.package.as_str());
101 run_all(ctx, &[PlannedCommand::new("brew", &args)])?;
102 Ok(make_receipt(ctx, t, None, None))
103 }
104
105 fn verify(
106 &self,
107 _ctx: &EffectCtx<'_>,
108 _receipt: &PublishReceipt,
109 ) -> Result<VerifyOutcome, AdapterError> {
110 Ok(VerifyOutcome::Unknown)
113 }
114
115 fn timeout(&self) -> Duration {
116 Duration::from_secs(600)
117 }
118}