Skip to content

Commit

Permalink
[cargo-nextest] pass in --filter-platform to cargo metadata
Browse files Browse the repository at this point in the history
This ensures that unnecessary dependencies aren't fetched.
  • Loading branch information
sunshowers committed Apr 23, 2024
1 parent ad82b4b commit df0dc20
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 7 deletions.
6 changes: 6 additions & 0 deletions cargo-nextest/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,7 @@ impl BaseApp {
manifest_path.as_deref(),
cargo_opts.target_dir.as_deref(),
&cargo_opts,
&build_platforms,
output,
)?;
let graph = PackageGraph::from_json(&json)
Expand Down Expand Up @@ -1889,11 +1890,16 @@ fn acquire_graph_data(
manifest_path: Option<&Utf8Path>,
target_dir: Option<&Utf8Path>,
cargo_opts: &CargoOptions,
build_platforms: &BuildPlatforms,
output: OutputContext,
) -> Result<String> {
let cargo_target_arg = build_platforms.to_cargo_target_arg()?;
let cargo_target_arg_str = cargo_target_arg.to_string();

let mut cargo_cli = CargoCli::new("metadata", manifest_path, output);
cargo_cli
.add_args(["--format-version=1", "--all-features"])
.add_args(["--filter-platform", &cargo_target_arg_str])
.add_generic_cargo_options(cargo_opts);

// We used to be able to pass in --no-deps in common cases, but that was (a) error-prone and (b)
Expand Down
10 changes: 10 additions & 0 deletions cargo-nextest/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ pub enum ExpectedError {
#[from]
err: UnknownHostPlatform,
},
#[error("target triple error")]
TargetTripleError {
#[from]
err: TargetTripleError,
},
#[error("metadata materialize error")]
MetadataMaterializeError {
arg_name: &'static str,
Expand Down Expand Up @@ -361,6 +366,7 @@ impl ExpectedError {
| Self::CargoConfigError { .. }
| Self::TestFilterBuilderError { .. }
| Self::UnknownHostPlatform { .. }
| Self::TargetTripleError { .. }
| Self::MetadataMaterializeError { .. }
| Self::UnknownArchiveFormat { .. }
| Self::ArchiveExtractError { .. }
Expand Down Expand Up @@ -603,6 +609,10 @@ impl ExpectedError {
log::error!("the host platform was unknown to nextest");
Some(err as &dyn Error)
}
Self::TargetTripleError { err } => {
log::error!("{err}");
err.source()

Check warning on line 614 in cargo-nextest/src/errors.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/errors.rs#L612-L614

Added lines #L612 - L614 were not covered by tests
}
Self::MetadataMaterializeError { arg_name, err } => {

Check warning on line 616 in cargo-nextest/src/errors.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/errors.rs#L616

Added line #L616 was not covered by tests
log::error!(
"error reading metadata from argument {}",
Expand Down
93 changes: 87 additions & 6 deletions nextest-runner/src/cargo_config/target_triple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
errors::TargetTripleError,
};
use camino::{Utf8Path, Utf8PathBuf};
use camino_tempfile::NamedUtf8TempFile;
use std::fmt;
use target_spec::{summaries::PlatformSummary, Platform, TargetFeatures};

Expand Down Expand Up @@ -49,10 +50,14 @@ impl TargetTriple {
platform: Option<PlatformSummary>,
) -> Result<Option<TargetTriple>, target_spec::Error> {
platform
.map(|platform| {
let platform = platform.to_platform()?;
.map(|summary| {
let platform = summary.to_platform()?;
let location = if platform.is_custom() {
TargetDefinitionLocation::MetadataCustom
TargetDefinitionLocation::MetadataCustom(
summary
.custom_json
.expect("custom platform <=> custom JSON"),
)

Check warning on line 60 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L56-L60

Added lines #L56 - L60 were not covered by tests
} else {
TargetDefinitionLocation::Builtin
};
Expand Down Expand Up @@ -80,6 +85,26 @@ impl TargetTriple {
.transpose()
}

/// Returns the target triple being built as a string to pass into downstream Cargo arguments,
/// such as `cargo metadata --filter-platform`.
///
/// For custom target triples, this will be a path to a file ending with `.json`. Nextest may
/// temporarily extract the target triple, in which case a `Utf8TempFile` is returned.
pub fn to_cargo_target_arg(&self) -> Result<CargoTargetArg, TargetTripleError> {
match &self.location {
TargetDefinitionLocation::Builtin | TargetDefinitionLocation::Heuristic => Ok(
CargoTargetArg::Builtin(self.platform.triple_str().to_string()),
),
TargetDefinitionLocation::DirectPath(path)
| TargetDefinitionLocation::RustTargetPath(path) => {
Ok(CargoTargetArg::Path(path.clone()))

Check warning on line 100 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L98-L100

Added lines #L98 - L100 were not covered by tests
}
TargetDefinitionLocation::MetadataCustom(json) => {
CargoTargetArg::from_custom_json(json, self.source.clone())

Check warning on line 103 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L102-L103

Added lines #L102 - L103 were not covered by tests
}
}
}

/// Find the target triple being built.
///
/// This does so by looking at, in order:
Expand Down Expand Up @@ -273,6 +298,62 @@ impl TargetTriple {
}
}

/// Cargo argument for downstream commands.
///
/// If it is necessary to run a Cargo command with a target triple, this enum provides the right
/// invocation. Create it with [`TargetTriple::to_cargo_target_arg`].
#[derive(Debug)]
pub enum CargoTargetArg {
/// The target triple is a builtin.
Builtin(String),

/// The target triple is a JSON file at this path.
Path(Utf8PathBuf),

/// The target triple is a temporary JSON file.
TempFile(NamedUtf8TempFile),
}

impl CargoTargetArg {
fn from_custom_json(json: &str, source: TargetTripleSource) -> Result<Self, TargetTripleError> {

Check warning on line 318 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L318

Added line #L318 was not covered by tests
// Extract the JSON to a temporary file. Cargo requires that the file name end with `.json`.
let f = camino_tempfile::Builder::new()
.prefix("nextest-custom-target-")
.suffix(".json")
.rand_bytes(5)
.tempfile()
.map_err(|error| TargetTripleError::CustomPlatformTempFileError {
source: source.clone(),
error,
})?;
std::fs::write(f.path(), json).map_err(|error| {
TargetTripleError::CustomPlatformWriteError {
source,
path: f.path().to_owned(),
error,
}
})?;

Check warning on line 335 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L320-L335

Added lines #L320 - L335 were not covered by tests

Ok(Self::TempFile(f))
}

Check warning on line 338 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L337-L338

Added lines #L337 - L338 were not covered by tests
}

impl fmt::Display for CargoTargetArg {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Builtin(triple) => {
write!(f, "{triple}")
}
Self::Path(path) => {
write!(f, "{path}")

Check warning on line 348 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L347-L348

Added lines #L347 - L348 were not covered by tests
}
Self::TempFile(file) => {
write!(f, "{}", file.path())

Check warning on line 351 in nextest-runner/src/cargo_config/target_triple.rs

View check run for this annotation

Codecov / codecov/patch

nextest-runner/src/cargo_config/target_triple.rs#L350-L351

Added lines #L350 - L351 were not covered by tests
}
}
}
}

/// The place where a target triple's configuration was picked up from.
///
/// This is the type of [`TargetTriple::source`].
Expand Down Expand Up @@ -338,8 +419,8 @@ pub enum TargetDefinitionLocation {
/// The definition was obtained heuristically.
Heuristic,

/// A custom definition was stored in metadata.
MetadataCustom,
/// A custom definition was stored in metadata. The string is the JSON of the custom target.
MetadataCustom(String),
}

impl fmt::Display for TargetDefinitionLocation {
Expand All @@ -357,7 +438,7 @@ impl fmt::Display for TargetDefinitionLocation {
Self::Heuristic => {
write!(f, "definition obtained heuristically")
}
Self::MetadataCustom => {
Self::MetadataCustom(_) => {
write!(f, "custom definition stored in metadata")
}
}
Expand Down
31 changes: 31 additions & 0 deletions nextest-runner/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,37 @@ pub enum TargetTripleError {
#[source]
error: std::io::Error,
},

/// Failed to create a temporary file for a custom platform.
#[error(
"for custom platform obtained from {source}, \
failed to create temporary file for custom platform"
)]
CustomPlatformTempFileError {
/// The source of the target triple.
source: TargetTripleSource,

/// The error that occurred during the create.
#[source]
error: std::io::Error,
},

/// Failed to write a custom platform to disk.
#[error(
"for custom platform obtained from {source}, \
failed to write JSON to temporary path `{path}`"
)]
CustomPlatformWriteError {
/// The source of the target triple.
source: TargetTripleSource,

/// The path that we tried to write to.
path: Utf8PathBuf,

/// The error that occurred during the write.
#[source]
error: std::io::Error,
},
}

/// An error occurred determining the target runner
Expand Down
16 changes: 15 additions & 1 deletion nextest-runner/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

//! Platform-related data structures.
use crate::{cargo_config::TargetTriple, errors::UnknownHostPlatform};
use crate::{
cargo_config::{CargoTargetArg, TargetTriple},
errors::{TargetTripleError, UnknownHostPlatform},
};
pub use target_spec::Platform;

/// A representation of host and target platforms.
Expand Down Expand Up @@ -34,4 +37,15 @@ impl BuildPlatforms {
pub fn new_with_host(host: Platform, target: Option<TargetTriple>) -> Self {
Self { host, target }
}

/// Returns the argument to pass into `cargo metadata --filter-platform <triple>`.
pub fn to_cargo_target_arg(&self) -> Result<CargoTargetArg, TargetTripleError> {
match &self.target {
Some(target) => target.to_cargo_target_arg(),
None => {
// If there's no target, use the host platform.
Ok(CargoTargetArg::Builtin(self.host.triple_str().to_owned()))
}
}
}
}

0 comments on commit df0dc20

Please sign in to comment.