about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjyn <github@jyn.dev>2023-04-20 21:30:48 -0500
committerjyn <github@jyn.dev>2023-04-29 11:51:57 -0500
commit78a709348dca33414f76986ae72c651d489092f4 (patch)
tree0d815354c402f990f11f2db2700208c9b45a8362
parent2a75607baba3e42814e4cc7fa35358f1be7f75ed (diff)
downloadrust-78a709348dca33414f76986ae72c651d489092f4.tar.gz
rust-78a709348dca33414f76986ae72c651d489092f4.zip
Fix `x test --no-deps`
- Use `cargo metadata` to determine whether a crate has a library
  package or not
- Collect metadata for all workspaces, not just the root workspace and
  cargo
- Don't pass `--lib` for crates without a library
- Use `run_cargo_test` for rust-installer
- Don't build documentation in `lint-docs` if `--no-doc` is passed
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/bootstrap/metadata.rs42
-rw-r--r--src/bootstrap/test.rs49
3 files changed, 58 insertions, 34 deletions
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 14e1328171b..59d2e9cc69e 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -246,6 +246,7 @@ struct Crate {
     name: Interned<String>,
     deps: HashSet<Interned<String>>,
     path: PathBuf,
+    has_lib: bool,
 }
 
 impl Crate {
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
index 597aefadcfe..8f2c3faca3a 100644
--- a/src/bootstrap/metadata.rs
+++ b/src/bootstrap/metadata.rs
@@ -5,7 +5,7 @@ use serde_derive::Deserialize;
 
 use crate::cache::INTERNER;
 use crate::util::output;
-use crate::{Build, Crate};
+use crate::{t, Build, Crate};
 
 /// For more information, see the output of
 /// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
@@ -22,6 +22,7 @@ struct Package {
     source: Option<String>,
     manifest_path: String,
     dependencies: Vec<Dependency>,
+    targets: Vec<Target>,
 }
 
 /// For more information, see the output of
@@ -32,6 +33,11 @@ struct Dependency {
     source: Option<String>,
 }
 
+#[derive(Debug, Deserialize)]
+struct Target {
+    kind: Vec<String>,
+}
+
 /// Collects and stores package metadata of each workspace members into `build`,
 /// by executing `cargo metadata` commands.
 pub fn build(build: &mut Build) {
@@ -46,11 +52,16 @@ pub fn build(build: &mut Build) {
                 .filter(|dep| dep.source.is_none())
                 .map(|dep| INTERNER.intern_string(dep.name))
                 .collect();
-            let krate = Crate { name, deps, path };
+            let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib"));
+            let krate = Crate { name, deps, path, has_lib };
             let relative_path = krate.local_path(build);
             build.crates.insert(name, krate);
             let existing_path = build.crate_paths.insert(relative_path, name);
-            assert!(existing_path.is_none(), "multiple crates with the same path");
+            assert!(
+                existing_path.is_none(),
+                "multiple crates with the same path: {}",
+                existing_path.unwrap()
+            );
         }
     }
 }
@@ -60,7 +71,7 @@ pub fn build(build: &mut Build) {
 /// Note that `src/tools/cargo` is no longer a workspace member but we still
 /// treat it as one here, by invoking an additional `cargo metadata` command.
 fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
-    let cmd_metadata = |manifest_path| {
+    let collect_metadata = |manifest_path| {
         let mut cargo = Command::new(&build.initial_cargo);
         cargo
             .arg("metadata")
@@ -68,21 +79,20 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
             .arg("1")
             .arg("--no-deps")
             .arg("--manifest-path")
-            .arg(manifest_path);
-        cargo
+            .arg(build.src.join(manifest_path));
+        let metadata_output = output(&mut cargo);
+        let Output { packages, .. } = t!(serde_json::from_str(&metadata_output));
+        packages
     };
 
-    // Collects `metadata.packages` from the root workspace.
-    let root_manifest_path = build.src.join("Cargo.toml");
-    let root_output = output(&mut cmd_metadata(&root_manifest_path));
-    let Output { packages, .. } = serde_json::from_str(&root_output).unwrap();
-
-    // Collects `metadata.packages` from src/tools/cargo separately.
-    let cargo_manifest_path = build.src.join("src/tools/cargo/Cargo.toml");
-    let cargo_output = output(&mut cmd_metadata(&cargo_manifest_path));
-    let Output { packages: cargo_packages, .. } = serde_json::from_str(&cargo_output).unwrap();
+    // Collects `metadata.packages` from all workspaces.
+    let packages = collect_metadata("Cargo.toml");
+    let cargo_packages = collect_metadata("src/tools/cargo/Cargo.toml");
+    let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml");
+    let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml");
 
     // We only care about the root package from `src/tool/cargo` workspace.
     let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter();
-    packages.into_iter().chain(cargo_package)
+
+    packages.into_iter().chain(cargo_package).chain(ra_packages).chain(bootstrap_packages)
 }
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 5b70494b30b..aee84e9c9be 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -103,7 +103,8 @@ impl Step for CrateBootstrap {
             path,
             bootstrap_host,
         ));
-        run_cargo_test(cargo, &[], &[], compiler, bootstrap_host, builder);
+        let crate_name = path.rsplit_once('/').unwrap().1;
+        run_cargo_test(cargo, &[], &[], crate_name, compiler, bootstrap_host, builder);
     }
 }
 
@@ -152,7 +153,11 @@ You can skip linkcheck with --exclude src/tools/linkchecker"
             SourceType::InTree,
             &[],
         );
