Skip to content

detect more failure cases #98

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

Open
wants to merge 17 commits into
base: master
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
13 changes: 9 additions & 4 deletions src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ pub struct Command<'w, 'pl> {
log_output: bool,
}

impl<'w, 'pl> Command<'w, 'pl> {
impl<'w> Command<'w, '_> {
/// Create a new, unsandboxed command.
pub fn new<R: Runnable>(workspace: &'w Workspace, binary: R) -> Self {
binary.prepare_command(Self::new_inner(binary.name(), Some(workspace), None))
Expand Down Expand Up @@ -329,9 +329,14 @@ impl<'w, 'pl> Command<'w, 'pl> {
/// # Ok(())
/// # }
/// ```
pub fn process_lines(mut self, f: &'pl mut dyn FnMut(&str, &mut ProcessLinesActions)) -> Self {
self.process_lines = Some(f);
self
pub fn process_lines<'pl>(
self,
f: &'pl mut dyn FnMut(&str, &mut ProcessLinesActions),
) -> Command<'w, 'pl> {
Command {
process_lines: Some(f),
..self
}
}

/// Enable or disable logging all the output lines to the [`log` crate][log]. By default
Expand Down
93 changes: 59 additions & 34 deletions src/prepare.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::cmd::{Command, CommandError};
use crate::cmd::{Command, CommandError, ProcessLinesActions};
use crate::{build::CratePatch, Crate, Toolchain, Workspace};
use anyhow::Context as _;
use log::info;
Expand Down Expand Up @@ -101,8 +101,6 @@ impl<'a> Prepare<'a> {
return Ok(());
}

let mut yanked_deps = false;
let mut missing_deps = false;
let mut cmd = Command::new(self.workspace, self.toolchain.cargo()).args(&[
"generate-lockfile",
"--manifest-path",
Expand All @@ -114,28 +112,7 @@ impl<'a> Prepare<'a> {
.env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly");
}

match cmd
.cd(self.source_dir)
.process_lines(&mut |line, _| {
if line.contains("failed to select a version for the requirement") {
yanked_deps = true;
} else if line.contains("failed to load source for dependency")
|| line.contains("no matching package named")
{
missing_deps = true;
}
})
.run_capture()
{
Ok(_) => Ok(()),
Err(CommandError::ExecutionFailed { status: _, stderr }) if yanked_deps => {
Err(PrepareError::YankedDependencies(stderr).into())
}
Err(CommandError::ExecutionFailed { status: _, stderr }) if missing_deps => {
Err(PrepareError::MissingDependencies(stderr).into())
}
Err(err) => Err(err.into()),
}
run_command(cmd.cd(self.source_dir))
}

fn fetch_deps(&mut self) -> anyhow::Result<()> {
Expand All @@ -149,7 +126,6 @@ pub(crate) fn fetch_deps(
source_dir: &Path,
fetch_build_std_targets: &[&str],
) -> anyhow::Result<()> {
let mut missing_deps = false;
let mut cmd = Command::new(workspace, toolchain.cargo())
.args(&["fetch", "--manifest-path", "Cargo.toml"])
.cd(source_dir);
Expand All @@ -163,18 +139,61 @@ pub(crate) fn fetch_deps(
cmd = cmd.args(&["--target", target]);
}

match cmd
.process_lines(&mut |line, _| {
if line.contains("failed to load source for dependency") {
missing_deps = true;
}
})
.run_capture()
{
run_command(cmd)
}

fn run_command(cmd: Command) -> anyhow::Result<()> {
let mut yanked_deps = false;
let mut missing_deps = false;
let mut broken_deps = false;
let mut broken_lockfile = false;

let mut process = |line: &str, _: &mut ProcessLinesActions| {
if line.contains("failed to select a version for the requirement") {
yanked_deps = true;
} else if line.contains("failed to load source for dependency")
|| line.contains("no matching package named")
|| line.contains("no matching package found")
|| line.contains("registry index was not found in any configuration:")
|| line.contains("no matching package for override ")
|| (line.contains("The patch location ")
&& line.contains(" does not appear to contain any packages matching the name "))
{
missing_deps = true;
} else if line.contains("failed to parse manifest at")
|| line.contains("error: invalid table header")
|| line.contains("error: invalid type: ")
|| line.contains("error: cyclic feature dependency: feature ")
|| line.contains("error: cyclic package dependency: package ")
|| (line.contains("error: package collision in the lockfile: packages ")
&& line.contains(
" are different, but only one can be written to lockfile unambiguously",
))
{
broken_deps = true;
} else if line.contains("error: failed to parse lock file at")
|| line.contains(
"error: Attempting to resolve a dependency with more than one crate with links=",
)
{
broken_lockfile = true;
}
};

match cmd.process_lines(&mut process).run_capture() {
Ok(_) => Ok(()),
Err(CommandError::ExecutionFailed { status: _, stderr }) if yanked_deps => {
Err(PrepareError::YankedDependencies(stderr).into())
}
Err(CommandError::ExecutionFailed { status: _, stderr }) if missing_deps => {
Err(PrepareError::MissingDependencies(stderr).into())
}
Err(CommandError::ExecutionFailed { status: _, stderr }) if broken_deps => {
Err(PrepareError::BrokenDependencies(stderr).into())
}
Err(CommandError::ExecutionFailed { status: _, stderr }) if broken_lockfile => {
Err(PrepareError::InvalidCargoLock(stderr).into())
}
Err(err) => Err(err.into()),
}
}
Expand Down Expand Up @@ -384,12 +403,18 @@ pub enum PrepareError {
/// rejecting it.
#[error("invalid Cargo.toml syntax")]
InvalidCargoTomlSyntax,
/// Something about the crates dependencies is invalid
#[error("broken dependencies: \n\n{0}")]
BrokenDependencies(String),
/// Some of this crate's dependencies were yanked, preventing Crater from fetching them.
#[error("the crate depends on yanked dependencies: \n\n{0}")]
YankedDependencies(String),
/// Some of the dependencies do not exist anymore.
#[error("the crate depends on missing dependencies: \n\n{0}")]
MissingDependencies(String),
/// cargo rejected (generating) the lockfile
#[error("the crate has a broken lockfile: \n\n{0}")]
InvalidCargoLock(String),
}

#[cfg(test)]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "invalid-cargotoml-conflicting-links"
version = "0.1.0"
authors = ["Pietro Albini <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ring_13 = { version = "=0.13.5", package = "ring" }
ring_14 = { version = "=0.14.6", package = "ring" }


[replace]
"ring:0.13.5" = { git = "https://github.com/briansmith/ring.git", rev = "704e4216a397bd830479bcd6d7dd67fc62cdbe67" }
"ring:0.14.6" = { git = "https://github.com/briansmith/ring.git", rev = "ef85df478152aa3fe06c811309379efa08f8a529" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
12 changes: 12 additions & 0 deletions tests/buildtest/crates/invalid-cargotoml-content-deps/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "invalid-cargotoml-content-deps"
version = "0.1.0"
authors = ["Pietro Albini <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
parity-db = "=0.2.3"
# invalid package name in invalid-cargotoml-content is too invalid
# invalid-cargotoml-content = { git = "https://github.com/rust-lang/rustwide.git", rev = "ee102383cbe40aafdfce7bf04a120226c16a8983" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "invalid-cargotoml-content-type-in-deps"
version = "0.1.0"
authors = []
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
libressl-pnacl-sys = "=2.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
12 changes: 12 additions & 0 deletions tests/buildtest/crates/invalid-cargotoml-cyclic-feature/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "invalid-cargotoml-cyclic-feature"
version = "0.1.0"
authors = ["Pietro Albini <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[features]
cyclic = ["cyclic"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
10 changes: 10 additions & 0 deletions tests/buildtest/crates/invalid-cargotoml-cyclic-package/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "invalid-cargotoml-cyclic-package"
version = "0.1.0"
authors = ["Pietro Albini <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
invalid-cargotoml-cyclic-package = { path = "./" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "invalid-cargotoml-missing-override"
version = "0.1.0"
authors = ["Pietro Albini <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
build-rs = "=0.1.2"

[replace]
"build-rs:0.1.2" = { git = "https://github.com/rust-lang/rustwide.git", rev = "07784be00b68cfd6bf80006c8d8669a7d6374ec2" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
Loading