Skip to content
Permalink
Browse files

Auto merge of #406 - pietroalbini:detect-yanked, r=pietroalbini

Detect crates with yanked dependencies and mark them as broken

This PR removes yet another source of errors.
  • Loading branch information...
bors committed Mar 12, 2019
2 parents 6730b1a + d1aa2c9 commit 76f728ac55a010151a8cbe6deada86fadfee3cda
@@ -169,7 +169,7 @@ div.category div.crate > a {
}

div.category div.crate > span {
flex-basis: 10em;
flex-basis: 12em;
text-align: center;
}

@@ -834,7 +834,6 @@ cpal = { skip = true } #automatic
cplex-sys = { skip = true } #automatic
cppStream = { skip = true } #automatic
cpp_codegen = { skip = true } #automatic
cpp_demangle = { broken = true } # dependency yanked
cpp_to_rust = { skip = true } #automatic
cpp_to_rust_generator = { skip = true } #automatic
cpp_utils = { skip-tests = true } #automatic
@@ -3053,7 +3052,6 @@ multi-logger = { skip = true } #automatic
multiaddr = { skip-tests = true } #automatic
multiboot = { skip = true } #automatic
multidim = { skip = true } #automatic
multihash = { broken = true } # dependency yanked
multiinput = { skip = true } #automatic
multitooth = { skip = true } #automatic
must = { skip-tests = true } #automatic
@@ -3463,7 +3461,6 @@ pamsm = { skip = true } #automatic
pancurses = { skip = true } #automatic
pandoc_types = { skip-tests = true } #automatic
pango-sys = { skip-tests = true } #automatic
pangocairo = { broken = true } # dependency yanked
panic-abort = { skip = true } #automatic
panic-halt = { skip = true } #automatic
panic-itm = { skip = true } #automatic
@@ -3968,7 +3965,6 @@ reproto-manifest = { skip = true } #automatic
reproto-parser = { skip = true } #automatic
reproto-path-parser = { skip = true } #automatic
reproto-trans = { skip = true } #automatic
reql = { broken = true } # dependency yanked
reql-derive = { skip = true } #automatic
reql-io = { skip = true } #automatic
reqwest = { skip = true } #automatic
@@ -4133,7 +4129,6 @@ rui = { skip = true } #automatic
rules = { skip = true } #automatic
rulinalg = { skip-tests = true } #automatic
ruma-api = { skip = true } #automatic
ruma-signatures = { broken = true } # dependency yanked
rumo = { skip = true } #automatic
rumqtt = { skip = true } #automatic
run-or-raise = { skip = true } #automatic
@@ -4151,7 +4146,6 @@ runtime-loop = { skip-tests = true } #automatic
runtime-macros = { skip = true } #automatic
ruroonga = { skip = true } #automatic
rurust = { skip = true } #automatic
rusoto = { broken = true } # dependency yanked
rusoto_mock = { skip = true } #automatic
rusql = { skip = true } #automatic
rusqlcipher = { skip = true } #automatic
@@ -4363,7 +4357,6 @@ scoped_allocator = { skip = true } #automatic
scopeguard = { skip-tests = true } #automatic
score = { skip = true } #automatic
scout = { skip-tests = true } #automatic
scram = { broken = true } # dependency yanked
scram-tmp = { skip = true } #automatic
scrap = { skip = true } #automatic
scrapyard-core = { skip = true } #automatic
@@ -5559,7 +5552,6 @@ xmpp-rs = { skip = true } #automatic
xolehlp-sys = { skip = true } #automatic
xor-utils = { skip = true } #automatic
xor_name = { skip = true } #automatic
xoroshiro = { broken = true } # dependency yanked
xplm = { skip = true } #automatic
xpsprint-sys = { skip = true } #automatic
xpsupport = { skip = true } #automatic
@@ -0,0 +1,8 @@
[package]
name = "yanked-deps"
version = "0.1.0"
authors = ["Pietro Albini <pietro@pietroalbini.org>"]
edition = "2018"

