From 472da1c2dbd52d21807f53ff4c46b9c145d9569c Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 8 Aug 2021 02:50:46 +0900 Subject: [PATCH] Support trybuild --- Cargo.toml | 1 + src/fs.rs | 11 +++++++++++ src/main.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 626816c6..b424f9f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ rustc-demangle = "0.1.19" serde = { version = "1.0.103", features = ["derive"] } serde_json = "1" shell-escape = "0.1.5" +toml = "0.5.2" tracing = { version = "0.1.21", default-features = false, features = ["std"] } tracing-subscriber = { version = "0.2.16", default-features = false, features = ["ansi", "env-filter"] } walkdir = "2" diff --git a/src/fs.rs b/src/fs.rs index ead2ecf2..9cea8c45 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -1,5 +1,6 @@ #![cfg_attr(test, allow(dead_code))] +pub(crate) use std::fs::ReadDir; use std::{io, path::Path}; use anyhow::{Context as _, Result}; @@ -81,3 +82,13 @@ pub(crate) fn read_to_string(path: impl AsRef) -> Result { trace!(track_caller: ?res, ?path, "read_to_string"); res.with_context(|| format!("failed to read from file `{}`", path.display())) } + +/// Returns an iterator over the entries within a directory. +/// This is a wrapper for [`std::fs::read_dir`]. +#[track_caller] +pub(crate) fn read_dir(path: impl AsRef) -> Result { + let path = path.as_ref(); + let res = std::fs::read_dir(path); + trace!(track_caller: ?res, ?path, "read_dir"); + res.with_context(|| format!("failed to read directory `{}`", path.display())) +} diff --git a/src/main.rs b/src/main.rs index 3158d64f..ee42e26c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,6 +24,7 @@ use std::{ }; use anyhow::Result; +use regex::Regex; use serde::Deserialize; use tracing::warn; use walkdir::WalkDir; @@ -167,6 +168,43 @@ fn object_files(cx: &Context) -> Result> { } } } + + // trybuild + let trybuild_dir = &cx.metadata.target_directory.join("tests"); + let mut trybuild_target = trybuild_dir.join("target"); + if let Some(target) = &cx.target { + trybuild_target.push(target); + } + trybuild_target.push("debug"); + if trybuild_target.is_dir() { + let mut trybuild_projects = vec![]; + for entry in fs::read_dir(trybuild_dir)?.filter_map(Result::ok) { + let manifest_path = entry.path().join("Cargo.toml"); + if !manifest_path.is_file() { + continue; + } + let manifest: Manifest = toml::from_str(&fs::read_to_string(manifest_path)?)?; + trybuild_projects.push(manifest.package.name); + } + if !trybuild_projects.is_empty() { + let re = + Regex::new(&format!("^({})-[0-9A-Fa-f]+$", trybuild_projects.join("|"))).unwrap(); + for entry in WalkDir::new(trybuild_target).into_iter().filter_map(Result::ok) { + let path = entry.path(); + if let Some(path) = path.file_name().unwrap().to_str() { + if re.is_match(path) { + // Excludes dummy binaries generated by trybuild. + // https://github.com/dtolnay/trybuild/blob/54ddc67c9e2f236d44ac6640a2327e178ff6ae68/src/run.rs#L228-L231 + continue; + } + } + if is_executable::is_executable(path) { + files.push(path.to_owned().into_os_string()); + } + } + } + } + // This sort is necessary to make the result of `llvm-cov show` match between macos and linux. files.sort_unstable(); trace!(object_files = ?files); @@ -338,6 +376,18 @@ struct Profile { test: bool, } +// Cargo manifest +// https://doc.rust-lang.org/cargo/reference/manifest.html +#[derive(Debug, Deserialize)] +struct Manifest { + package: Package, +} + +#[derive(Debug, Deserialize)] +struct Package { + name: String, +} + fn append_args(cx: &Context, cmd: &mut ProcessBuilder) { if cx.no_fail_fast { cmd.arg("--no-fail-fast");