use std::fmt::Write as _;
use crate::contract::schema::{Distribution, Installer};
pub const PINNED_CARGO_DIST_VERSION: &str = "0.28.2";
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeneratedDistConfig {
pub toml: String,
pub targets: Vec<String>,
pub installers: Vec<String>,
pub cargo_dist_version: &'static str,
pub warnings: Vec<String>,
}
#[must_use]
pub fn generate(dist: &Distribution) -> GeneratedDistConfig {
let mut warnings = Vec::new();
let targets: Vec<String> = dist.platforms.clone();
if !targets.iter().any(|t| t.contains("linux")) {
warnings.push(
"distribution.platforms lists no Linux target — the cross-platform install \
requirement (macOS AND Linux) is not met; add an '…-unknown-linux-musl' triple"
.to_string(),
);
}
let mut installers: Vec<String> = Vec::new();
let mut excluded_homebrew = false;
for installer in &dist.installers {
let name = match installer {
Installer::Homebrew => {
excluded_homebrew = true;
continue;
}
Installer::Shell => Installer::Shell.as_str(),
Installer::Powershell => Installer::Powershell.as_str(),
Installer::Msi => Installer::Msi.as_str(),
Installer::Npm => Installer::Npm.as_str(),
};
if !installers.iter().any(|s| s == name) {
installers.push(name.to_string());
}
}
if excluded_homebrew {
warnings.push(
"the 'homebrew' installer is published by ossctl's Homebrew tap adapter (post-tag, \
once the release tarball sha256 exists), not cargo-dist — it is excluded from [dist] \
installers, mirroring ossctl's own dist-workspace.toml"
.to_string(),
);
}
let shell = Installer::Shell.as_str().to_string();
if !installers.contains(&shell) {
installers.insert(0, shell);
warnings.push(
"added the 'shell' installer so the generated curl-installer covers macOS and Linux \
(the Unix cross-platform install path)"
.to_string(),
);
}
let toml = render_toml(&targets, &installers);
GeneratedDistConfig {
toml,
targets,
installers,
cargo_dist_version: PINNED_CARGO_DIST_VERSION,
warnings,
}
}
fn render_toml(targets: &[String], installers: &[String]) -> String {
let mut out = String::new();
out.push_str(
"# Generated by `ossctl dist generate` from OSS-RELEASE.md `distribution`.\n\
# Edit distribution.* in OSS-RELEASE.md, then re-run `ossctl dist generate`.\n\
# The tag-triggered `.github/workflows/release.yml` is produced from the\n\
# [dist] section below via `dist generate` — never hand-edit the workflow.\n\
[workspace]\n\
members = [\"cargo:.\"]\n\
\n\
[dist]\n",
);
let _ = writeln!(out, "cargo-dist-version = \"{PINNED_CARGO_DIST_VERSION}\"");
out.push_str("ci = \"github\"\n");
let _ = writeln!(out, "installers = {}", inline_string_array(installers));
out.push_str("targets = [\n");
for target in targets {
let _ = writeln!(out, " {},", toml_basic_string(target));
}
out.push_str("]\n");
out.push_str("hosting = \"github\"\n");
out.push_str("github-attestations = true\n");
out.push_str("pr-run-mode = \"skip\"\n");
out
}
fn inline_string_array(items: &[String]) -> String {
let quoted: Vec<String> = items.iter().map(|s| toml_basic_string(s)).collect();
format!("[{}]", quoted.join(", "))
}
fn toml_basic_string(value: &str) -> String {
let mut out = String::with_capacity(value.len() + 2);
out.push('"');
for ch in value.chars() {
match ch {
'"' => out.push_str("\\\""),
'\\' => out.push_str("\\\\"),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if c.is_control() => {
let _ = write!(out, "\\u{:04X}", c as u32);
}
c => out.push(c),
}
}
out.push('"');
out
}
#[cfg(test)]
mod tests;