devalang_wasm/services/build/outputs/
logs.rs1#![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}