diff --git a/.changes/1491.json b/.changes/1491.json index 8ac3fc67a..b0cd7b98e 100644 --- a/.changes/1491.json +++ b/.changes/1491.json @@ -1,5 +1,5 @@ { - "description": "Allow specifying only a tag for images in config", + "description": "Allow specifying only a tag or subtarget for images in config", "issues": [1169], "type": "changed" } diff --git a/Cargo.toml b/Cargo.toml index d87376ffb..e8a10ae4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,6 +86,12 @@ search = "" replace = "\n\n[Unreleased]: https://github.com/cross-rs/{{crate_name}}/compare/v{{version}}...HEAD" exactly = 1 +[[package.metadata.release.pre-release-replacements]] +file = "docs/config_file.md" +search = "(# Translates to `.*?:).*?(-centos`)" +replace = "${1}{{version}}$2" +exactly = 1 + [package.metadata.binstall] pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }.tar.gz" bin-dir = "{ bin }{ binary-ext }" diff --git a/docs/config_file.md b/docs/config_file.md index 451575e89..be67ee1f2 100644 --- a/docs/config_file.md +++ b/docs/config_file.md @@ -234,6 +234,14 @@ image = ":edge" image = "@sha256:77db671d8356a64ae72a3e1415e63f547f26d374fbe3c4762c1cd36c7eac7b99" ``` +You can also specify a subtarget with no tag nor image name: + +```toml +[target.x86_64-unknown-linux-gnu] +# Translates to `ghcr.io/cross-rs/x86_64-unknown-linux-gnu:0.3.0-centos` +image = "-centos" +``` + The `image` key can also take the toolchains/platforms supported by the image: ```toml diff --git a/src/docker/image.rs b/src/docker/image.rs index e88fa5797..3d3c15bca 100644 --- a/src/docker/image.rs +++ b/src/docker/image.rs @@ -2,7 +2,12 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; -use crate::{errors::*, shell::MessageInfo, TargetTriple}; +use crate::{ + docker::{CROSS_IMAGE, DEFAULT_IMAGE_VERSION}, + errors::*, + shell::MessageInfo, + TargetTriple, +}; use super::Engine; @@ -114,6 +119,8 @@ pub enum ImageReference { Name(String), /// Unqualified reference, only a tag or digest Identifier(String), + /// Unqualified reference, only a subtarget + Subtarget(String), } impl ImageReference { @@ -121,13 +128,30 @@ impl ImageReference { match self { Self::Name(s) => s, Self::Identifier(s) => s, + Self::Subtarget(s) => s, } } + + pub fn ensure_qualified(&mut self, target_name: &str) { + let image_name = match self { + Self::Name(_) => return, + Self::Identifier(id) => { + format!("{CROSS_IMAGE}/{target_name}{id}") + } + Self::Subtarget(sub) => { + format!("{CROSS_IMAGE}/{target_name}:{DEFAULT_IMAGE_VERSION}{sub}") + } + }; + + *self = Self::Name(image_name); + } } impl From for ImageReference { fn from(s: String) -> Self { - if s.starts_with(':') || s.starts_with('@') { + if s.starts_with('-') { + Self::Subtarget(s) + } else if s.starts_with(':') || s.starts_with('@') { Self::Identifier(s) } else { Self::Name(s) diff --git a/src/docker/shared.rs b/src/docker/shared.rs index 3f116cb35..4a1c56f89 100644 --- a/src/docker/shared.rs +++ b/src/docker/shared.rs @@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::{env, fs, time}; use super::custom::{Dockerfile, PreBuild}; -use super::image::{ImageReference, PossibleImage}; +use super::image::PossibleImage; use super::Image; use super::PROVIDED_IMAGES; use super::{engine::*, ProvidedImage}; @@ -1252,10 +1252,8 @@ fn get_user_image( } if let Some(image) = &mut image { - if let ImageReference::Identifier(id) = &image.reference { - let target_name = get_target_name(target, uses_zig); - image.reference = ImageReference::Name(format!("{CROSS_IMAGE}/{target_name}{id}")); - } + let target_name = get_target_name(target, uses_zig); + image.reference.ensure_qualified(target_name); } Ok(image) @@ -1633,6 +1631,10 @@ mod tests { let mut map = HashMap::new(); test(map.clone(), &default_ver, &default_ver)?; + map.insert("CROSS_TARGET_X86_64_UNKNOWN_LINUX_GNU_IMAGE", "-centos"); + let centos_tag = format!("{default_ver}-centos"); + test(map.clone(), ¢os_tag, ¢os_tag)?; + map.insert("CROSS_TARGET_X86_64_UNKNOWN_LINUX_GNU_IMAGE", ":edge"); test(map.clone(), ":edge", ":edge")?;