From fc2352b0fe01f03d2f50c03dad3f82c58f1c2f4e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 28 Jan 2024 14:34:51 -0500 Subject: [PATCH] refactor: read JSON fingerprint reading only when needed --- src/cargo/core/compiler/fingerprint/mod.rs | 80 +++++++++++++--------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 925123a8a10f..369956333644 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -373,6 +373,7 @@ use serde::{Deserialize, Serialize}; use tracing::{debug, info}; use crate::core::compiler::unit_graph::UnitDep; +use crate::core::Verbosity; use crate::core::Package; use crate::util::errors::CargoResult; use crate::util::interning::InternedString; @@ -415,7 +416,9 @@ pub fn prepare_target(cx: &mut Context<'_, '_>, unit: &Unit, force: bool) -> Car // information about failed comparisons to aid in debugging. let fingerprint = calculate(cx, unit)?; let mtime_on_use = cx.bcx.config.cli_unstable().mtime_on_use; - let dirty_reason = compare_old_fingerprint(unit, &loc, &*fingerprint, mtime_on_use, force); + let verbosity = cx.bcx.config.shell().verbosity(); + let dirty_reason = + compare_old_fingerprint(unit, &loc, &*fingerprint, mtime_on_use, force, verbosity); let Some(dirty_reason) = dirty_reason else { return Ok(Job::new_fresh()); @@ -1741,9 +1744,43 @@ fn compare_old_fingerprint( new_fingerprint: &Fingerprint, mtime_on_use: bool, forced: bool, + verbosity: Verbosity, ) -> Option { - let compare = _compare_old_fingerprint(old_hash_path, new_fingerprint, mtime_on_use); - log_compare(unit, &compare); + if mtime_on_use { + // update the mtime so other cleaners know we used it + let t = FileTime::from_system_time(SystemTime::now()); + debug!("mtime-on-use forcing {:?} to {}", old_hash_path, t); + paths::set_file_time_no_err(old_hash_path, t); + } + + let tracing_enabled = tracing::enabled!(tracing::Level::INFO); + let verbose = !matches!(verbosity, Verbosity::Quiet | Verbosity::Normal); + + let compare = + _compare_old_fingerprint(old_hash_path, new_fingerprint, tracing_enabled || verbose); + + if tracing_enabled { + // Logs the result of fingerprint comparison. + // TODO: Obsolete and mostly superseded by [`DirtyReason`]. Could be removed. + match compare.as_ref() { + Ok(None) => {} + Ok(Some(reason)) => { + info!( + "fingerprint dirty for {}/{:?}/{:?}", + unit.pkg, unit.mode, unit.target, + ); + info!(" dirty: {reason:?}"); + } + Err(e) => { + info!( + "fingerprint error for {}/{:?}/{:?}", + unit.pkg, unit.mode, unit.target, + ); + info!(" err: {e:?}"); + } + } + } + match compare { Ok(None) if forced => Some(DirtyReason::Forced), Ok(reason) => reason, @@ -1751,25 +1788,23 @@ fn compare_old_fingerprint( } } +/// If detail is not required, just returns a [`DirtyReason::NothingObvious`] +/// instead of comparing JSON fingerprint files. fn _compare_old_fingerprint( old_hash_path: &Path, new_fingerprint: &Fingerprint, - mtime_on_use: bool, + detail_required: bool, ) -> CargoResult> { let old_fingerprint_short = paths::read(old_hash_path)?; - if mtime_on_use { - // update the mtime so other cleaners know we used it - let t = FileTime::from_system_time(SystemTime::now()); - debug!("mtime-on-use forcing {:?} to {}", old_hash_path, t); - paths::set_file_time_no_err(old_hash_path, t); - } - let new_hash = new_fingerprint.hash_u64(); if util::to_hex(new_hash) == old_fingerprint_short && new_fingerprint.fs_status.up_to_date() { return Ok(None); } + if !detail_required { + return Ok(Some(DirtyReason::NothingObvious)); + } let old_fingerprint_json = paths::read(&old_hash_path.with_extension("json"))?; let old_fingerprint: Fingerprint = serde_json::from_str(&old_fingerprint_json) @@ -1785,29 +1820,6 @@ fn _compare_old_fingerprint( Ok(Some(new_fingerprint.compare(&old_fingerprint))) } -/// Logs the result of fingerprint comparison. -/// -/// TODO: Obsolete and mostly superseded by [`DirtyReason`]. Could be removed. -fn log_compare(unit: &Unit, compare: &CargoResult>) { - match compare { - Ok(None) => {} - Ok(Some(reason)) => { - info!( - "fingerprint dirty for {}/{:?}/{:?}", - unit.pkg, unit.mode, unit.target, - ); - info!(" dirty: {reason:?}"); - } - Err(e) => { - info!( - "fingerprint error for {}/{:?}/{:?}", - unit.pkg, unit.mode, unit.target, - ); - info!(" err: {e:?}"); - } - } -} - /// Parses Cargo's internal [`EncodedDepInfo`] structure that was previously /// serialized to disk. ///