use crate::paths::Paths;
use crate::session::{self, PULSE_SESSION};
use crate::{run, util};
use anyhow::Result;
use std::process::ExitCode;
struct UpOpts {
watch: bool,
json: bool,
}
impl UpOpts {
fn parse(args: &[String]) -> std::result::Result<Self, String> {
let mut o = UpOpts {
watch: false,
json: false,
};
for a in args {
match a.as_str() {
"--watch" | "-w" => o.watch = true,
"--json" => o.json = true,
other => return Err(other.to_string()),
}
}
Ok(o)
}
}
pub fn cmd_up(paths: &Paths, args: &[String]) -> Result<ExitCode> {
let opts = match UpOpts::parse(args) {
Ok(o) => o,
Err(bad) => {
eprintln!("looop up: unknown option '{bad}' (expected --watch/-w and/or --json)");
return Ok(ExitCode::from(1));
}
};
let UpOpts { watch, json } = opts;
if session::is_alive(paths, PULSE_SESSION) {
println!("looop: pulse already running — see it: looop ls");
if watch {
println!("looop: watching {PULSE_SESSION} (Ctrl-C to stop watching)");
session::watch(paths, PULSE_SESSION)?;
}
return Ok(ExitCode::SUCCESS);
}
if session::status_exists(paths, PULSE_SESSION) {
session::prune(paths); }
if json {
unsafe { std::env::set_var("LOOOP_LOG_FORMAT", "json") };
}
let bin = paths.bin.to_string_lossy().to_string();
session::spawn_detached(paths, vec![bin, "_pulse".to_string()], PULSE_SESSION)?;
println!("looop: pulse started{}", if json { " [json]" } else { "" });
if watch {
session::await_alive(paths, PULSE_SESSION, std::time::Duration::from_secs(5));
println!("looop: watching {PULSE_SESSION} (Ctrl-C to stop watching)");
session::watch(paths, PULSE_SESSION)?;
}
Ok(ExitCode::SUCCESS)
}
pub fn cmd_down(paths: &Paths) -> Result<ExitCode> {
if !session::is_alive(paths, PULSE_SESSION) {
session::prune(paths);
println!("looop: no pulse session to stop");
return Ok(ExitCode::SUCCESS);
}
match session::kill_quiet(paths, PULSE_SESSION) {
Ok(()) => {
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(2);
while session::is_alive(paths, PULSE_SESSION) && std::time::Instant::now() < deadline {
std::thread::sleep(std::time::Duration::from_millis(50));
}
session::prune(paths);
println!("looop: pulse stopped");
Ok(ExitCode::SUCCESS)
}
Err(e) => {
util::event(util::Level::Error, "down", &e.to_string(), &[]);
Ok(ExitCode::from(1))
}
}
}
pub fn cmd_pulse(paths: &Paths) -> Result<ExitCode> {
run::cmd_run(paths)
}