devalang_wasm/services/build/outputs/
logs.rs

1#![cfg(feature = "cli")]
2
3use std::fs::{OpenOptions, create_dir_all};
4use std::io::Write;
5use std::path::Path;
6
7use anyhow::{Context, Result};
8use time::OffsetDateTime;
9use time::macros::format_description;
10
11const LOG_FILE_NAME: &str = "build.log";
12const TIMESTAMP_FORMAT: &[time::format_description::FormatItem<'static>] =
13    format_description!("[hour padding:zero]:[minute padding:zero]:[second padding:zero]");
14
15#[derive(Debug, Clone, Copy, Default)]
16pub struct LogWriter;
17
18impl LogWriter {
19    pub fn new() -> Self {
20        Self
21    }
22
23    pub fn clear(&self, output_root: impl AsRef<Path>) -> Result<()> {
24        let root = output_root.as_ref().join("logs");
25        create_dir_all(&root)
26            .with_context(|| format!("failed to create log directory: {}", root.display()))?;
27
28        let log_path = root.join(LOG_FILE_NAME);
29        if log_path.exists() {
30            std::fs::remove_file(&log_path)
31                .with_context(|| format!("failed to remove log file: {}", log_path.display()))?;
32        }
33
34        Ok(())
35    }
36
37    pub fn append(&self, output_root: impl AsRef<Path>, message: &str) -> Result<()> {
38        let root = output_root.as_ref().join("logs");
39        create_dir_all(&root)
40            .with_context(|| format!("failed to create log directory: {}", root.display()))?;
41
42        let log_path = root.join(LOG_FILE_NAME);
43        let mut file = OpenOptions::new()
44            .create(true)
45            .append(true)
46            .open(&log_path)
47            .with_context(|| format!("failed to open log file: {}", log_path.display()))?;
48
49        let timestamp = OffsetDateTime::now_utc();
50        let formatted = timestamp
51            .format(TIMESTAMP_FORMAT)
52            .unwrap_or_else(|_| "00:00:00".to_string());
53
54        writeln!(file, "[{}] {}", formatted, message)
55            .with_context(|| format!("unable to write log record: {}", log_path.display()))?;
56
57        Ok(())
58    }
59}