From 1a277ab8899aa3840e146ff66e535be904a2c20e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 28 Jan 2024 13:58:51 -0500 Subject: [PATCH] refactor: `DirtyReason::FreshBuild` to represent build from scratch the only beahvior change in this commit is that source verification is also performed for `DirtyReason::Forced`. --- .../core/compiler/fingerprint/dirty_reason.rs | 8 +++ src/cargo/core/compiler/fingerprint/mod.rs | 52 ++++++++----------- src/cargo/core/compiler/job_queue/mod.rs | 8 +-- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/dirty_reason.rs b/src/cargo/core/compiler/fingerprint/dirty_reason.rs index bdd2052c04e6..418422c14c51 100644 --- a/src/cargo/core/compiler/fingerprint/dirty_reason.rs +++ b/src/cargo/core/compiler/fingerprint/dirty_reason.rs @@ -77,6 +77,8 @@ pub enum DirtyReason { FsStatusOutdated(FsStatus), NothingObvious, Forced, + /// First time to build something. + FreshBuild, } trait ShellExt { @@ -131,6 +133,11 @@ impl fmt::Display for After { } impl DirtyReason { + /// Whether a build is dirty because it is a fresh build being kicked off. + pub fn is_fresh_build(&self) -> bool { + matches!(self, DirtyReason::FreshBuild) + } + fn after(old_time: FileTime, new_time: FileTime, what: &'static str) -> After { After { old_time, @@ -257,6 +264,7 @@ impl DirtyReason { s.dirty_because(unit, "the fingerprint comparison turned up nothing obvious") } DirtyReason::Forced => s.dirty_because(unit, "forced"), + DirtyReason::FreshBuild => s.dirty_because(unit, "fresh build"), } } } diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 94a464042e69..ea768e78cbcc 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -415,11 +415,14 @@ 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 compare = compare_old_fingerprint(unit, &loc, &*fingerprint, mtime_on_use); + let dirty_reason = compare_old_fingerprint(unit, &loc, &*fingerprint, mtime_on_use, force); - // If our comparison failed or reported dirty (e.g., we're going to trigger - // a rebuild of this crate), then we also ensure the source of the crate - // passes all verification checks before we build it. + let Some(dirty_reason) = dirty_reason else { + return Ok(Job::new_fresh()); + }; + + // We're going to rebuild, so ensure the source of the crate passes all + // verification checks before we build it. // // The `Source::verify` method is intended to allow sources to execute // pre-build checks to ensure that the relevant source code is all @@ -427,30 +430,12 @@ pub fn prepare_target(cx: &mut Context<'_, '_>, unit: &Unit, force: bool) -> Car // directory sources which will use this hook to perform an integrity check // on all files in the source to ensure they haven't changed. If they have // changed then an error is issued. - if compare - .as_ref() - .map(|dirty| dirty.is_some()) - .unwrap_or(true) - { - let source_id = unit.pkg.package_id().source_id(); - let sources = bcx.packages.sources(); - let source = sources - .get(source_id) - .ok_or_else(|| internal("missing package source"))?; - source.verify(unit.pkg.package_id())?; - } - - let dirty_reason = match compare { - Ok(None) => { - if force { - Some(DirtyReason::Forced) - } else { - return Ok(Job::new_fresh()); - } - } - Ok(reason) => reason, - Err(_) => None, - }; + let source_id = unit.pkg.package_id().source_id(); + let sources = bcx.packages.sources(); + let source = sources + .get(source_id) + .ok_or_else(|| internal("missing package source"))?; + source.verify(unit.pkg.package_id())?; // Clear out the old fingerprint file if it exists. This protects when // compilation is interrupted leaving a corrupt file. For example, a @@ -521,7 +506,7 @@ pub fn prepare_target(cx: &mut Context<'_, '_>, unit: &Unit, force: bool) -> Car Work::new(move |_| write_fingerprint(&loc, &fingerprint)) }; - Ok(Job::new_dirty(write_fingerprint, dirty_reason)) + Ok(Job::new_dirty(write_fingerprint, Some(dirty_reason))) } /// Dependency edge information for fingerprints. This is generated for each @@ -1755,10 +1740,15 @@ fn compare_old_fingerprint( old_hash_path: &Path, new_fingerprint: &Fingerprint, mtime_on_use: bool, -) -> CargoResult> { + forced: bool, +) -> Option { let compare = _compare_old_fingerprint(old_hash_path, new_fingerprint, mtime_on_use); log_compare(unit, &compare); - compare + match compare { + Ok(None) if forced => Some(DirtyReason::Forced), + Ok(reason) => reason, + Err(_) => Some(DirtyReason::FreshBuild), + } } fn _compare_old_fingerprint( diff --git a/src/cargo/core/compiler/job_queue/mod.rs b/src/cargo/core/compiler/job_queue/mod.rs index 7c4c89e4f37d..aa2ced1c2695 100644 --- a/src/cargo/core/compiler/job_queue/mod.rs +++ b/src/cargo/core/compiler/job_queue/mod.rs @@ -1111,9 +1111,11 @@ impl<'cfg> DrainState<'cfg> { // being a compiled package. Dirty(dirty_reason) => { if let Some(reason) = dirty_reason { - config - .shell() - .verbose(|shell| reason.present_to(shell, unit, ws_root))?; + if !reason.is_fresh_build() { + config + .shell() + .verbose(|shell| reason.present_to(shell, unit, ws_root))?; + } } if unit.mode.is_doc() {