Skip to content

Commit 165ceb8

Browse files
committed
feat(build-analysis): build-started log message
The build-started message ought to be pretty much the same as the header in timings HTML report, but some data is only available after the entire build or dependency resolution. Let's collect these data first.
1 parent d42eadb commit 165ceb8

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use crate::ops::resolve::{SpecsAndResolvedFeatures, WorkspaceResolve};
5656
use crate::util::BuildLogger;
5757
use crate::util::context::{GlobalContext, WarningHandling};
5858
use crate::util::interning::InternedString;
59+
use crate::util::log_message::LogMessage;
5960
use crate::util::{CargoResult, StableHasher};
6061

6162
mod compile_filter;
@@ -155,9 +156,24 @@ pub fn compile_ws<'a>(
155156
exec: &Arc<dyn Executor>,
156157
) -> CargoResult<Compilation<'a>> {
157158
let interner = UnitInterner::new();
158-
let _logger = BuildLogger::maybe_new(ws)?;
159+
let logger = BuildLogger::maybe_new(ws)?;
160+
161+
if let Some(ref logger) = logger {
162+
let rustc = ws.gctx().load_global_rustc(Some(ws))?;
163+
logger.log(&LogMessage::BuildStarted {
164+
cwd: ws.gctx().cwd(),
165+
host: rustc.host.as_str(),
166+
jobs: options.build_config.jobs,
167+
profile: options.build_config.requested_profile.as_str(),
168+
rustc_version: &rustc.version.to_string(),
169+
rustc_version_verbose: &rustc.verbose_version,
170+
target_dir: &ws.target_dir().as_path_unlocked(),
171+
workspace_root: &ws.root(),
172+
});
173+
}
159174

160175
let bcx = create_bcx(ws, options, &interner)?;
176+
161177
if options.build_config.unit_graph {
162178
unit_graph::emit_serialized_unit_graph(&bcx.roots, &bcx.unit_graph, ws.gctx())?;
163179
return Compilation::new(&bcx);

src/cargo/util/log_message.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Messages for logging.
22
3+
use std::path::Path;
4+
35
use jiff::Timestamp;
46
use serde::Serialize;
57

@@ -8,17 +10,29 @@ use serde::Serialize;
810
/// Each variant represents a different type of event.
911
#[derive(Serialize)]
1012
#[serde(tag = "reason", rename_all = "kebab-case")]
11-
pub enum LogMessage {}
13+
pub enum LogMessage<'a> {
14+
/// Emitted when a build starts.
15+
BuildStarted {
16+
cwd: &'a Path,
17+
host: &'a str,
18+
jobs: u32,
19+
profile: &'a str,
20+
rustc_version: &'a str,
21+
rustc_version_verbose: &'a str,
22+
target_dir: &'a Path,
23+
workspace_root: &'a Path,
24+
},
25+
}
1226

13-
impl LogMessage {
27+
impl LogMessage<'_> {
1428
/// Converts this message to a JSON log line with run_id and timestamp.
1529
pub fn to_json_log(&self, run_id: &str) -> String {
1630
#[derive(Serialize)]
1731
struct LogEntry<'a> {
1832
run_id: &'a str,
1933
timestamp: Timestamp,
2034
#[serde(flatten)]
21-
msg: &'a LogMessage,
35+
msg: &'a LogMessage<'a>,
2236
}
2337

2438
let entry = LogEntry {

src/cargo/util/logger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl BuildLogger {
8585
}
8686

8787
/// Logs a message.
88-
pub fn log(&self, msg: &LogMessage) {
88+
pub fn log(&self, msg: &LogMessage<'_>) {
8989
let json = msg.to_json_log(&self.run_id);
9090
let _ = self.tx.send(json);
9191
}

tests/testsuite/build_analysis.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use crate::prelude::*;
44

55
use cargo_test_support::basic_manifest;
6+
use cargo_test_support::compare::assert_e2e;
7+
use cargo_test_support::paths;
68
use cargo_test_support::project;
79
use cargo_test_support::str;
810

@@ -42,3 +44,51 @@ fn simple() {
4244
"#]])
4345
.run();
4446
}
47+
48+
#[cargo_test]
49+
fn log_msg_build_started() {
50+
let p = project()
51+
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
52+
.file("src/lib.rs", "")
53+
.build();
54+
55+
p.cargo("check -Zbuild-analysis")
56+
.env("CARGO_BUILD_ANALYSIS_ENABLED", "true")
57+
.masquerade_as_nightly_cargo(&["build-analysis"])
58+
.run();
59+
60+
let cargo_home = paths::cargo_home();
61+
let log_dir = cargo_home.join("log");
62+
assert!(log_dir.exists());
63+
64+
let entries = std::fs::read_dir(&log_dir).unwrap();
65+
let log_file = entries
66+
.filter_map(Result::ok)
67+
.find(|e| e.path().extension().and_then(|s| s.to_str()) == Some("jsonl"))
68+
.unwrap();
69+
70+
let content = std::fs::read_to_string(log_file.path()).unwrap();
71+
72+
assert_e2e().eq(
73+
&content,
74+
str![[r#"
75+
[
76+
{
77+
"cwd": "[ROOT]/foo",
78+
"host": "[HOST_TARGET]",
79+
"jobs": "{...}",
80+
"profile": "dev",
81+
"reason": "build-started",
82+
"run_id": "[..]T[..]Z-[..]",
83+
"rustc_version": "1.[..]",
84+
"rustc_version_verbose": "{...}",
85+
"target_dir": "[ROOT]/foo/target",
86+
"timestamp": "[..]T[..]Z",
87+
"workspace_root": "[ROOT]/foo"
88+
}
89+
]
90+
"#]]
91+
.is_json()
92+
.against_jsonlines(),
93+
);
94+
}

0 commit comments

Comments
 (0)