vergen_pretty/pretty/feature/
trace.rs

1// Copyright (c) 2022 vergen developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9#[cfg(feature = "color")]
10use super::color::{BOLD_BLUE, BOLD_GREEN};
11use crate::{Prefix, Suffix, pretty::Pretty};
12use tracing::{Level, event};
13
14impl Pretty {
15    /// Output the `vergen` environment variables that are set in table format to a tracing subscriber
16    ///
17    #[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
18    pub fn trace(mut self) {
19        self.populate_fmt();
20
21        if let Some(prefix) = &self.prefix {
22            prefix.trace();
23        }
24
25        for (category, label, value) in &self.vars {
26            let key = format!(
27                "{label:>0$} ({category:>1$})",
28                self.max_label, self.max_category
29            );
30            self.inner_trace(&key, value);
31        }
32
33        if let Some(suffix) = &self.suffix {
34            suffix.trace();
35        }
36    }
37
38    #[cfg(feature = "color")]
39    fn inner_trace(&self, key: &str, value: &str) {
40        let key = if let Some(style) = &self.key_style {
41            style
42        } else {
43            &BOLD_BLUE
44        }
45        .apply_to(key);
46        let value = if let Some(style) = &self.value_style {
47            style
48        } else {
49            &BOLD_GREEN
50        }
51        .apply_to(value);
52        match self.level {
53            Level::DEBUG => event!(Level::DEBUG, "{key}: {value}"),
54            Level::ERROR => event!(Level::ERROR, "{key}: {value}"),
55            Level::INFO => event!(Level::INFO, "{key}: {value}"),
56            Level::TRACE => event!(Level::TRACE, "{key}: {value}"),
57            Level::WARN => event!(Level::WARN, "{key}: {value}"),
58        }
59    }
60
61    #[cfg(not(feature = "color"))]
62    fn inner_trace(&self, key: &str, value: &str) {
63        match self.level {
64            Level::DEBUG => event!(Level::DEBUG, "{key}: {value}"),
65            Level::ERROR => event!(Level::ERROR, "{key}: {value}"),
66            Level::INFO => event!(Level::INFO, "{key}: {value}"),
67            Level::TRACE => event!(Level::TRACE, "{key}: {value}"),
68            Level::WARN => event!(Level::WARN, "{key}: {value}"),
69        }
70    }
71}
72
73impl Prefix {
74    /// Output the `vergen` environment variables that are set in table format to a tracing subscriber
75    ///
76    pub(crate) fn trace(&self) {
77        self.inner_trace();
78    }
79
80    #[cfg(feature = "color")]
81    fn inner_trace(&self) {
82        for line in &self.lines {
83            let line = if let Some(style) = &self.style {
84                format!("{}", style.apply_to(line))
85            } else {
86                line.clone()
87            };
88            match self.level {
89                Level::DEBUG => event!(Level::DEBUG, "{line}"),
90                Level::ERROR => event!(Level::ERROR, "{line}"),
91                Level::INFO => event!(Level::INFO, "{line}"),
92                Level::TRACE => event!(Level::TRACE, "{line}"),
93                Level::WARN => event!(Level::WARN, "{line}"),
94            }
95        }
96    }
97
98    #[cfg(not(feature = "color"))]
99    fn inner_trace(&self) {
100        for line in &self.lines {
101            match self.level {
102                Level::DEBUG => event!(Level::DEBUG, "{line}"),
103                Level::ERROR => event!(Level::ERROR, "{line}"),
104                Level::INFO => event!(Level::INFO, "{line}"),
105                Level::TRACE => event!(Level::TRACE, "{line}"),
106                Level::WARN => event!(Level::WARN, "{line}"),
107            }
108        }
109    }
110}
111
112impl Suffix {
113    /// Output the `vergen` environment variables that are set in table format to a tracing subscriber
114    ///
115    pub(crate) fn trace(&self) {
116        self.inner_trace();
117    }
118
119    #[cfg(feature = "color")]
120    fn inner_trace(&self) {
121        for line in &self.lines {
122            let line = if let Some(style) = &self.style {
123                format!("{}", style.apply_to(line))
124            } else {
125                line.clone()
126            };
127            match self.level {
128                Level::DEBUG => event!(Level::DEBUG, "{line}"),
129                Level::ERROR => event!(Level::ERROR, "{line}"),
130                Level::INFO => event!(Level::INFO, "{line}"),
131                Level::TRACE => event!(Level::TRACE, "{line}"),
132                Level::WARN => event!(Level::WARN, "{line}"),
133            }
134        }
135    }
136
137    #[cfg(not(feature = "color"))]
138    fn inner_trace(&self) {
139        for line in &self.lines {
140            match self.level {
141                Level::DEBUG => event!(Level::DEBUG, "{line}"),
142                Level::ERROR => event!(Level::ERROR, "{line}"),
143                Level::INFO => event!(Level::INFO, "{line}"),
144                Level::TRACE => event!(Level::TRACE, "{line}"),
145                Level::WARN => event!(Level::WARN, "{line}"),
146            }
147        }
148    }
149}
150
151#[cfg(test)]
152mod test {
153    use crate::{Prefix, Pretty, Suffix, utils::test_utils::TEST_PREFIX_SUFFIX, vergen_pretty_env};
154    #[cfg(feature = "color")]
155    use console::Style;
156    use std::sync::Once;
157    use tracing::{Level, metadata::LevelFilter};
158    use tracing_subscriber::{
159        fmt, prelude::__tracing_subscriber_SubscriberExt, registry, util::SubscriberInitExt,
160    };
161
162    static INIT_TRACING: Once = Once::new();
163
164    fn initialize_tracing() {
165        INIT_TRACING.call_once(|| {
166            let format = fmt::layer().compact().with_level(true).with_ansi(true);
167            let filter_layer = LevelFilter::from(Level::TRACE);
168            registry()
169                .with(format)
170                .with(filter_layer)
171                .try_init()
172                .expect("unable to initialize tracing");
173        });
174    }
175
176    #[test]
177    fn default_trace_works() {
178        initialize_tracing();
179        Pretty::builder().env(vergen_pretty_env!()).build().trace();
180    }
181
182    #[test]
183    fn trace_debug_works() {
184        initialize_tracing();
185        let level = Level::DEBUG;
186        let prefix = Prefix::builder()
187            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
188            .level(level)
189            .build();
190        let suffix = Suffix::builder()
191            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
192            .level(level)
193            .build();
194        Pretty::builder()
195            .env(vergen_pretty_env!())
196            .level(level)
197            .prefix(prefix)
198            .suffix(suffix)
199            .build()
200            .trace();
201    }
202
203    #[test]
204    fn default_trace_trace_works() {
205        initialize_tracing();
206        let level = Level::TRACE;
207        let prefix = Prefix::builder()
208            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
209            .level(level)
210            .build();
211        let suffix = Suffix::builder()
212            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
213            .level(level)
214            .build();
215        Pretty::builder()
216            .env(vergen_pretty_env!())
217            .level(level)
218            .prefix(prefix)
219            .suffix(suffix)
220            .build()
221            .trace();
222    }
223
224    #[test]
225    fn default_trace_error_works() {
226        initialize_tracing();
227        let level = Level::ERROR;
228        let prefix = Prefix::builder()
229            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
230            .level(level)
231            .build();
232        let suffix = Suffix::builder()
233            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
234            .level(level)
235            .build();
236        Pretty::builder()
237            .env(vergen_pretty_env!())
238            .level(level)
239            .prefix(prefix)
240            .suffix(suffix)
241            .build()
242            .trace();
243    }
244
245    #[test]
246    fn default_trace_warn_works() {
247        initialize_tracing();
248        let level = Level::WARN;
249        let prefix = Prefix::builder()
250            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
251            .level(level)
252            .build();
253        let suffix = Suffix::builder()
254            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
255            .level(level)
256            .build();
257        Pretty::builder()
258            .env(vergen_pretty_env!())
259            .level(level)
260            .prefix(prefix)
261            .suffix(suffix)
262            .build()
263            .trace();
264    }
265
266    #[test]
267    #[cfg(feature = "color")]
268    fn trace_key_style_works() {
269        initialize_tracing();
270        let red_bold = Style::new().bold().red();
271        Pretty::builder()
272            .env(vergen_pretty_env!())
273            .key_style(red_bold)
274            .build()
275            .trace();
276    }
277
278    #[test]
279    #[cfg(feature = "color")]
280    fn trace_value_style_works() {
281        initialize_tracing();
282        let red_bold = Style::new().bold().red();
283        Pretty::builder()
284            .env(vergen_pretty_env!())
285            .value_style(red_bold)
286            .build()
287            .trace();
288    }
289
290    #[test]
291    fn trace_prefix_works() {
292        initialize_tracing();
293        let prefix = Prefix::builder()
294            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
295            .build();
296        Pretty::builder()
297            .env(vergen_pretty_env!())
298            .prefix(prefix)
299            .build()
300            .trace();
301    }
302
303    #[cfg(feature = "color")]
304    #[test]
305    fn trace_prefix_with_style_works() {
306        initialize_tracing();
307        let red_bold = Style::new().bold().red();
308        let prefix = Prefix::builder()
309            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
310            .style(red_bold)
311            .build();
312        Pretty::builder()
313            .env(vergen_pretty_env!())
314            .prefix(prefix)
315            .build()
316            .trace();
317    }
318
319    #[test]
320    fn trace_suffix_works() {
321        initialize_tracing();
322        let suffix = Suffix::builder()
323            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
324            .build();
325        Pretty::builder()
326            .env(vergen_pretty_env!())
327            .suffix(suffix)
328            .build()
329            .trace();
330    }
331
332    #[cfg(feature = "color")]
333    #[test]
334    fn trace_suffix_with_style_works() {
335        initialize_tracing();
336        let red_bold = Style::new().bold().red();
337        let suffix = Suffix::builder()
338            .lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
339            .style(red_bold)
340            .build();
341        Pretty::builder()
342            .env(vergen_pretty_env!())
343            .suffix(suffix)
344            .build()
345            .trace();
346    }
347
348    #[test]
349    fn trace_with_filter_works() {
350        initialize_tracing();
351        Pretty::builder()
352            .env(vergen_pretty_env!())
353            .filter(vec!["VERGEN_GIT_BRANCH", "VERGEN_SYSINFO_USER"])
354            .build()
355            .trace();
356    }
357}