use std::path::{Path, PathBuf};
use crate::schedule::{Schedule, ScheduleExecutor, SchedulesFile};
pub fn commander_pid_path() -> PathBuf {
dirs::home_dir()
.unwrap_or_default()
.join(".mur")
.join("commander")
.join("commander.pid")
}
pub fn is_commander_running() -> bool {
is_commander_running_at(&commander_pid_path())
}
pub fn is_commander_running_at(pid_path: &Path) -> bool {
let content = match std::fs::read_to_string(pid_path) {
Ok(c) => c,
Err(_) => return false,
};
let pid: i32 = match content.trim().parse() {
Ok(p) => p,
Err(_) => return false,
};
#[cfg(unix)]
{
unsafe { libc::kill(pid, 0) == 0 }
}
#[cfg(not(unix))]
{
false
}
}
pub fn schedules_path() -> PathBuf {
dirs::home_dir()
.unwrap_or_default()
.join(".mur")
.join("schedules.yaml")
}
pub fn load_schedules() -> Result<Vec<Schedule>, Box<dyn std::error::Error>> {
let path = schedules_path();
if !path.exists() {
return Ok(Vec::new());
}
let content = std::fs::read_to_string(&path)?;
let file: SchedulesFile = serde_yaml::from_str(&content)?;
Ok(file.schedules)
}
pub fn save_schedules(schedules: &[Schedule]) -> Result<(), Box<dyn std::error::Error>> {
let path = schedules_path();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let file = SchedulesFile {
schedules: schedules.to_vec(),
};
let yaml = serde_yaml::to_string(&file)?;
std::fs::write(&path, yaml)?;
Ok(())
}
pub fn claim_all_for_commander() -> Result<Vec<String>, Box<dyn std::error::Error>> {
let mut schedules = load_schedules()?;
let mut claimed = Vec::new();
for schedule in &mut schedules {
if schedule.executor != ScheduleExecutor::Commander {
claimed.push(schedule.workflow.clone());
schedule.executor = ScheduleExecutor::Commander;
}
}
if !claimed.is_empty() {
save_schedules(&schedules)?;
}
Ok(claimed)
}
pub fn release_all_from_commander() -> Result<Vec<String>, Box<dyn std::error::Error>> {
let mut schedules = load_schedules()?;
let mut released = Vec::new();
for schedule in &mut schedules {
if schedule.executor == ScheduleExecutor::Commander {
released.push(schedule.workflow.clone());
schedule.executor = ScheduleExecutor::SystemCron;
}
}
if !released.is_empty() {
save_schedules(&schedules)?;
}
Ok(released)
}
pub fn auto_detect_executor() -> ScheduleExecutor {
if is_commander_running() {
ScheduleExecutor::Commander
} else {
ScheduleExecutor::SystemCron
}
}