[dependencies]
ring = "0.2"
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
@@ -2,7 +2,7 @@ use crate::assets;
use crate::experiments::Experiment;
use crate::prelude::*;
use crate::report::{archives::Archive, Comparison, CrateResult, ReportWriter, TestResults};
use crate::results::{EncodingType, FailureReason, TestResult};
use crate::results::{BrokenReason, EncodingType, FailureReason, TestResult};
use mime;
use minifier;
use std::collections::HashMap;
@@ -29,6 +29,7 @@ impl ResultColor for Comparison {
Comparison::SameTestSkipped => Color::Striped("#72a156", "#80b65f"),
Comparison::SameTestPass => Color::Single("#72a156"),
Comparison::Error => Color::Single("#d77026"),
Comparison::Broken => Color::Single("#44176e"),
Comparison::SpuriousRegressed => Color::Striped("#db3026", "#d5433b"),
Comparison::SpuriousFixed => Color::Striped("#5630db", "#5d3dcf"),
}
@@ -38,6 +39,7 @@ impl ResultColor for Comparison {
impl ResultColor for TestResult {
fn color(&self) -> Color {
match self {
TestResult::BrokenCrate(_) => Color::Single("#44176e"),
TestResult::BuildFail(_) => Color::Single("#db3026"),
TestResult::TestFail(_) => Color::Single("#65461e"),
TestResult::TestSkipped | TestResult::TestPass => Color::Single("#62a156"),
@@ -54,16 +56,26 @@ impl ResultName for FailureReason {
fn name(&self) -> String {
match self {
FailureReason::Unknown => "failed".into(),
FailureReason::Broken => "broken".into(),
FailureReason::Timeout => "timed out".into(),
FailureReason::OOM => "OOM".into(),
}
}
}

impl ResultName for BrokenReason {
fn name(&self) -> String {
match self {
BrokenReason::Unknown => "broken crate".into(),
BrokenReason::CargoToml => "broken Cargo.toml".into(),
BrokenReason::Yanked => "deps yanked".into(),
}
}
}

impl ResultName for TestResult {
fn name(&self) -> String {
match self {
TestResult::BrokenCrate(reason) => reason.name(),
TestResult::BuildFail(reason) => format!("build {}", reason.name()),
TestResult::TestFail(reason) => format!("test {}", reason.name()),
TestResult::TestSkipped => "test skipped".into(),
@@ -52,6 +52,7 @@ string_enum!(pub enum Comparison {
Skipped => "skipped",
Unknown => "unknown",
Error => "error",
Broken => "broken",
SameBuildFail => "build-fail",
SameTestFail => "test-fail",
SameTestSkipped => "test-skipped",
@@ -70,6 +71,7 @@ impl Comparison {
| Comparison::SpuriousRegressed
| Comparison::SpuriousFixed => true,
Comparison::Skipped
| Comparison::Broken
| Comparison::SameBuildFail
| Comparison::SameTestFail
| Comparison::SameTestSkipped
@@ -334,6 +336,7 @@ fn compare(
| (TestFail(_), BuildFail(_)) => Comparison::Regressed,

(Error, _) | (_, Error) => Comparison::Error,
(BrokenCrate(_), _) | (_, BrokenCrate(_)) => Comparison::Broken,
(TestFail(_), TestSkipped)
| (TestPass, TestSkipped)
| (TestSkipped, TestFail(_))
@@ -469,7 +472,7 @@ mod tests {
use crate::config::{Config, CrateConfig};
use crate::crates::{Crate, GitHubRepo, RegistryCrate};
use crate::experiments::{CapLints, Experiment, Mode, Status};
use crate::results::{DummyDB, FailureReason, TestResult};
use crate::results::{BrokenReason, DummyDB, FailureReason, TestResult};
use crate::toolchain::{MAIN_TOOLCHAIN, TEST_TOOLCHAIN};
use std::collections::HashMap;

@@ -623,6 +626,16 @@ mod tests {
TestSkipped, Error => Error;
TestFail(Unknown), Error => Error;
BuildFail(Unknown), Error => Error;

// Broken
BrokenCrate(BrokenReason::Unknown), TestPass => Broken;
BrokenCrate(BrokenReason::Unknown), TestSkipped => Broken;
BrokenCrate(BrokenReason::Unknown), TestFail(Unknown) => Broken;
BrokenCrate(BrokenReason::Unknown), BuildFail(Unknown) => Broken;
TestPass, BrokenCrate(BrokenReason::Unknown) => Broken;
TestSkipped, BrokenCrate(BrokenReason::Unknown) => Broken;
TestFail(Unknown), BrokenCrate(BrokenReason::Unknown) => Broken;
BuildFail(Unknown), BrokenCrate(BrokenReason::Unknown) => Broken;
]
);

@@ -112,12 +112,12 @@ impl EncodedLog {

macro_rules! test_result_enum {
(pub enum $name:ident {
with_reason { $($with_reason_name:ident(FailureReason) => $with_reason_repr:expr,)* }
with_reason { $($with_reason_name:ident($reason:ident) => $with_reason_repr:expr,)* }
without_reason { $($reasonless_name:ident => $reasonless_repr:expr,)* }
}) => {
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub enum $name {
$($with_reason_name(FailureReason),)*
$($with_reason_name($reason),)*
$($reasonless_name,)*
}

@@ -129,7 +129,7 @@ macro_rules! test_result_enum {

if parts.len() == 1 {
match parts[0] {
$($with_reason_repr => Ok($name::$with_reason_name(FailureReason::Unknown)),)*
$($with_reason_repr => Ok($name::$with_reason_name($reason::Unknown)),)*
$($reasonless_repr => Ok($name::$reasonless_name),)*
other => Err(TestResultParseError::UnknownResult(other.into()).into()),
}
@@ -168,22 +168,28 @@ pub enum TestResultParseError {

string_enum!(pub enum FailureReason {
Unknown => "unknown",
Broken => "broken",
OOM => "oom",
Timeout => "timeout",
});

impl FailureReason {
pub(crate) fn is_spurious(self) -> bool {
match self {
FailureReason::Unknown | FailureReason::Broken => false,
FailureReason::Unknown => false,
FailureReason::OOM | FailureReason::Timeout => true,
}
}
}

string_enum!(pub enum BrokenReason {
Unknown => "unknown",
CargoToml => "cargo-toml",
Yanked => "yanked",
});

test_result_enum!(pub enum TestResult {
with_reason {
BrokenCrate(BrokenReason) => "broken",
BuildFail(FailureReason) => "build-fail",
TestFail(FailureReason) => "test-fail",
}
@@ -11,7 +11,7 @@ use crate::docker::DockerEnv;
use crate::experiments::{Experiment, Mode};
use crate::logs::LogStorage;
use crate::prelude::*;
use crate::results::{FailureReason, TestResult, WriteResults};
use crate::results::{BrokenReason, TestResult, WriteResults};
use crate::runner::graph::{build_graph, WalkResult};
use crate::utils;
use crossbeam_utils::thread::scope;
@@ -118,7 +118,7 @@ fn run_ex_inner<DB: WriteResults + Sync>(
utils::report_failure(&e);

let mut result = if config.is_broken(&task.krate) {
TestResult::BuildFail(FailureReason::Broken)
TestResult::BrokenCrate(BrokenReason::Unknown)
} else {
TestResult::Error
};
@@ -2,7 +2,7 @@ use crate::crates::Crate;
use crate::dirs::crate_source_dir;
use crate::experiments::Experiment;
use crate::prelude::*;
use crate::results::{FailureReason, TestResult, WriteResults};
use crate::results::{BrokenReason, TestResult, WriteResults};
use crate::run::RunCommand;
use crate::runner::toml_frobber::TomlFrobber;
use crate::runner::OverrideResult;
@@ -90,7 +90,7 @@ impl<'a, DB: WriteResults + 'a> PrepareCrate<'a, DB> {
// Skip crates missing a Cargo.toml
if !source_dir.join("Cargo.toml").is_file() {
Err(err_msg(format!("missing Cargo.toml for {}", self.krate))).with_context(
|_| OverrideResult(TestResult::BuildFail(FailureReason::Broken)),
|_| OverrideResult(TestResult::BrokenCrate(BrokenReason::CargoToml)),
)?;
}

@@ -100,7 +100,9 @@ impl<'a, DB: WriteResults + 'a> PrepareCrate<'a, DB> {
.hide_output(true)
.run()
.with_context(|_| format!("invalid syntax in {}'s Cargo.toml", self.krate))
.with_context(|_| OverrideResult(TestResult::BuildFail(FailureReason::Broken)))?;
.with_context(|_| {
OverrideResult(TestResult::BrokenCrate(BrokenReason::CargoToml))
})?;
}
Ok(())
}
@@ -125,15 +127,33 @@ impl<'a, DB: WriteResults + 'a> PrepareCrate<'a, DB> {
return Ok(());
}

RunCommand::new(CARGO.toolchain(toolchain).unstable_features(true))
let mut yanked_deps = false;
let res = RunCommand::new(CARGO.toolchain(toolchain).unstable_features(true))
.args(&[
"generate-lockfile",
"--manifest-path",
"Cargo.toml",
"-Zno-index-update",
])
.cd(source_dir)
.run()?;
.process_lines(&mut |line| {
if line.contains("failed to select a version for the requirement") {
yanked_deps = true;
}
})
.run();
match res {
Err(_) if yanked_deps => {
return Err(
err_msg(format!("crate {} depends on yanked crates", self.krate))
.context(OverrideResult(TestResult::BrokenCrate(
BrokenReason::Yanked,
)))
.into(),
);
}
other => other?,
}
self.lockfile_captured = true;
}
Ok(())
@@ -32,15 +32,15 @@
},
{
"name": "broken-cargotoml (local)",
"res": "build-fail",
"res": "broken",
"runs": [
{
"log": "stable/local/broken-cargotoml",
"res": "build-fail:broken"
"res": "broken:cargo-toml"
},
{
"log": "beta/local/broken-cargotoml",
"res": "build-fail:broken"
"res": "broken:cargo-toml"
}
],
"url": "https://github.com/rust-lang-nursery/crater/tree/master/local-crates/broken-cargotoml"
@@ -164,6 +164,21 @@
}
],
"url": "https://github.com/rust-lang-nursery/crater/tree/master/local-crates/test-fail"
},
{
"name": "yanked-deps (local)",
"res": "broken",
"runs": [
{
"log": "stable/local/yanked-deps",
"res": "broken:yanked"
},
{
"log": "beta/local/yanked-deps",
"res": "broken:yanked"
}
],
"url": "https://github.com/rust-lang-nursery/crater/tree/master/local-crates/yanked-deps"
}
]
}

0 comments on commit 76f728a

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.