mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #6363 - dwijnand:add-executable-in-json-output, r=matklad
Include executable in JSON output. Fixes #5426 Rebase of @patriksvensson's #5517 CC @matklad I didn't really get into the issue or the code, I just interatively rebased Patrik's branch and then massaged and cleaned up the code until the tests passed. So please double check it for code correctness, test case correctness and test case coverage. Particularly the branch changed an if condition according to [this suggestion](https://github.com/rust-lang/cargo/pull/5517#issuecomment-388557248) by Aleksey. I rolled that back because at one point it helped fix a series of tests. But let me know if that should be included here.
This commit is contained in:
commit
bfd6618840
@ -49,6 +49,16 @@ pub struct OutputFile {
|
||||
pub flavor: FileFlavor,
|
||||
}
|
||||
|
||||
impl OutputFile {
|
||||
/// Gets the hardlink if present. Otherwise returns the path.
|
||||
pub fn bindst(&self) -> &PathBuf {
|
||||
return match self.hardlink {
|
||||
Some(ref link_dst) => link_dst,
|
||||
None => &self.path,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
|
||||
pub(super) fn new(
|
||||
roots: &[Unit<'a>],
|
||||
|
@ -163,10 +163,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let bindst = match output.hardlink {
|
||||
Some(ref link_dst) => link_dst,
|
||||
None => &output.path,
|
||||
};
|
||||
let bindst = output.bindst();
|
||||
|
||||
if unit.mode == CompileMode::Test {
|
||||
self.compilation.tests.push((
|
||||
@ -274,6 +271,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
|
||||
Ok(self.compilation)
|
||||
}
|
||||
|
||||
/// Returns the executable for the specified unit (if any).
|
||||
pub fn get_executable(&mut self, unit: &Unit<'a>) -> CargoResult<Option<PathBuf>> {
|
||||
for output in self.outputs(unit)?.iter() {
|
||||
if output.flavor == FileFlavor::DebugInfo {
|
||||
continue;
|
||||
}
|
||||
|
||||
let is_binary = unit.target.is_bin() || unit.target.is_bin_example();
|
||||
let is_test = unit.mode.is_any_test() && !unit.mode.is_check();
|
||||
|
||||
if is_binary || is_test {
|
||||
return Ok(Option::Some(output.bindst().clone()));
|
||||
}
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
pub fn prepare_units(
|
||||
&mut self,
|
||||
export_dir: Option<PathBuf>,
|
||||
|
@ -409,6 +409,7 @@ fn link_targets<'a, 'cfg>(
|
||||
.map(|s| s.to_owned())
|
||||
.collect();
|
||||
let json_messages = bcx.build_config.json_messages();
|
||||
let executable = cx.get_executable(unit)?;
|
||||
let mut target = unit.target.clone();
|
||||
if let TargetSourcePath::Metabuild = target.src_path() {
|
||||
// Give it something to serialize.
|
||||
@ -432,11 +433,11 @@ fn link_targets<'a, 'cfg>(
|
||||
let dst = match output.hardlink.as_ref() {
|
||||
Some(dst) => dst,
|
||||
None => {
|
||||
destinations.push(src.display().to_string());
|
||||
destinations.push(src.clone());
|
||||
continue;
|
||||
}
|
||||
};
|
||||
destinations.push(dst.display().to_string());
|
||||
destinations.push(dst.clone());
|
||||
hardlink_or_copy(src, dst)?;
|
||||
if let Some(ref path) = output.export_path {
|
||||
let export_dir = export_dir.as_ref().unwrap();
|
||||
@ -463,6 +464,7 @@ fn link_targets<'a, 'cfg>(
|
||||
profile: art_profile,
|
||||
features,
|
||||
filenames: destinations,
|
||||
executable,
|
||||
fresh,
|
||||
});
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::ser;
|
||||
use serde_json::{self, value::RawValue};
|
||||
|
||||
@ -33,7 +35,8 @@ pub struct Artifact<'a> {
|
||||
pub target: &'a Target,
|
||||
pub profile: ArtifactProfile,
|
||||
pub features: Vec<String>,
|
||||
pub filenames: Vec<String>,
|
||||
pub filenames: Vec<PathBuf>,
|
||||
pub executable: Option<PathBuf>,
|
||||
pub fresh: bool,
|
||||
}
|
||||
|
||||
|
@ -1485,3 +1485,46 @@ fn bench_virtual_manifest_all_implied() {
|
||||
.with_stdout_contains("test bench_bar ... bench: [..]")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_artifact_includes_executable_for_benchmark() {
|
||||
if !is_nightly() {
|
||||
return;
|
||||
}
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"benches/benchmark.rs",
|
||||
r#"
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use test::Bencher;
|
||||
|
||||
#[bench]
|
||||
fn bench_foo(_: &mut Bencher) -> () { () }
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
|
||||
p.cargo("bench --no-run --message-format=json")
|
||||
.with_json(r#"
|
||||
{
|
||||
"executable": "[..]/foo/target/release/benchmark-[..][EXE]",
|
||||
"features": [],
|
||||
"filenames": [ "[..]/foo/target/release/benchmark-[..][EXE]" ],
|
||||
"fresh": false,
|
||||
"package_id": "foo 0.0.1 ([..])",
|
||||
"profile": "{...}",
|
||||
"reason": "compiler-artifact",
|
||||
"target": {
|
||||
"crate_types": [ "bin" ],
|
||||
"kind": [ "bench" ],
|
||||
"edition": "2015",
|
||||
"name": "benchmark",
|
||||
"src_path": "[..]/foo/benches/benchmark.rs"
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.run();
|
||||
}
|
||||
|
@ -3083,6 +3083,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": null,
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": false
|
||||
@ -3110,6 +3111,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": null,
|
||||
"features": [],
|
||||
"package_id":"bar 0.5.0 ([..])",
|
||||
"target":{
|
||||
@ -3162,6 +3164,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": "[..]/foo/target/debug/foo[EXE]",
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": false
|
||||
@ -3191,6 +3194,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": null,
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": true
|
||||
@ -3205,6 +3209,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": null,
|
||||
"features": [],
|
||||
"package_id":"bar 0.5.0 ([..])",
|
||||
"target":{
|
||||
@ -3244,6 +3249,7 @@ fn compiler_json_error_format() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": "[..]/foo/target/debug/foo[EXE]",
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": true
|
||||
@ -3309,6 +3315,7 @@ fn message_format_json_forward_stderr() {
|
||||
"overflow_checks": false,
|
||||
"test":false
|
||||
},
|
||||
"executable": "{...}",
|
||||
"features":[],
|
||||
"filenames": "{...}",
|
||||
"fresh": false
|
||||
|
@ -3004,6 +3004,7 @@ fn json_artifact_includes_test_flag() {
|
||||
"overflow_checks": true,
|
||||
"test": false
|
||||
},
|
||||
"executable": null,
|
||||
"features": [],
|
||||
"package_id":"foo 0.0.1 ([..])",
|
||||
"target":{
|
||||
@ -3026,6 +3027,7 @@ fn json_artifact_includes_test_flag() {
|
||||
"overflow_checks": true,
|
||||
"test": true
|
||||
},
|
||||
"executable": "[..]/foo-[..]",
|
||||
"features": [],
|
||||
"package_id":"foo 0.0.1 ([..])",
|
||||
"target":{
|
||||
@ -3042,6 +3044,63 @@ fn json_artifact_includes_test_flag() {
|
||||
).run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_artifact_includes_executable_for_library_tests() {
|
||||
let p = project()
|
||||
.file("src/main.rs", "fn main() { }")
|
||||
.file("src/lib.rs", r#"#[test] fn lib_test() {}"#)
|
||||
.build();
|
||||
|
||||
p.cargo("test --lib -v --no-run --message-format=json")
|
||||
.with_json(r#"
|
||||
{
|
||||
"executable": "[..]/foo/target/debug/foo-[..][EXE]",
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": false,
|
||||
"package_id": "foo 0.0.1 ([..])",
|
||||
"profile": "{...}",
|
||||
"reason": "compiler-artifact",
|
||||
"target": {
|
||||
"crate_types": [ "lib" ],
|
||||
"kind": [ "lib" ],
|
||||
"edition": "2015",
|
||||
"name": "foo",
|
||||
"src_path": "[..]/foo/src/lib.rs"
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn json_artifact_includes_executable_for_integration_tests() {
|
||||
let p = project()
|
||||
.file("tests/integration_test.rs", r#"#[test] fn integration_test() {}"#)
|
||||
.build();
|
||||
|
||||
p.cargo("test -v --no-run --message-format=json --test integration_test")
|
||||
.with_json(r#"
|
||||
{
|
||||
"executable": "[..]/foo/target/debug/integration_test-[..][EXE]",
|
||||
"features": [],
|
||||
"filenames": "{...}",
|
||||
"fresh": false,
|
||||
"package_id": "foo 0.0.1 ([..])",
|
||||
"profile": "{...}",
|
||||
"reason": "compiler-artifact",
|
||||
"target": {
|
||||
"crate_types": [ "bin" ],
|
||||
"kind": [ "test" ],
|
||||
"edition": "2015",
|
||||
"name": "integration_test",
|
||||
"src_path": "[..]/foo/tests/integration_test.rs"
|
||||
}
|
||||
}
|
||||
"#)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_script_links() {
|
||||
let p = project()
|
||||
|
Loading…
x
Reference in New Issue
Block a user