Exclude target directory from Time Machine
authorKornel <kornel@geekhood.net>
Wed, 9 Aug 2017 14:41:53 +0000 (15:41 +0100)
committerKornel <kornel@geekhood.net>
Thu, 10 Aug 2017 00:42:32 +0000 (01:42 +0100)
Temporary/derived files outside dedicated system directories should be explicitly excluded from backups to prevent undesirable bloat and churn.

Cargo.lock
Cargo.toml
src/cargo/lib.rs
src/cargo/ops/cargo_rustc/layout.rs

index 08ab0affd618b0934607477bf6d48e546b1bf3de..4f5f08f17538b119205173f5599f8b45bded7fe2 100644 (file)
@@ -6,6 +6,7 @@ dependencies = [
  "atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cargotest 0.1.0",
+ "core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.11.0",
  "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -162,6 +163,23 @@ dependencies = [
  "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "core-foundation"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.28 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "crates-io"
 version = "0.11.0"
@@ -1003,6 +1021,8 @@ dependencies = [
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum cmake 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f"
 "checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
+"checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7"
+"checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387"
 "checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
 "checksum curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7034c534a1d7d22f7971d6088aa9d281d219ef724026c3428092500f41ae9c2c"
 "checksum curl-sys 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d5481162dc4f424d088581db2f979fa7d4c238fe9794595de61d8d7522e277de"
index 97914d2cd3a8de3810536aef164aec09670188bb..8bfd2fb52aa84bd97021c56fdc21f78f948694f1 100644 (file)
@@ -54,6 +54,9 @@ url = "1.1"
 [target.'cfg(unix)'.dependencies]
 openssl = "0.9"
 
+[target.'cfg(target_os = "macos")'.dependencies]
+core-foundation = { version = "0.4.4", features = ["mac_os_10_7_support"] }
+
 [target.'cfg(windows)'.dependencies]
 advapi32-sys = "0.2"
 kernel32-sys = "0.2"
index bfaf0d1bd965c9144ac27066654f396d49e219c0..118776c6cfec7e0d02ae534b46d66f425389299e 100755 (executable)
@@ -34,6 +34,8 @@ extern crate tempdir;
 extern crate termcolor;
 extern crate toml;
 extern crate url;
+#[cfg(target_os = "macos")]
+extern crate core_foundation;
 
 use std::fmt;
 use std::error::Error;
index 83c66e85a07e94401211b04d7907dbed4aac41d0..e5b2baec3f51ecabab83b751c652655b56885bd6 100644 (file)
@@ -108,11 +108,42 @@ impl Layout {
         })
     }
 
+    #[cfg(not(target_os = "macos"))]
+    fn exclude_from_backups(&self, _: &Path) {}
+
+    #[cfg(target_os = "macos")]
+    /// Marks files or directories as excluded from Time Machine on macOS
+    ///
+    /// This is recommended to prevent derived/temporary files from bloating backups.
+    fn exclude_from_backups(&self, path: &Path) {
+        use std::ptr;
+        use core_foundation::{url, number, string};
+        use core_foundation::base::TCFType;
+
+        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
+        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
+        match (url::CFURL::from_path(path, false), is_excluded_key) {
+            (Some(path), Ok(is_excluded_key)) => unsafe {
+                url::CFURLSetResourcePropertyForKey(
+                    path.as_concrete_TypeRef(),
+                    is_excluded_key.as_concrete_TypeRef(),
+                    number::kCFBooleanTrue as *const _,
+                    ptr::null_mut(),
+                );
+            },
+            // Errors are ignored, since it's an optional feature and failure
+            // doesn't prevent Cargo from working
+            _ => {}
+        }
+    }
+
     pub fn prepare(&mut self) -> io::Result<()> {
         if fs::metadata(&self.root).is_err() {
             fs::create_dir_all(&self.root)?;
         }
 
+        self.exclude_from_backups(&self.root);
+
         mkdir(&self.deps)?;
         mkdir(&self.native)?;
         mkdir(&self.incremental)?;