-        run_cargo_test(cargo, &[], &[], compiler, bootstrap_host, builder);
+        run_cargo_test(cargo, &[], &[], "linkchecker", compiler, bootstrap_host, builder);
+
+        if builder.doc_tests == DocTests::No {
+            return;
+        }
 
         // Build all the default documentation.
         builder.default_doc(&[]);
@@ -300,7 +305,7 @@ impl Step for Cargo {
         );
 
         // NOTE: can't use `run_cargo_test` because we need to overwrite `PATH`
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], compiler, self.host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", compiler, self.host, builder);
 
         // Don't run cross-compile tests, we may not have cross-compiled libstd libs
         // available.
@@ -368,7 +373,7 @@ impl Step for RustAnalyzer {
         cargo.env("SKIP_SLOW_TESTS", "1");
 
         cargo.add_rustc_lib_path(builder, compiler);
-        run_cargo_test(cargo, &[], &[], compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "rust-analyzer", compiler, host, builder);
     }
 }
 
@@ -417,7 +422,7 @@ impl Step for Rustfmt {
 
         cargo.add_rustc_lib_path(builder, compiler);
 
-        run_cargo_test(cargo, &[], &[], compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "rustfmt", compiler, host, builder);
     }
 }
 
@@ -465,7 +470,7 @@ impl Step for RustDemangler {
         cargo.env("RUST_DEMANGLER_DRIVER_PATH", rust_demangler);
         cargo.add_rustc_lib_path(builder, compiler);
 
-        run_cargo_test(cargo, &[], &[], compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "rust-demangler", compiler, host, builder);
     }
 }
 
@@ -602,7 +607,7 @@ impl Step for Miri {
 
         // This can NOT be `run_cargo_test` since the Miri test runner
         // does not understand the flags added by `add_flags_and_try_run_test`.
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], compiler, target, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", compiler, target, builder);
         {
             let _time = util::timeit(&builder);
             builder.run(&mut cargo);
@@ -679,7 +684,7 @@ impl Step for CompiletestTest {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(cargo, &[], &[], compiler, host, builder);
+        run_cargo_test(cargo, &[], &[], "compiletest", compiler, host, builder);
     }
 }
 
@@ -722,17 +727,13 @@ impl Step for Clippy {
             &[],
         );
 
-        if !builder.fail_fast {
-            cargo.arg("--no-fail-fast");
-        }
-
         cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
         cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
         let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
 
         cargo.add_rustc_lib_path(builder, compiler);
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], compiler, host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], "clippy", compiler, host, builder);
 
         if builder.try_run(&mut cargo) {
             // The tests succeeded; nothing to do.
@@ -2048,11 +2049,13 @@ fn run_cargo_test(
     cargo: impl Into<Command>,
     libtest_args: &[&str],
     crates: &[Interned<String>],
+    primary_crate: &str,
     compiler: Compiler,
     target: TargetSelection,
     builder: &Builder<'_>,
 ) -> bool {
-    let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, compiler, target, builder);
+    let mut cargo =
+        prepare_cargo_test(cargo, libtest_args, crates, primary_crate, compiler, target, builder);
     let _time = util::timeit(&builder);
     add_flags_and_try_run_tests(builder, &mut cargo)
 }
@@ -2062,6 +2065,7 @@ fn prepare_cargo_test(
     cargo: impl Into<Command>,
     libtest_args: &[&str],
     crates: &[Interned<String>],
+    primary_crate: &str,
     compiler: Compiler,
     target: TargetSelection,
     builder: &Builder<'_>,
@@ -2079,7 +2083,14 @@ fn prepare_cargo_test(
             cargo.arg("--doc");
         }
         DocTests::No => {
-            cargo.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
+            let krate = &builder
+                .crates
+                .get(&INTERNER.intern_str(primary_crate))
+                .unwrap_or_else(|| panic!("missing crate {primary_crate}"));
+            if krate.has_lib {
+                cargo.arg("--lib");
+            }
+            cargo.args(&["--bins", "--examples", "--tests", "--benches"]);
         }
         DocTests::Yes => {}
     }
@@ -2191,7 +2202,7 @@ impl Step for Crate {
             compiler.host,
             target,
         );
-        run_cargo_test(cargo, &[], &self.crates, compiler, target, builder);
+        run_cargo_test(cargo, &[], &self.crates, &self.crates[0], compiler, target, builder);
     }
 }
 
@@ -2284,6 +2295,7 @@ impl Step for CrateRustdoc {
             cargo,
             &[],
             &[INTERNER.intern_str("rustdoc:0.0.0")],
+            "rustdoc",
             compiler,
             target,
             builder,
@@ -2345,6 +2357,7 @@ impl Step for CrateRustdocJsonTypes {
             cargo,
             libtest_args,
             &[INTERNER.intern_str("rustdoc-json-types")],
+            "rustdoc-json-types",
             compiler,
             target,
             builder,
@@ -2504,7 +2517,7 @@ impl Step for Bootstrap {
         }
         // rustbuild tests are racy on directory creation so just run them one at a time.
         // Since there's not many this shouldn't be a problem.
-        run_cargo_test(cmd, &["--test-threads=1"], &[], compiler, host, builder);
+        run_cargo_test(cmd, &["--test-threads=1"], &[], "bootstrap", compiler, host, builder);
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -2617,7 +2630,7 @@ impl Step for RustInstaller {
             SourceType::InTree,
             &[],
         );
-        try_run(builder, &mut cargo.into());
+        run_cargo_test(cargo, &[], &[], "installer", compiler, bootstrap_host, builder);
 
         // We currently don't support running the test.sh script outside linux(?) environments.
         // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a