Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output configured targets #1240

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>,
Comment on lines +9 to +11
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this kind of stability?

/// Coloring: auto, always, never
#[clap(long)]
pub color: Option<String>,
}
Comment on lines +7 to +15
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should there be a way to only output targets in toml config? Maybe that could be data included in the output?


#[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(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a nice usage of try trait :D

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
triplet: Some(i.name).filter(|i| *i != "zig")?.to_owned(),
triplet: if *i.name != "zig" { i.name.to_owned() } else { return None },

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()]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

})
}
}
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