Skip to content

Commit 117c33b

Browse files
authored
Turbopack: report changed env vars in tracing (#88195)
### What? Add a list of changed defined env vars to the trace file
1 parent 37a09be commit 117c33b

File tree

1 file changed

+113
-21
lines changed

1 file changed

+113
-21
lines changed

crates/next-api/src/project.rs

Lines changed: 113 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ use next_core::{
2525
segment_config::ParseSegmentMode,
2626
util::{NextRuntime, OptionEnvMap},
2727
};
28+
use rustc_hash::FxHashMap;
2829
use serde::{Deserialize, Serialize};
29-
use tracing::Instrument;
30+
use tracing::{Instrument, field::Empty};
3031
use turbo_rcstr::{RcStr, rcstr};
3132
use turbo_tasks::{
3233
Completion, Completions, FxIndexMap, IntoTraitRef, NonLocalValue, OperationValue, OperationVc,
@@ -329,34 +330,125 @@ fn output_fs_operation(project: ResolvedVc<Project>) -> Vc<DiskFileSystem> {
329330
project.project_fs()
330331
}
331332

333+
enum EnvDiffType {
334+
Added,
335+
Removed,
336+
Modified,
337+
}
338+
339+
fn env_diff(
340+
old: &[(RcStr, Option<RcStr>)],
341+
new: &[(RcStr, Option<RcStr>)],
342+
) -> Vec<(RcStr, EnvDiffType)> {
343+
let mut diffs = Vec::new();
344+
let mut old_map: FxHashMap<_, _> = old.iter().cloned().collect();
345+
346+
for (key, new_value) in new.iter() {
347+
match old_map.remove(key) {
348+
Some(old_value) => {
349+
if &old_value != new_value {
350+
diffs.push((key.clone(), EnvDiffType::Modified));
351+
}
352+
}
353+
None => {
354+
diffs.push((key.clone(), EnvDiffType::Added));
355+
}
356+
}
357+
}
358+
359+
for (key, _) in old.iter() {
360+
if old_map.contains_key(key) {
361+
diffs.push((key.clone(), EnvDiffType::Removed));
362+
}
363+
}
364+
365+
diffs
366+
}
367+
368+
fn env_diff_report(old: &[(RcStr, Option<RcStr>)], new: &[(RcStr, Option<RcStr>)]) -> String {
369+
use std::fmt::Write;
370+
371+
let diff = env_diff(old, new);
372+
373+
let mut report = String::new();
374+
for (key, diff_type) in diff {
375+
let symbol = match diff_type {
376+
EnvDiffType::Added => "+",
377+
EnvDiffType::Removed => "-",
378+
EnvDiffType::Modified => "*",
379+
};
380+
if !report.is_empty() {
381+
report.push_str(", ");
382+
}
383+
write!(report, "{}{}", symbol, key).unwrap();
384+
}
385+
report
386+
}
387+
388+
fn define_env_diff_report(old: &DefineEnv, new: &DefineEnv) -> String {
389+
use std::fmt::Write;
390+
391+
let mut report = String::new();
392+
for (name, old, new) in [
393+
("client", &old.client, &new.client),
394+
("edge", &old.edge, &new.edge),
395+
("nodejs", &old.nodejs, &new.nodejs),
396+
] {
397+
let diff = env_diff_report(old, new);
398+
if !diff.is_empty() {
399+
if !report.is_empty() {
400+
report.push_str(", ");
401+
}
402+
write!(report, "{name}: {{ {diff} }}").unwrap();
403+
}
404+
}
405+
report
406+
}
407+
332408
impl ProjectContainer {
333-
#[tracing::instrument(level = "info", name = "initialize project", skip_all)]
334409
pub async fn initialize(self: ResolvedVc<Self>, options: ProjectOptions) -> Result<()> {
335-
let watch = options.watch;
410+
let span = tracing::info_span!(
411+
"initialize project",
412+
project_name = %self.await?.name,
413+
env_diff = Empty
414+
);
415+
let span_clone = span.clone();
416+
async move {
417+
let watch = options.watch;
336418

337-
self.await?.options_state.set(Some(options));
419+
let this = self.await?;
420+
if let Some(old_options) = &*this.options_state.get_untracked() {
421+
span.record(
422+
"env_diff",
423+
define_env_diff_report(&old_options.define_env, &options.define_env).as_str(),
424+
);
425+
}
426+
this.options_state.set(Some(options));
338427

339-
let project = self.project().to_resolved().await?;
340-
let project_fs = project_fs_operation(project)
341-
.read_strongly_consistent()
342-
.await?;
343-
if watch.enable {
344-
project_fs
345-
.start_watching_with_invalidation_reason(watch.poll_interval)
428+
let project = self.project().to_resolved().await?;
429+
let project_fs = project_fs_operation(project)
430+
.read_strongly_consistent()
346431
.await?;
347-
} else {
348-
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
349-
// this path is just used for display purposes
432+
if watch.enable {
433+
project_fs
434+
.start_watching_with_invalidation_reason(watch.poll_interval)
435+
.await?;
436+
} else {
437+
project_fs.invalidate_with_reason(|path| invalidation::Initialize {
438+
// this path is just used for display purposes
439+
path: RcStr::from(path.to_string_lossy()),
440+
});
441+
}
442+
let output_fs = output_fs_operation(project)
443+
.read_strongly_consistent()
444+
.await?;
445+
output_fs.invalidate_with_reason(|path| invalidation::Initialize {
350446
path: RcStr::from(path.to_string_lossy()),
351447
});
448+
Ok(())
352449
}
353-
let output_fs = output_fs_operation(project)
354-
.read_strongly_consistent()
355-
.await?;
356-
output_fs.invalidate_with_reason(|path| invalidation::Initialize {
357-
path: RcStr::from(path.to_string_lossy()),
358-
});
359-
Ok(())
450+
.instrument(span_clone)
451+
.await
360452
}
361453

362454
#[tracing::instrument(level = "info", name = "update project options", skip_all)]

0 commit comments

Comments
 (0)