about summary refs log tree commit diff
diff options
context:
space:
mode:
authoronur-ozkan <work@onurozkan.dev>2025-01-09 08:38:50 +0300
committeronur-ozkan <work@onurozkan.dev>2025-01-12 08:43:00 +0300
commit58306c6a0027f3d36dbbd10b23d30ed453514c9a (patch)
treeeca54ea179f31fb32e75851dba9d5b2686817768
parent12445e0b2c532e389b8293924ed7c2b6fad5238f (diff)
downloadrust-58306c6a0027f3d36dbbd10b23d30ed453514c9a.tar.gz
rust-58306c6a0027f3d36dbbd10b23d30ed453514c9a.zip
implement `BuildStamp` that is stricter impl for build stamps
Signed-off-by: onur-ozkan <work@onurozkan.dev>
-rw-r--r--src/bootstrap/src/utils/build_stamp.rs73
-rw-r--r--src/bootstrap/src/utils/mod.rs7
2 files changed, 78 insertions, 2 deletions
diff --git a/src/bootstrap/src/utils/build_stamp.rs b/src/bootstrap/src/utils/build_stamp.rs
new file mode 100644
index 00000000000..fc695b2b477
--- /dev/null
+++ b/src/bootstrap/src/utils/build_stamp.rs
@@ -0,0 +1,73 @@
+use std::{
+    fs, io,
+    path::{Path, PathBuf},
+};
+
+#[derive(Clone)]
+pub struct BuildStamp {
+    path: PathBuf,
+    stamp: String,
+}
+
+impl From<BuildStamp> for PathBuf {
+    fn from(value: BuildStamp) -> Self {
+        value.path
+    }
+}
+
+impl AsRef<Path> for BuildStamp {
+    fn as_ref(&self) -> &Path {
+        &self.path
+    }
+}
+
+impl BuildStamp {
+    pub fn new(dir: &Path) -> Self {
+        Self { path: dir.join(".stamp"), stamp: String::new() }
+    }
+
+    pub fn with_stamp(mut self, stamp: String) -> Self {
+        self.stamp = stamp;
+        self
+    }
+
+    pub fn with_prefix(mut self, prefix: &str) -> Self {
+        assert!(
+            !prefix.starts_with('.') && !prefix.ends_with('.'),
+            "prefix can not start or end with '.'"
+        );
+
+        let stamp_filename = self.path.components().last().unwrap().as_os_str().to_str().unwrap();
+        let stamp_filename = stamp_filename.strip_prefix('.').unwrap_or(stamp_filename);
+        self.path.set_file_name(format!(".{prefix}-{stamp_filename}"));
+
+        self
+    }
+
+    pub fn remove(self) -> io::Result<()> {
+        match fs::remove_file(&self.path) {
+            Ok(()) => Ok(()),
+            Err(e) => {
+                if e.kind() == io::ErrorKind::NotFound {
+                    Ok(())
+                } else {
+                    Err(e)
+                }
+            }
+        }
+    }
+
+    pub fn write(&self) -> io::Result<()> {
+        fs::write(&self.path, &self.stamp)
+    }
+
+    pub fn is_up_to_date(&self) -> bool {
+        match fs::read(&self.path) {
+            Ok(h) => self.stamp.as_bytes() == h.as_slice(),
+            Err(e) if e.kind() == io::ErrorKind::NotFound => false,
+            Err(e) => {
+                panic!("failed to read stamp file `{}`: {}", self.path.display(), e);
+            }
+        }
+    }
+}
diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs
index b5f5e2ba6dc..ea56932b404 100644
--- a/src/bootstrap/src/utils/mod.rs
+++ b/src/bootstrap/src/utils/mod.rs
@@ -2,6 +2,7 @@
 //! support for a wide range of tasks and operations such as caching, tarballs, release
 //! channels, job management, etc.
 
+pub(crate) mod build_stamp;
 pub(crate) mod cache;
 pub(crate) mod cc_detect;
 pub(crate) mod change_tracker;
@@ -9,10 +10,12 @@ pub(crate) mod channel;
 pub(crate) mod exec;
 pub(crate) mod helpers;
 pub(crate) mod job;
-#[cfg(feature = "build-metrics")]
-pub(crate) mod metrics;
 pub(crate) mod render_tests;
 pub(crate) mod shared_helpers;
 pub(crate) mod tarball;
+
+#[cfg(feature = "build-metrics")]
+pub(crate) mod metrics;
+
 #[cfg(test)]
 mod tests;