use std::path::PathBuf;
use crate::fs::Fs;
use crate::paths::Pather;
use crate::Result;
const MARKER_FILENAME: &str = "cfprefsd-needs-invalidation";
const MARKER_NOTE: &[u8] =
b"dodot detected plist drift on the last `up`; the CLI prompt clears this file.\n";
pub fn cfprefsd_marker_path(paths: &dyn Pather) -> PathBuf {
paths.data_dir().join(MARKER_FILENAME)
}
pub fn cfprefsd_marker_exists(fs: &dyn Fs, paths: &dyn Pather) -> bool {
fs.exists(&cfprefsd_marker_path(paths))
}
pub fn write_cfprefsd_marker(fs: &dyn Fs, paths: &dyn Pather) -> Result<()> {
let path = cfprefsd_marker_path(paths);
fs.mkdir_all(paths.data_dir())?;
fs.write_file(&path, MARKER_NOTE)
}
pub fn clear_cfprefsd_marker(fs: &dyn Fs, paths: &dyn Pather) {
let path = cfprefsd_marker_path(paths);
if fs.exists(&path) {
let _ = fs.remove_file(&path);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::TempEnvironment;
#[test]
fn marker_round_trip() {
let env = TempEnvironment::builder().build();
assert!(!cfprefsd_marker_exists(env.fs.as_ref(), env.paths.as_ref()));
write_cfprefsd_marker(env.fs.as_ref(), env.paths.as_ref()).unwrap();
assert!(cfprefsd_marker_exists(env.fs.as_ref(), env.paths.as_ref()));
clear_cfprefsd_marker(env.fs.as_ref(), env.paths.as_ref());
assert!(!cfprefsd_marker_exists(env.fs.as_ref(), env.paths.as_ref()));
}
#[test]
fn write_is_idempotent() {
let env = TempEnvironment::builder().build();
write_cfprefsd_marker(env.fs.as_ref(), env.paths.as_ref()).unwrap();
write_cfprefsd_marker(env.fs.as_ref(), env.paths.as_ref()).unwrap();
assert!(cfprefsd_marker_exists(env.fs.as_ref(), env.paths.as_ref()));
}
#[test]
fn clear_is_idempotent_when_missing() {
let env = TempEnvironment::builder().build();
clear_cfprefsd_marker(env.fs.as_ref(), env.paths.as_ref());
assert!(!cfprefsd_marker_exists(env.fs.as_ref(), env.paths.as_ref()));
}
}