summary refs log tree commit diff stats
path: root/src/file_tree/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/file_tree/mod.rs')
-rw-r--r--src/file_tree/mod.rs47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/file_tree/mod.rs b/src/file_tree/mod.rs
index d6f0c3c..96637b3 100644
--- a/src/file_tree/mod.rs
+++ b/src/file_tree/mod.rs
@@ -24,10 +24,13 @@
 //! you.
 
 use std::{
-    fs, io,
+    fs::{self, File},
+    io,
     path::{Path, PathBuf},
 };
 
+use anyhow::bail;
+
 /// A file tree containing all files that were generated. These are separated into host and
 /// auxiliary files. See their respective descriptions about what differentiates them.
 #[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
@@ -47,18 +50,48 @@ pub struct GeneratedFile {
     ///
     /// This should already be formatted and ready to be used.
     pub value: String,
+
+    /// Whether to override this file silently, if it already exists.
+    pub clobber: bool,
 }
 
 impl GeneratedFile {
     pub fn new(path: PathBuf, value: String) -> Self {
-        Self { path, value }
+        Self {
+            path,
+            value,
+            clobber: true,
+        }
+    }
+    pub fn new_clobber(path: PathBuf, value: String, clobber: bool) -> Self {
+        Self {
+            path,
+            value,
+            clobber,
+        }
     }
     pub fn new_in_out_dir(name: String, value: String, out_dir: &Path) -> Self {
         let path = out_dir.join(name);
-        Self { path, value }
+        Self {
+            path,
+            value,
+            clobber: true,
+        }
     }
 
-    pub fn materialize(self) -> io::Result<()> {
+    pub fn materialize(self) -> anyhow::Result<()> {
+        if !self.clobber {
+            // Check if the file exists
+            if self.path.try_exists()? {
+                bail!(
+                    "Path at '{}' already exists,\n       \
+                    but I don't want to override the file there!\n       \
+                    Please move it out of the way manually.",
+                    self.path.display()
+                )
+            }
+        }
+
         fs::create_dir_all(self.path.parent().expect("This path should have a parent"))?;
         fs::write(self.path, self.value.as_bytes())?;
         Ok(())
@@ -78,11 +111,11 @@ impl FileTree {
         files.into_iter().for_each(|file| self.add_file(file));
     }
 
-    pub fn materialize(self) -> io::Result<()> {
+    pub fn materialize(self) -> anyhow::Result<()> {
         self.files
             .into_iter()
-            .map(|file| -> io::Result<()> { file.materialize() })
-            .collect::<io::Result<()>>()?;
+            .map(|file| -> anyhow::Result<()> { file.materialize() })
+            .collect::<anyhow::Result<()>>()?;
         Ok(())
     }
 }