Auto merge of #8069 - ehuss:build-finished, r=alexcrichton

Add "build-finished" JSON message.

This adds a JSON message when a build is finished.  This is useful for tools to know when to stop parsing JSON, which is particularly useful for commands like `cargo test` or `cargo run` where additional output may follow.

Closes #7978
This commit is contained in:
bors 2020-04-09 19:34:39 +00:00
commit 239f2bfd0c
7 changed files with 62 additions and 6 deletions

View File

@ -70,12 +70,11 @@ use super::job::{
use super::timings::Timings;
use super::{BuildContext, BuildPlan, CompileMode, Context, Unit};
use crate::core::{PackageId, TargetKind};
use crate::util;
use crate::util::diagnostic_server::{self, DiagnosticPrinter};
use crate::util::Queue;
use crate::util::{internal, profile, CargoResult, CargoResultExt, ProcessBuilder};
use crate::util::{Config, DependencyQueue};
use crate::util::{Progress, ProgressStyle};
use crate::util::machine_message::{self, Message as _};
use crate::util::{self, internal, profile};
use crate::util::{CargoResult, CargoResultExt, ProcessBuilder};
use crate::util::{Config, DependencyQueue, Progress, ProgressStyle, Queue};
/// This structure is backed by the `DependencyQueue` type and manages the
/// queueing of compilation steps for each package. Packages enqueue units of
@ -701,6 +700,13 @@ impl<'a, 'cfg> DrainState<'a, 'cfg> {
let time_elapsed = util::elapsed(cx.bcx.config.creation_time().elapsed());
self.timings.finished(cx.bcx, &error)?;
if cx.bcx.build_config.emit_json() {
let msg = machine_message::BuildFinished {
success: error.is_none(),
}
.to_json_string();
cx.bcx.config.shell().stdout_println(msg);
}
if let Some(e) = error {
Err(e)

View File

@ -90,3 +90,14 @@ impl<'a> Message for TimingInfo<'a> {
"timing-info"
}
}
#[derive(Serialize)]
pub struct BuildFinished {
pub success: bool,
}
impl Message for BuildFinished {
fn reason(&self) -> &str {
"build-finished"
}
}

View File

@ -217,6 +217,30 @@ may be found in [the chapter on build scripts](build-scripts.md).
}
```
#### Build finished
The "build-finished" message is emitted at the end of the build.
```javascript
{
/* The "reason" indicates the kind of message. */
"reason": "build-finished",
/* Whether or not the build finished successfully. */
"success": true,
}
````
This message can be helpful for tools to know when to stop reading JSON
messages. Commands such as `cargo test` or `cargo run` can produce additional
output after the build has finished. This message lets a tool know that Cargo
will not produce additional JSON messages, but there may be additional output
that may be generated afterwards (such as the output generated by the program
executed by `cargo run`).
> Note: There is experimental nightly-only support for JSON output for tests,
> so additional test-specific JSON messages may begin arriving after the
> "build-finished" message if that is enabled.
### Custom subcommands
Cargo is designed to be extensible with new subcommands without having to modify

View File

@ -1628,6 +1628,8 @@ fn json_artifact_includes_executable_for_benchmark() {
"src_path": "[..]/foo/benches/benchmark.rs"
}
}
{"reason": "build-finished", "success": true}
"#,
)
.run();

View File

@ -3200,6 +3200,8 @@ fn compiler_json_error_format() {
"filenames": "{...}",
"fresh": $FRESH
}
{"reason": "build-finished", "success": true}
"#
.replace("$FRESH", fresh)
};
@ -3280,6 +3282,8 @@ fn message_format_json_forward_stderr() {
"filenames": "{...}",
"fresh": false
}
{"reason": "build-finished", "success": true}
"#,
)
.run();

View File

@ -64,7 +64,10 @@ fn cargo_renders() {
p.cargo("build --message-format json-render-diagnostics")
.with_status(101)
.with_stdout("{\"reason\":\"compiler-artifact\",[..]")
.with_stdout(
"{\"reason\":\"compiler-artifact\",[..]\n\
{\"reason\":\"build-finished\",\"success\":false}",
)
.with_stderr_contains(
"\
[COMPILING] bar [..]

View File

@ -3363,6 +3363,8 @@ fn json_artifact_includes_test_flag() {
"filenames":["[..]/foo-[..]"],
"fresh": false
}
{"reason": "build-finished", "success": true}
"#,
)
.run();
@ -3395,6 +3397,8 @@ fn json_artifact_includes_executable_for_library_tests() {
"src_path": "[..]/foo/src/lib.rs"
}
}
{"reason": "build-finished", "success": true}
"#,
)
.run();
@ -3429,6 +3433,8 @@ fn json_artifact_includes_executable_for_integration_tests() {
"src_path": "[..]/foo/tests/integration_test.rs"
}
}
{"reason": "build-finished", "success": true}
"#,
)
.run();