Skip to content

Commit

Permalink
output configured targets
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed Apr 3, 2023
1 parent bb3df1b commit 4e9e6ca
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 4 deletions.
131 changes: 131 additions & 0 deletions src/bin/commands/list_targets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use std::str::FromStr;

use clap::Args;
use cross::docker;
use cross::shell::MessageInfo;

#[derive(Args, Debug)]
pub struct ListTargets {
/// Format version
#[clap(long)]
format_version: Option<FormatVersion>,
/// Coloring: auto, always, never
#[clap(long)]
pub color: Option<String>,
}

#[derive(Debug, Clone, Copy, serde::Serialize)]
pub enum FormatVersion {
#[serde(rename = "1")]
One,
}

#[derive(Debug, thiserror::Error)]
#[error("invalid format version")]
pub struct FormatVersionError;

impl FromStr for FormatVersion {
type Err = FormatVersionError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"1" => Ok(FormatVersion::One),
_ => Err(FormatVersionError),
}
}
}

#[derive(serde::Serialize)]
pub struct Output {
format_version: FormatVersion,
#[serde(flatten)]
other: serde_json::Value,
}

impl ListTargets {
pub fn verbose(&self) -> bool {
false
}

pub fn quiet(&self) -> bool {
false
}

pub fn color(&self) -> Option<&str> {
self.color.as_deref()
}

pub fn run(self, msg_info: &mut MessageInfo) -> cross::Result<()> {
let toml = if let Some(metadata) = cross::cargo_metadata_with_args(None, None, msg_info)? {
cross::toml(&metadata, msg_info)?
} else {
None
};

let config = cross::config::Config::new(toml);
let version = if let Some(version) = self.format_version {
version
} else {
msg_info.warn(
"please specify `--format-version` flag explicitly to avoid compatibility problems",
)?;
FormatVersion::One
};
let data = match version {
FormatVersion::One => self.run_v1(&config, msg_info)?,
};
println!(
"{}",
serde_json::to_string_pretty(&Output {
format_version: version,
other: data,
})?
);
Ok(())
}

pub fn run_v1(
self,
config: &cross::config::Config,
_msg_info: &mut MessageInfo,
) -> cross::Result<serde_json::Value> {
#[derive(serde::Serialize)]
struct Target {
triplet: String,
platforms: Vec<String>,
}
let mut targets: Vec<_> = cross::docker::PROVIDED_IMAGES
.iter()
.filter_map(|i| {
Some(Target {
triplet: Some(i.name).filter(|i| *i != "zig")?.to_owned(),
platforms: i.platforms.iter().map(ToString::to_string).collect(),
})
})
.collect();
if let Some(toml_targets) = config.targets() {
for (target, config) in toml_targets {
if targets.iter().any(|t| t.triplet == target.triple()) {
continue;
}
targets.push(Target {
triplet: target.triple().to_owned(),
platforms: config
.image
.as_ref()
.map(|i| {
i.toolchain
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
})
.filter(|v| !v.is_empty())
.unwrap_or_else(|| vec![docker::ImagePlatform::DEFAULT.to_string()]),
})
}
}
Ok(serde_json::json!({
"targets": targets,
}))
}
}
2 changes: 2 additions & 0 deletions src/bin/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod clean;
mod containers;
mod images;
mod list_targets;

pub use self::clean::*;
pub use self::containers::*;
pub use self::images::*;
pub use self::list_targets::*;
6 changes: 6 additions & 0 deletions src/bin/cross-util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ enum Commands {
Containers(commands::Containers),
/// Clean all cross data in local storage.
Clean(commands::Clean),
/// List all cross targets, including those specialized for the current project (if in one).
ListTargets(commands::ListTargets),
}

fn is_toolchain(toolchain: &str) -> cross::Result<Toolchain> {
Expand Down Expand Up @@ -103,6 +105,10 @@ pub fn main() -> cross::Result<()> {
let engine = get_engine!(args, false, msg_info)?;
args.run(engine, &mut msg_info)?;
}
Commands::ListTargets(args) => {
let mut msg_info = get_msg_info!(args)?;
args.run(&mut msg_info)?;
}
}

Ok(())
Expand Down
7 changes: 7 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,13 @@ impl Config {
}
}

/// Grabs all defined targets in toml
pub fn targets(
&self,
) -> Option<impl Iterator<Item = (&Target, &crate::cross_toml::CrossTargetConfig)>> {
self.toml.as_ref().map(|toml| toml.targets.iter())
}

pub fn confusable_target(&self, target: &Target, msg_info: &mut MessageInfo) -> Result<()> {
if let Some(keys) = self.toml.as_ref().map(|t| t.targets.keys()) {
for mentioned_target in keys {
Expand Down
2 changes: 1 addition & 1 deletion src/cross_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub struct CrossTargetConfig {
#[serde(default, deserialize_with = "opt_string_bool_or_struct")]
zig: Option<CrossZigConfig>,
#[serde(default, deserialize_with = "opt_string_or_struct")]
image: Option<PossibleImage>,
pub image: Option<PossibleImage>,
#[serde(default, deserialize_with = "opt_string_or_struct")]
dockerfile: Option<CrossTargetDockerfileConfig>,
#[serde(default, deserialize_with = "opt_string_or_string_vec")]
Expand Down
6 changes: 6 additions & 0 deletions src/docker/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ impl Serialize for ImagePlatform {
}
}

impl std::fmt::Display for ImagePlatform {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.serialize(f)
}
}

impl std::str::FromStr for ImagePlatform {
type Err = eyre::Report;
// [os/arch[/variant]=]toolchain
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,13 @@ impl Target {
triple: TargetTriple::DEFAULT,
};

fn new_built_in(triple: &str) -> Self {
pub fn new_built_in(triple: &str) -> Self {
Target::BuiltIn {
triple: triple.into(),
}
}

fn new_custom(triple: &str) -> Self {
pub fn new_custom(triple: &str) -> Self {
Target::Custom {
triple: triple.into(),
}
Expand Down Expand Up @@ -861,7 +861,7 @@ macro_rules! commit_info {
///
/// The values from `CROSS_CONFIG` or `Cross.toml` are concatenated with the package
/// metadata in `Cargo.toml`, with `Cross.toml` having the highest priority.
fn toml(metadata: &CargoMetadata, msg_info: &mut MessageInfo) -> Result<Option<CrossToml>> {
pub fn toml(metadata: &CargoMetadata, msg_info: &mut MessageInfo) -> Result<Option<CrossToml>> {
let root = &metadata.workspace_root;
let cross_config_path = match env::var("CROSS_CONFIG") {
Ok(var) => PathBuf::from(var),
Expand Down

0 comments on commit 4e9e6ca

Please sign in to comment.