diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index 3573fe1..c201cd7 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -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(workspace: &'w Workspace, binary: R) -> Self { binary.prepare_command(Self::new_inner(binary.name(), Some(workspace), None)) @@ -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 diff --git a/src/prepare.rs b/src/prepare.rs index 8239794..adc8850 100644 --- a/src/prepare.rs +++ b/src/prepare.rs @@ -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; @@ -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", @@ -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<()> { @@ -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); @@ -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()), } } @@ -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)] diff --git a/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.lock b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.lock new file mode 100644 index 0000000..fcd0b44 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.lock @@ -0,0 +1,98 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "cc" +version = "1.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a" +dependencies = [ + "shlex", +] + +[[package]] +name = "invalid-cargotoml-conflicting-links" +version = "0.1.0" +dependencies = [ + "ring 0.13.5", + "ring 0.14.6", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.172" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" + +[[package]] +name = "ring" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" +dependencies = [ + "cc", + "lazy_static", + "libc", + "untrusted", +] + +[[package]] +name = "ring" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" +dependencies = [ + "cc", + "lazy_static", + "libc", + "spin", + "untrusted", + "winapi", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "untrusted" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.toml new file mode 100644 index 0000000..d397cb2 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "invalid-cargotoml-conflicting-links" +version = "0.1.0" +authors = ["Pietro Albini "] +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" } diff --git a/tests/buildtest/crates/invalid-cargotoml-conflicting-links/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-conflicting-links/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-content-deps/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-content-deps/Cargo.toml new file mode 100644 index 0000000..e7ca4e7 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-content-deps/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "invalid-cargotoml-content-deps" +version = "0.1.0" +authors = ["Pietro Albini "] +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" } diff --git a/tests/buildtest/crates/invalid-cargotoml-content-deps/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-content-deps/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-content-deps/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.lock b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.lock new file mode 100644 index 0000000..1861b69 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.lock @@ -0,0 +1,25 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "invalid-cargotoml-content-type-in-deps" +version = "0.1.0" +dependencies = [ + "libressl-pnacl-sys", +] + +[[package]] +name = "libressl-pnacl-sys" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbd33b70b69d25b726e2e747833e22c7ebd98cc46da2b368f45b36b4d026395" +dependencies = [ + "pnacl-build-helper", +] + +[[package]] +name = "pnacl-build-helper" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb74016978b58b71690dc3bb9a4890bd41dac2d4c6835249edf71a698dbc2db" diff --git a/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.toml new file mode 100644 index 0000000..abf3e74 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/Cargo.toml @@ -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" diff --git a/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-content-type-in-deps/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/Cargo.toml new file mode 100644 index 0000000..915e692 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "invalid-cargotoml-cyclic-feature" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[features] +cyclic = ["cyclic"] diff --git a/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-cyclic-feature/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-cyclic-package/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-cyclic-package/Cargo.toml new file mode 100644 index 0000000..b5a0a5d --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-cyclic-package/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "invalid-cargotoml-cyclic-package" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +invalid-cargotoml-cyclic-package = { path = "./" } diff --git a/tests/buildtest/crates/invalid-cargotoml-cyclic-package/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-cyclic-package/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-cyclic-package/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-override/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-missing-override/Cargo.toml new file mode 100644 index 0000000..f44d7f5 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-override/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "invalid-cargotoml-missing-override" +version = "0.1.0" +authors = ["Pietro Albini "] +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" } diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-override/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-missing-override/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-override/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-patch/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-missing-patch/Cargo.toml new file mode 100644 index 0000000..b7fc03d --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-patch/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "invalid-cargotoml-missing-patch" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +build-rs = "=0.1.2" + +[patch.crates-io] +build-rs = { git = "https://github.com/rust-lang/rustwide.git", rev = "07784be00b68cfd6bf80006c8d8669a7d6374ec2" } diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-patch/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-missing-patch/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-patch/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/.cargo/config.toml b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/.cargo/config.toml new file mode 100644 index 0000000..01e9dc1 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/.cargo/config.toml @@ -0,0 +1,2 @@ +[registries] +will-be-removed = { index = "https://github.com/rust-lang/crates.io-index" } diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.lock b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.lock new file mode 100644 index 0000000..54f1e41 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "build-rs" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00b8763668c99f8d9101b8a0dd82106f58265464531a79b2cef0d9a30c17dd2" + +[[package]] +name = "invalid-cargotoml-missing-registry-config" +version = "0.1.0" +dependencies = [ + "build-rs", +] diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.toml new file mode 100644 index 0000000..40efe3b --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "invalid-cargotoml-missing-registry-config" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +build-rs = { version = "*", registry = "will-be-removed" } diff --git a/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-missing-registry-config/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-cargotoml-syntax-deps/Cargo.toml b/tests/buildtest/crates/invalid-cargotoml-syntax-deps/Cargo.toml new file mode 100644 index 0000000..7f319f6 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-syntax-deps/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "invalid-cargotoml-syntax-deps" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +url = "=0.5.9" diff --git a/tests/buildtest/crates/invalid-cargotoml-syntax-deps/src/main.rs b/tests/buildtest/crates/invalid-cargotoml-syntax-deps/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-cargotoml-syntax-deps/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.lock b/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.lock new file mode 100644 index 0000000..093a780 --- /dev/null +++ b/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "invalid-lockfile-syntax +version = "0.1.0" diff --git a/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.toml b/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.toml new file mode 100644 index 0000000..45ef771 --- /dev/null +++ b/tests/buildtest/crates/invalid-lockfile-syntax/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "invalid-lockfile-syntax" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/buildtest/crates/invalid-lockfile-syntax/src/main.rs b/tests/buildtest/crates/invalid-lockfile-syntax/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/invalid-lockfile-syntax/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/lockfile-collision/Cargo.toml b/tests/buildtest/crates/lockfile-collision/Cargo.toml new file mode 100644 index 0000000..db22620 --- /dev/null +++ b/tests/buildtest/crates/lockfile-collision/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "lockfile-collision" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lockfile-collision = { path = "./crates/lockfile-collision" } diff --git a/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/Cargo.toml b/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/Cargo.toml new file mode 100644 index 0000000..34e77d1 --- /dev/null +++ b/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "lockfile-collision" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/src/lib.rs b/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/src/lib.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/lockfile-collision/crates/lockfile-collision/src/lib.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/lockfile-collision/src/main.rs b/tests/buildtest/crates/lockfile-collision/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/lockfile-collision/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/missing-deps-git/Cargo.toml b/tests/buildtest/crates/missing-deps-git/Cargo.toml index 7e65c56..ceba8ea 100644 --- a/tests/buildtest/crates/missing-deps-git/Cargo.toml +++ b/tests/buildtest/crates/missing-deps-git/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "missing-deps" +name = "missing-deps-git" version = "0.1.0" authors = ["Pietro Albini "] edition = "2018" diff --git a/tests/buildtest/crates/missing-deps-registry-version/Cargo.lock b/tests/buildtest/crates/missing-deps-registry-version/Cargo.lock new file mode 100644 index 0000000..81155a1 --- /dev/null +++ b/tests/buildtest/crates/missing-deps-registry-version/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "empty-library" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2aa7b9820e9739aa1443425ad1f7deb9e7686d276d867e9c4752189b3130c" + +[[package]] +name = "missing-deps-registry-version" +version = "0.1.0" +dependencies = [ + "empty-library", +] diff --git a/tests/buildtest/crates/missing-deps-registry-version/Cargo.toml b/tests/buildtest/crates/missing-deps-registry-version/Cargo.toml new file mode 100644 index 0000000..40b69be --- /dev/null +++ b/tests/buildtest/crates/missing-deps-registry-version/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "missing-deps-registry-version" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +empty-library = "=0.5.0" diff --git a/tests/buildtest/crates/missing-deps-registry-version/src/main.rs b/tests/buildtest/crates/missing-deps-registry-version/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/missing-deps-registry-version/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/crates/missing-deps-typo/Cargo.toml b/tests/buildtest/crates/missing-deps-typo/Cargo.toml new file mode 100644 index 0000000..afc3e9d --- /dev/null +++ b/tests/buildtest/crates/missing-deps-typo/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "missing-deps-typo" +version = "0.1.0" +authors = ["Pietro Albini "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# it's build-rs (dash vs. underscore) +build_rs = "*" diff --git a/tests/buildtest/crates/missing-deps-typo/src/main.rs b/tests/buildtest/crates/missing-deps-typo/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/tests/buildtest/crates/missing-deps-typo/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/tests/buildtest/mod.rs b/tests/buildtest/mod.rs index 594df51..f916f3f 100644 --- a/tests/buildtest/mod.rs +++ b/tests/buildtest/mod.rs @@ -5,6 +5,51 @@ use rustwide::cmd::{ProcessLinesActions, SandboxBuilder}; mod runner; mod inside_docker; +#[test] +fn buildtest_crate_name_matches_folder_name() { + for result in std::fs::read_dir(concat!( + env!("CARGO_MANIFEST_DIR"), + "/tests/buildtest/crates" + )) + .unwrap() + { + let dir_entry = result.unwrap(); + if dir_entry.file_type().unwrap().is_dir() { + let dir_name = dir_entry.file_name(); + + if [ + "cargo-workspace".as_ref(), + "invalid-cargotoml-syntax".as_ref(), + ] + .contains(&dir_name.as_os_str()) + { + continue; + } + + let expected_crate_name = if dir_name != "invalid-cargotoml-content" { + dir_name.clone() + } else { + "!".into() + }; + + let cargo_toml_path = dir_entry.path().join("Cargo.toml"); + + if !cargo_toml_path.exists() { + continue; + } + + let cargo_toml_content = std::fs::read_to_string(&cargo_toml_path).unwrap(); + + assert!( + cargo_toml_content.contains(&format!("name = {expected_crate_name:?}")), + "directory {:?} does not contain a crate with the expected name {:?}", + dir_name, + expected_crate_name + ) + } + } +} + #[test] fn test_hello_world() { runner::run("hello-world", |run| { @@ -199,7 +244,7 @@ test_prepare_error_stderr!( test_missing_deps_git, "missing-deps-git", MissingDependencies, - "failed to get `not-a-git-repo` as a dependency of package `missing-deps v0.1.0" + "failed to get `not-a-git-repo` as a dependency of package `missing-deps-git v0.1.0" ); test_prepare_error_stderr!( @@ -215,3 +260,94 @@ test_prepare_error_stderr!( MissingDependencies, "error: no matching package named `macro` found" ); + +test_prepare_error_stderr!( + test_invalid_cargotoml_content_deps, + "invalid-cargotoml-content-deps", + BrokenDependencies, + "failed to parse the version requirement `0.11\t` for dependency `parking_lot`" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_syntax_deps, + "invalid-cargotoml-syntax-deps", + BrokenDependencies, + "error: invalid table header" +); + +test_prepare_error_stderr!( + test_invalid_lockfile_syntax, + "invalid-lockfile-syntax", + InvalidCargoLock, + "error: failed to parse lock file at" +); + +test_prepare_error_stderr!( + test_missing_deps_typo, + "missing-deps-typo", + MissingDependencies, + "error: no matching package found" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_cyclic_feature, + "invalid-cargotoml-cyclic-feature", + BrokenDependencies, + "error: cyclic feature dependency: feature" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_cyclic_package, + "invalid-cargotoml-cyclic-package", + BrokenDependencies, + "error: cyclic package dependency: package" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_missing_registry_config, + "invalid-cargotoml-missing-registry-config", + MissingDependencies, + "registry index was not found in any configuration: `will-be-removed`" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_missing_override, + "invalid-cargotoml-missing-override", + MissingDependencies, + "no matching package for override `https://github.com/rust-lang/crates.io-index#build-rs@0.1.2` found" +); + +test_prepare_error_stderr!( + test_missing_deps_registry_version, + "missing-deps-registry-version", + YankedDependencies, + "error: failed to select a version for the requirement `empty-library = \"=0.5.0\"`" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_content_type_in_deps, + "invalid-cargotoml-content-type-in-deps", + BrokenDependencies, + "error: invalid type: map, expected a string" +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_conflicting_links, + "invalid-cargotoml-conflicting-links", + InvalidCargoLock, + "error: Attempting to resolve a dependency with more than one crate with links=ring-asm" +); + +test_prepare_error_stderr!( + test_lockfile_collision, + "lockfile-collision", + BrokenDependencies, + "error: package collision in the lockfile: packages lockfile-collision v0.1.0 " +); + +test_prepare_error_stderr!( + test_invalid_cargotoml_missing_patch, + "invalid-cargotoml-missing-patch", + MissingDependencies, + "The patch location `https://github.com/rust-lang/rustwide.git?rev=07784be00b68cfd6bf80006c8d8669a7d6374ec2` does not appear to contain any packages matching the name `build-rs`" +); diff --git a/tests/buildtest/runner.rs b/tests/buildtest/runner.rs index a849d16..86b46ea 100644 --- a/tests/buildtest/runner.rs +++ b/tests/buildtest/runner.rs @@ -63,6 +63,30 @@ impl Runner { } } +#[allow(unused_macros)] +macro_rules! test_prepare_unknown_err { + ($name:ident, $krate:expr, $expected:ident $(,$expected_output:expr)?) => { + #[test] + fn $name() { + runner::run($krate, |run| { + let res = run.run( + rustwide::cmd::SandboxBuilder::new().enable_networking(false), + |_| Ok(()), + ); + if let Some(err) = res + .err() + .and_then(|err| err.downcast::().ok()) + { + panic!("did get an unexpected error: \n\n{}", err); + } else { + // Everything is OK! + } + Ok(()) + }); + } + }; +} + macro_rules! test_prepare_error { ($name:ident, $krate:expr, $expected:ident) => { #[test]