sagiegurari / cargo-make
1
//! # log
2
//!
3
//! Initializes the global logger.
4
//!
5

6
#[cfg(test)]
7
#[path = "./logger_test.rs"]
8
mod logger_test;
9

10
use crate::recursion_level;
11
use crate::types::FlowInfo;
12
use colored::*;
13
use envmnt;
14
use fern;
15
use log::{Level, LevelFilter};
16
use std::io::stdout;
17
use std::process::exit;
18

19 8
#[derive(Debug, PartialEq)]
20
/// The log levels
21
pub(crate) enum LogLevel {
22
    VERBOSE,
23
    INFO,
24
    ERROR,
25
}
26

27
/// The logger options used to initialize the logger
28
pub(crate) struct LoggerOptions {
29
    /// The logger level name (verbose, info, error)
30
    pub(crate) level: String,
31
    /// True to printout colorful output
32
    pub(crate) color: bool,
33
}
34

35 8
pub(crate) fn get_level(level_name: &str) -> LogLevel {
36 8
    let mut level = LogLevel::INFO;
37

38 8
    if level_name == "verbose" {
39 8
        level = LogLevel::VERBOSE;
40 8
    } else if level_name == "error" {
41 8
        level = LogLevel::ERROR;
42
    }
43

44 2
    level
45 8
}
46

47
/// Returns the current logger level name
48 8
pub(crate) fn get_log_level() -> String {
49 8
    let level = if log_enabled!(Level::Debug) {
50 0
        "verbose"
51 8
    } else if log_enabled!(Level::Info) {
52 0
        "info"
53
    } else {
54 8
        "error"
55
    };
56

57 8
    level.to_string()
58 8
}
59

60 8
fn get_name_for_filter(filter: &LevelFilter) -> String {
61 8
    let level = match filter {
62 8
        LevelFilter::Debug => Level::Debug,
63 8
        LevelFilter::Warn => Level::Warn,
64 8
        LevelFilter::Error => Level::Error,
65 8
        _ => Level::Info,
66
    };
67

68 8
    get_name_for_level(&level)
69 8
}
70

71 8
fn get_name_for_level(level: &Level) -> String {
72 8
    match level {
73 8
        Level::Debug => "verbose".to_string(),
74 8
        Level::Warn => "warn".to_string(),
75 8
        Level::Error => "error".to_string(),
76 8
        _ => "info".to_string(),
77
    }
78 8
}
79

80 8
fn get_formatted_name(name: &str, use_color: bool) -> ColoredString {
81 8
    if use_color {
82 8
        name.bold()
83
    } else {
84 8
        name.normal()
85
    }
86 8
}
87

88 8
fn get_formatted_log_level(level: &Level, use_color: bool) -> ColoredString {
89 8
    let mut level_name = get_name_for_level(&level);
90 8
    level_name = level_name.to_uppercase();
91

92 8
    if use_color {
93 8
        let fmt_value = match level {
94 8
            Level::Debug => level_name.cyan(),
95 8
            Level::Info => level_name.green(),
96 8
            Level::Warn => level_name.yellow(),
97 8
            Level::Error => level_name.red(),
98 0
            _ => level_name.normal(),
99
        };
100

101 8
        fmt_value.bold()
102
    } else {
103 8
        level_name.normal()
104
    }
105 8
}
106

107 8
pub(crate) fn should_reduce_output(flow_info: &FlowInfo) -> bool {
108 0
    match flow_info.config.config.reduce_output {
109 8
        Some(value) => value,
110 8
        None => !envmnt::is("CARGO_MAKE_CI"),
111
    }
112 8
}
113

114
/// Initializes the global logger.
115
///
116
/// # Arguments
117
///
118
/// * `level_name` - The log level name ('verbose', 'info', 'error')
119 8
pub(crate) fn init(options: &LoggerOptions) {
120 8
    let level_name = &options.level;
121 8
    let color = options.color;
122

123 8
    let level = get_level(level_name);
124

125 8
    let log_level = match level {
126 8
        LogLevel::VERBOSE => LevelFilter::Debug,
127 2
        LogLevel::INFO => LevelFilter::Info,
128 8
        LogLevel::ERROR => LevelFilter::Error,
129
    };
130 8
    let level_name_value = get_name_for_filter(&log_level);
131

132 8
    envmnt::set("CARGO_MAKE_LOG_LEVEL", &level_name_value);
133 8
    envmnt::set_bool("CARGO_MAKE_DISABLE_COLOR", !color);
134

135 8
    let recursion_lvl = recursion_level::get();
136 8
    let recursion_level_log = if recursion_lvl == 0 {
137 6
        "".to_string()
138
    } else {
139 2
        format!("[{}]", recursion_lvl)
140
    };
141

142 8
    let result = fern::Dispatch::new()
143 8
        .format(move |out, message, record| {
144 8
            let name = env!("CARGO_PKG_NAME");
145

146 8
            let record_level = record.level();
147

148 2
            if cfg!(test) {
149 8
                if record_level == LevelFilter::Error {
150 8
                    panic!("test error flow");
151
                }
152
            }
153

154 0
            let name_fmt = get_formatted_name(&name, color);
155

156 0
            let record_level_fmt = get_formatted_log_level(&record_level, color);
157

158 0
            out.finish(format_args!(
159 0
                "[{}]{} {} - {}",
160 0
                &name_fmt, &recursion_level_log, &record_level_fmt, &message
161
            ));
162

163 0
            if record_level == Level::Error {
164 0
                warn!("Build Failed.");
165

166 0
                exit(1);
167
            }
168 0
        })
169 8
        .level(log_level)
170 8
        .chain(stdout())
171
        .apply();
172

173 8
    if result.is_err() {
174 8
        println!("Unable to setup logger.");
175
    }
176 8
}

Read our documentation on viewing source code .

Loading