use crate::service_messages::ClientFailure;
use std::path::{Path, PathBuf};
pub const OWN_MARKERS: [&str; 4] =
["(monochromatic-git-policy-cli-unit)", "(cli-git-unit)", "Description=Commit service socket for the git wrapper", "Description=Commit service for the git wrapper"];
pub(crate) fn write_atomically(path: &Path, text: &str) -> std::io::Result<()> {
let number: u64 = TEMPORARY_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let temporary: PathBuf = path.with_extension(format!("tmp-{}-{number}", std::process::id()));
std::fs::write(&temporary, text.as_bytes())?;
let renamed: std::io::Result<()> = std::fs::rename(&temporary, path);
if renamed.is_err() {
let _removed = std::fs::remove_file(&temporary);
}
return renamed;
}
pub(crate) static TEMPORARY_COUNTER: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
pub(crate) fn is_own_unit_file(path: &Path) -> bool {
return match std::fs::read_to_string(path) {
Ok(text) => carries_own_marker(text.as_str()),
Err(_unreadable) => false,
};
}
pub(crate) fn carries_own_marker(text: &str) -> bool {
for marker in OWN_MARKERS {
if text.contains(marker) {
return true;
}
}
return false;
}
pub(crate) fn own_unit_file_in_runtime_or_user_directory(runtime_directory: &Path, user_directory: Option<&Path>, name: &str) -> bool {
if is_own_unit_file(runtime_directory.join(name).as_path()) {
return true;
}
return match user_directory {
Some(found) => is_own_unit_file(found.join(name).as_path()),
None => false,
};
}
pub(crate) fn any_named_anywhere(directories: &[PathBuf], names: &[&str]) -> bool {
for name in names {
for found in directories {
if found.join(name).exists() {
return true;
}
}
}
return false;
}
pub(crate) fn remove_settled(path: &Path) -> Result<(), ClientFailure> {
return match std::fs::remove_file(path) {
Ok(()) => Ok(()),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(error) => Err(ClientFailure::CouldNotStart(format!("{} cannot be removed: {error}", path.display()))),
};
}