1use std::env;
4
5use anyhow::{Error, Result};
6use colored::{control::set_override, Colorize};
7use log::{Level, LevelFilter, Metadata, Record};
8
9#[derive(Default)]
10struct SimpleLogger;
11
12impl SimpleLogger {
13 fn level_color(level: &Level) -> String {
14 let name = format!("{:>5}", level.as_str().to_uppercase());
15 match level {
16 Level::Error => name.red().bold().to_string(),
17 Level::Warn => name.yellow().bold().to_string(),
18 Level::Info => name.green().bold().to_string(),
19 Level::Debug => name.blue().bold().to_string(),
20 Level::Trace => name.magenta().bold().to_string(),
21 }
22 }
23}
24
25impl log::Log for SimpleLogger {
26 fn enabled(&self, metadata: &Metadata) -> bool {
27 metadata.level() <= log::max_level()
28 }
29
30 fn log(&self, record: &Record) {
31 if record.target() == "CI_LOG_GROUPING" {
32 println!("{}", record.args());
34 } else if self.enabled(record.metadata()) {
35 println!(
36 "[{}]: {}",
37 Self::level_color(&record.level()),
38 record.args()
39 );
40 }
41 }
42
43 fn flush(&self) {}
44}
45
46pub fn init() -> Result<()> {
51 let logger: SimpleLogger = SimpleLogger;
52 if matches!(
53 env::var("CPP_LINTER_COLOR").as_deref(),
54 Ok("on" | "1" | "true")
55 ) {
56 set_override(true);
57 }
58 log::set_boxed_logger(Box::new(logger))
59 .map(|()| log::set_max_level(LevelFilter::Info))
60 .map_err(Error::from)
61}
62
63#[cfg(test)]
64mod test {
65 use std::env;
66
67 use super::{init, SimpleLogger};
68
69 #[test]
70 fn trace_log() {
71 env::set_var("CPP_LINTER_COLOR", "true");
72 init().unwrap_or(());
73 assert!(SimpleLogger::level_color(&log::Level::Trace).contains("TRACE"));
74 log::set_max_level(log::LevelFilter::Trace);
75 log::trace!("A dummy log statement for code coverage");
76 }
77}