use anyhow::{Context as _, Result};
use crate::context::Context;
use crate::target::map_target;
pub const DEFAULT_NAME_TEMPLATE: &str = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{% if Arm %}v{{ Arm }}{% endif %}{% if Mips %}_{{ Mips }}{% endif %}{% if Amd64 and Amd64 != \"v1\" %}{{ Amd64 }}{% endif %}";
pub const DEFAULT_NAME_TEMPLATE_MULTI_CRATE: &str = DEFAULT_NAME_TEMPLATE;
pub const DEFAULT_BINARY_NAME_TEMPLATE: &str = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{% if Arm %}v{{ Arm }}{% endif %}{% if Mips %}_{{ Mips }}{% endif %}{% if Amd64 and Amd64 != \"v1\" %}{{ Amd64 }}{% endif %}";
pub const MICRO_ARCH_VARIANT_SUFFIX: &str = "{% if Arm %}v{{ Arm }}{% endif %}{% if Mips %}_{{ Mips }}{% endif %}{% if Amd64 and Amd64 != \"v1\" %}{{ Amd64 }}{% endif %}";
pub const INSTALLER_AMD64_VARIANT_SUFFIX: &str =
"{% if Amd64 and Amd64 != \"v1\" %}{{ Amd64 }}{% endif %}";
pub fn seed_target_vars(ctx: &mut Context, target: &str) {
let (os, arch) = map_target(target);
let vars = ctx.template_vars_mut();
vars.set("Os", &os);
vars.set("Target", target);
vars.set("Arm", "");
vars.set("Arm64", "");
vars.set("Amd64", "");
vars.set("Mips", "");
vars.set("I386", "");
if let Some(version) = arch.strip_prefix("armv") {
vars.set("Arch", "arm");
vars.set("Arm", version);
} else {
vars.set("Arch", &arch);
}
}
pub fn seed_amd64_variant_var(
vars: &mut crate::template::TemplateVars,
amd64_variant: Option<&str>,
) {
vars.set("Amd64", amd64_variant.unwrap_or(""));
}
pub fn render_archive_stem(ctx: &mut Context, name_template: &str, target: &str) -> Result<String> {
seed_target_vars(ctx, target);
ctx.render_template(name_template)
.with_context(|| format!("render archive name template for target '{target}'"))
}
pub fn render_archive_asset_name(
ctx: &mut Context,
name_template: &str,
target: &str,
format: &str,
) -> Result<String> {
let stem = render_archive_stem(ctx, name_template, target)?;
Ok(format!("{stem}.{format}"))
}
pub fn binstall_pkg_fmt(format: &str) -> Option<&'static str> {
match format {
"tar.gz" | "tgz" => Some("tgz"),
"tar.xz" | "txz" => Some("txz"),
"tar.zst" | "tzst" => Some("tzstd"),
"tar.bz2" | "tbz2" => Some("tbz2"),
"tar" => Some("tar"),
"zip" => Some("zip"),
"bin" => Some("bin"),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::context::{Context, ContextOptions};
fn ctx() -> Context {
let config = Config {
project_name: "anodizer".to_string(),
..Default::default()
};
let mut ctx = Context::new(config, ContextOptions::default());
ctx.template_vars_mut().set("ProjectName", "anodizer");
ctx.template_vars_mut().set("Version", "1.2.3");
ctx
}
#[test]
fn seeds_os_arch_target() {
let mut c = ctx();
seed_target_vars(&mut c, "x86_64-unknown-linux-gnu");
assert_eq!(c.template_vars().get("Os").unwrap(), "linux");
assert_eq!(c.template_vars().get("Arch").unwrap(), "amd64");
assert_eq!(
c.template_vars().get("Target").unwrap(),
"x86_64-unknown-linux-gnu"
);
assert_eq!(c.template_vars().get("Amd64").unwrap(), "");
assert_eq!(c.template_vars().get("Arm").unwrap(), "");
}
#[test]
fn armv7_splits_arch_and_arm() {
let mut c = ctx();
seed_target_vars(&mut c, "armv7-unknown-linux-gnueabihf");
assert_eq!(c.template_vars().get("Arch").unwrap(), "arm");
assert_eq!(c.template_vars().get("Arm").unwrap(), "7");
assert_eq!(c.template_vars().get("Amd64").unwrap(), "");
}
#[test]
fn mips_carries_no_variant_suffix() {
let mut c = ctx();
seed_target_vars(&mut c, "mips-unknown-linux-gnu");
assert_eq!(c.template_vars().get("Arch").unwrap(), "mips");
assert_eq!(c.template_vars().get("Mips").unwrap(), "");
}
#[test]
fn variant_vars_reset_between_targets() {
let mut c = ctx();
seed_target_vars(&mut c, "armv7-unknown-linux-gnueabihf");
assert_eq!(c.template_vars().get("Arm").unwrap(), "7");
seed_target_vars(&mut c, "x86_64-unknown-linux-gnu");
assert_eq!(c.template_vars().get("Arm").unwrap(), "");
assert_eq!(c.template_vars().get("Arch").unwrap(), "amd64");
}
#[test]
fn default_template_renders_goreleaser_stem() {
let mut c = ctx();
let stem =
render_archive_stem(&mut c, DEFAULT_NAME_TEMPLATE, "aarch64-apple-darwin").unwrap();
assert_eq!(stem, "anodizer_1.2.3_darwin_arm64");
}
#[test]
fn custom_template_renders_with_format_ext() {
let mut c = ctx();
let name = render_archive_asset_name(
&mut c,
"{{ ProjectName }}-{{ Version }}-{{ Os }}-{{ Arch }}",
"x86_64-pc-windows-msvc",
"zip",
)
.unwrap();
assert_eq!(name, "anodizer-1.2.3-windows-amd64.zip");
}
#[test]
fn default_template_byte_identical_to_head_for_every_arch() {
let cases: &[(&str, &str)] = &[
(
"armv7-unknown-linux-gnueabihf",
"anodizer_1.2.3_linux_armv7",
),
(
"armv6-unknown-linux-gnueabihf",
"anodizer_1.2.3_linux_armv6",
),
("mips-unknown-linux-gnu", "anodizer_1.2.3_linux_mips"),
("mipsel-unknown-linux-gnu", "anodizer_1.2.3_linux_mipsel"),
(
"mips64-unknown-linux-gnuabi64",
"anodizer_1.2.3_linux_mips64",
),
(
"mips64el-unknown-linux-gnuabi64",
"anodizer_1.2.3_linux_mips64el",
),
("i686-unknown-linux-gnu", "anodizer_1.2.3_linux_386"),
("x86_64-unknown-linux-gnu", "anodizer_1.2.3_linux_amd64"),
("aarch64-unknown-linux-gnu", "anodizer_1.2.3_linux_arm64"),
("x86_64-apple-darwin", "anodizer_1.2.3_darwin_amd64"),
("aarch64-apple-darwin", "anodizer_1.2.3_darwin_arm64"),
("x86_64-pc-windows-msvc", "anodizer_1.2.3_windows_amd64"),
("aarch64-pc-windows-msvc", "anodizer_1.2.3_windows_arm64"),
];
for (target, expected) in cases {
let mut c = ctx();
let stem = render_archive_stem(&mut c, DEFAULT_NAME_TEMPLATE, target).unwrap();
assert_eq!(
&stem, expected,
"default-template asset stem for {target} must match HEAD"
);
}
}
#[test]
fn new_seeding_equals_head_seeding_per_target() {
let targets = [
"armv7-unknown-linux-gnueabihf",
"armv6-unknown-linux-gnueabihf",
"mips-unknown-linux-gnu",
"mipsel-unknown-linux-gnu",
"mips64-unknown-linux-gnuabi64",
"i686-unknown-linux-gnu",
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"aarch64-apple-darwin",
"x86_64-pc-windows-msvc",
"aarch64-pc-windows-msvc",
];
for target in targets {
let (os, arch) = crate::target::map_target(target);
let mut head = ctx();
{
let v = head.template_vars_mut();
v.set("Os", &os);
v.set("Arch", &arch);
v.set("Target", target);
v.set("Arm", "");
v.set("Arm64", "");
v.set("Amd64", "");
v.set("Mips", "");
v.set("I386", "");
}
let head_stem = head.render_template(DEFAULT_NAME_TEMPLATE).unwrap();
let mut new = ctx();
let new_stem = render_archive_stem(&mut new, DEFAULT_NAME_TEMPLATE, target).unwrap();
assert_eq!(
head_stem, new_stem,
"new seed_target_vars must be byte-identical to HEAD for {target}"
);
}
}
#[test]
fn archive_defaults_end_with_full_micro_arch_suffix() {
assert!(DEFAULT_NAME_TEMPLATE.ends_with(MICRO_ARCH_VARIANT_SUFFIX));
assert!(DEFAULT_BINARY_NAME_TEMPLATE.ends_with(MICRO_ARCH_VARIANT_SUFFIX));
}
#[test]
fn installer_amd64_suffix_is_the_tail_of_the_full_suffix() {
assert!(MICRO_ARCH_VARIANT_SUFFIX.ends_with(INSTALLER_AMD64_VARIANT_SUFFIX));
}
#[test]
fn pkg_fmt_maps_known_formats() {
assert_eq!(binstall_pkg_fmt("tar.gz"), Some("tgz"));
assert_eq!(binstall_pkg_fmt("zip"), Some("zip"));
assert_eq!(binstall_pkg_fmt("tar.xz"), Some("txz"));
assert_eq!(binstall_pkg_fmt("binary"), None);
assert_eq!(binstall_pkg_fmt("none"), None);
}
}