From 548300b20f441e20fb93eaadde66c61874009fb3 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Mon, 28 Dec 2020 15:33:32 +0200 Subject: [PATCH] Add the path to the manifest in json output This allows consumers of the json messages to avoid guessing where exactly the package root is. Having access to the package root is difficult by virtue of requiring logic to guess its location by e.g. walking filesystem from the source file. This guessing logic becomes further complicated in presence of workspaces and nigh impossible to implement correctly in instances where artifacts end up produced from paths above the package root (e.g. `../foo.rs`). Since Cargo has access to this data in the first place, there doesn't seem to be much reason to force consumers to invent their own, possibly flawed, logic. --- src/cargo/core/compiler/mod.rs | 43 +++++++++++++++++++++++++++---- src/cargo/util/machine_message.rs | 2 ++ tests/testsuite/bench.rs | 1 + tests/testsuite/build.rs | 7 +++++ tests/testsuite/doc.rs | 1 + tests/testsuite/metabuild.rs | 2 ++ tests/testsuite/test.rs | 3 +++ 7 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 87ea322c370..71e3abd3eae 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -175,6 +175,7 @@ fn compile<'cfg>( let work = if unit.show_warnings(bcx.config) { replay_output_cache( unit.pkg.package_id(), + PathBuf::from(unit.pkg.manifest_path()), &unit.target, cx.files().message_cache_path(unit), cx.bcx.build_config.message_format, @@ -219,6 +220,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc) -> Car // Prepare the native lib state (extra `-L` and `-l` flags). let build_script_outputs = Arc::clone(&cx.build_script_outputs); let current_id = unit.pkg.package_id(); + let manifest_path = PathBuf::from(unit.pkg.manifest_path()); let build_scripts = cx.build_scripts.get(unit).cloned(); // If we are a binary and the package also contains a library, then we @@ -316,7 +318,16 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc) -> Car &target, mode, &mut |line| on_stdout_line(state, line, package_id, &target), - &mut |line| on_stderr_line(state, line, package_id, &target, &mut output_options), + &mut |line| { + on_stderr_line( + state, + line, + package_id, + &manifest_path, + &target, + &mut output_options, + ) + }, ) .map_err(verbose_if_simple_exit_code) .chain_err(|| format!("could not compile `{}`", name))?; @@ -414,6 +425,7 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu let outputs = cx.outputs(unit)?; let export_dir = cx.files().export_dir(); let package_id = unit.pkg.package_id(); + let manifest_path = PathBuf::from(unit.pkg.manifest_path()); let profile = unit.profile; let unit_mode = unit.mode; let features = unit.features.iter().map(|s| s.to_string()).collect(); @@ -467,6 +479,7 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu let msg = machine_message::Artifact { package_id, + manifest_path, target: &target, profile: art_profile, features, @@ -618,10 +631,10 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult { let name = unit.pkg.name().to_string(); let build_script_outputs = Arc::clone(&cx.build_script_outputs); let package_id = unit.pkg.package_id(); + let manifest_path = PathBuf::from(unit.pkg.manifest_path()); let target = Target::clone(&unit.target); let mut output_options = OutputOptions::new(cx, unit); let script_metadata = cx.find_build_script_metadata(unit); - Ok(Work::new(move |state| { if let Some(script_metadata) = script_metadata { if let Some(output) = build_script_outputs.lock().unwrap().get(script_metadata) { @@ -638,7 +651,16 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult { rustdoc .exec_with_streaming( &mut |line| on_stdout_line(state, line, package_id, &target), - &mut |line| on_stderr_line(state, line, package_id, &target, &mut output_options), + &mut |line| { + on_stderr_line( + state, + line, + package_id, + &manifest_path, + &target, + &mut output_options, + ) + }, false, ) .chain_err(|| format!("could not document `{}`", name))?; @@ -1139,10 +1161,11 @@ fn on_stderr_line( state: &JobState<'_>, line: &str, package_id: PackageId, + manifest_path: &std::path::Path, target: &Target, options: &mut OutputOptions, ) -> CargoResult<()> { - if on_stderr_line_inner(state, line, package_id, target, options)? { + if on_stderr_line_inner(state, line, package_id, manifest_path, target, options)? { // Check if caching is enabled. if let Some((path, cell)) = &mut options.cache_cell { // Cache the output, which will be replayed later when Fresh. @@ -1160,6 +1183,7 @@ fn on_stderr_line_inner( state: &JobState<'_>, line: &str, package_id: PackageId, + manifest_path: &std::path::Path, target: &Target, options: &mut OutputOptions, ) -> CargoResult { @@ -1300,6 +1324,7 @@ fn on_stderr_line_inner( // indicating which package it came from and then emit it. let msg = machine_message::FromCompiler { package_id, + manifest_path, target, message: compiler_message, } @@ -1314,6 +1339,7 @@ fn on_stderr_line_inner( fn replay_output_cache( package_id: PackageId, + manifest_path: PathBuf, target: &Target, path: PathBuf, format: MessageFormat, @@ -1343,7 +1369,14 @@ fn replay_output_cache( break; } let trimmed = line.trim_end_matches(&['\n', '\r'][..]); - on_stderr_line(state, trimmed, package_id, &target, &mut options)?; + on_stderr_line( + state, + trimmed, + package_id, + &manifest_path, + &target, + &mut options, + )?; line.clear(); } Ok(()) diff --git a/src/cargo/util/machine_message.rs b/src/cargo/util/machine_message.rs index ab3c32e3676..baef5167b36 100644 --- a/src/cargo/util/machine_message.rs +++ b/src/cargo/util/machine_message.rs @@ -20,6 +20,7 @@ pub trait Message: ser::Serialize { #[derive(Serialize)] pub struct FromCompiler<'a> { pub package_id: PackageId, + pub manifest_path: &'a Path, pub target: &'a Target, pub message: Box, } @@ -33,6 +34,7 @@ impl<'a> Message for FromCompiler<'a> { #[derive(Serialize)] pub struct Artifact<'a> { pub package_id: PackageId, + pub manifest_path: PathBuf, pub target: &'a Target, pub profile: ArtifactProfile, pub features: Vec, diff --git a/tests/testsuite/bench.rs b/tests/testsuite/bench.rs index 959b688f380..37884a3f402 100644 --- a/tests/testsuite/bench.rs +++ b/tests/testsuite/bench.rs @@ -1736,6 +1736,7 @@ fn json_artifact_includes_executable_for_benchmark() { "filenames": "{...}", "fresh": false, "package_id": "foo 0.0.1 ([..])", + "manifest_path": "[..]", "profile": "{...}", "reason": "compiler-artifact", "target": { diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 35feb0fcdd6..7276aea8710 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -3140,6 +3140,7 @@ fn compiler_json_error_format() { { "reason":"compiler-artifact", "package_id":"foo 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["custom-build"], "crate_types":["bin"], @@ -3166,6 +3167,7 @@ fn compiler_json_error_format() { { "reason":"compiler-message", "package_id":"bar 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["lib"], "crate_types":["lib"], @@ -3191,6 +3193,7 @@ fn compiler_json_error_format() { "executable": null, "features": [], "package_id":"bar 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["lib"], "crate_types":["lib"], @@ -3221,6 +3224,7 @@ fn compiler_json_error_format() { { "reason":"compiler-message", "package_id":"foo 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["bin"], "crate_types":["bin"], @@ -3237,6 +3241,7 @@ fn compiler_json_error_format() { { "reason":"compiler-artifact", "package_id":"foo 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["bin"], "crate_types":["bin"], @@ -3307,6 +3312,7 @@ fn message_format_json_forward_stderr() { { "reason":"compiler-message", "package_id":"foo 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["bin"], "crate_types":["bin"], @@ -3323,6 +3329,7 @@ fn message_format_json_forward_stderr() { { "reason":"compiler-artifact", "package_id":"foo 0.5.0 ([..])", + "manifest_path": "[..]", "target":{ "kind":["bin"], "crate_types":["bin"], diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 4878c649875..c06e13a3fe6 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -1414,6 +1414,7 @@ fn doc_message_format() { "spans": "{...}" }, "package_id": "foo [..]", + "manifest_path": "[..]", "reason": "compiler-message", "target": "{...}" } diff --git a/tests/testsuite/metabuild.rs b/tests/testsuite/metabuild.rs index a40243aaf4f..149b6dd298a 100644 --- a/tests/testsuite/metabuild.rs +++ b/tests/testsuite/metabuild.rs @@ -691,6 +691,7 @@ fn metabuild_json_artifact() { "filenames": "{...}", "fresh": false, "package_id": "foo [..]", + "manifest_path": "[..]", "profile": "{...}", "reason": "compiler-artifact", "target": { @@ -743,6 +744,7 @@ fn metabuild_failed_build_json() { "spans": "{...}" }, "package_id": "foo [..]", + "manifest_path": "[..]", "reason": "compiler-message", "target": { "crate_types": [ diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index 48260439161..5ed6198c864 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -3536,6 +3536,7 @@ fn json_artifact_includes_test_flag() { "executable": "[..]/foo-[..]", "features": [], "package_id":"foo 0.0.1 ([..])", + "manifest_path": "[..]", "target":{ "kind":["lib"], "crate_types":["lib"], @@ -3572,6 +3573,7 @@ fn json_artifact_includes_executable_for_library_tests() { "filenames": "{...}", "fresh": false, "package_id": "foo 0.0.1 ([..])", + "manifest_path": "[..]", "profile": "{...}", "reason": "compiler-artifact", "target": { @@ -3610,6 +3612,7 @@ fn json_artifact_includes_executable_for_integration_tests() { "filenames": "{...}", "fresh": false, "package_id": "foo 0.0.1 ([..])", + "manifest_path": "[..]", "profile": "{...}", "reason": "compiler-artifact", "target": {