evobench_tools/run/sub_command/
wd_log.rs1use std::{
2 io::{BufWriter, Write, stderr, stdout},
3 os::unix::{ffi::OsStrExt, process::CommandExt},
4 process::Command,
5 time::Duration,
6};
7
8use anyhow::{Context, Result, anyhow, bail};
9
10use crate::run::working_directory_pool::{
11 WdAllowBareOpt, WorkingDirectoryIdOpt, WorkingDirectoryPool,
12};
13
14#[derive(Debug, clap::Args)]
15pub struct LogOrLogf {
16 #[clap(short, long)]
20 list: bool,
21
22 #[clap(flatten)]
23 allow_bare: WdAllowBareOpt,
24
25 id: WorkingDirectoryIdOpt,
28}
29
30impl LogOrLogf {
31 pub fn run(self, logf: bool, working_directory_pool: &WorkingDirectoryPool) -> Result<()> {
32 let Self {
33 list,
34 allow_bare,
35 id,
36 } = self;
37 let id = id.to_working_directory_id(allow_bare)?;
38
39 let working_directory_path =
40 if let Some(wd) = working_directory_pool.get_working_directory(id) {
41 wd.working_directory_path()
42 } else {
43 let mut out = BufWriter::new(stderr().lock());
44 writeln!(
45 &mut out,
46 "NOTE: working directory with id {id} does not exist. \
47 Looking for log files anyway."
48 )?;
49 out.flush()?;
50 if !list {
51 std::thread::sleep(Duration::from_millis(1400));
52 }
53 working_directory_pool.get_working_directory_path(id)
54 };
55
56 if list {
57 let mut out = BufWriter::new(stdout().lock());
58 for (standard_log_path, _run_id) in working_directory_path.standard_log_paths()? {
59 out.write_all(standard_log_path.as_os_str().as_bytes())?;
60 out.write_all(b"\n")?;
61 }
62 out.flush()?;
63 } else {
64 let (standard_log_path, _run_id) = working_directory_path
65 .last_standard_log_path()?
66 .ok_or_else(|| anyhow!("could not find a log file for working directory {id}"))?;
67
68 if logf {
69 let mut cmd = Command::new("tail");
70 cmd.arg("-F");
71 cmd.arg("--");
72 cmd.arg(standard_log_path);
73 return Err(cmd.exec()).with_context(|| anyhow!("executing {cmd:?}"));
74 } else {
75 let pager = match std::env::var("PAGER") {
76 Ok(s) => s,
77 Err(e) => match e {
78 std::env::VarError::NotPresent => "less".into(),
79 _ => bail!("can't decode PAGER env var: {e:#}"),
80 },
81 };
82
83 let mut cmd = Command::new(&pager);
84 cmd.arg(standard_log_path);
85 return Err(cmd.exec()).with_context(|| anyhow!("executing pager {pager:?}"));
86 }
87 }
88 Ok(())
89 }
90}