Skip to main content

nextest_runner/show_config/
nextest_version.rs

1// Copyright (c) The nextest Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4use crate::{
5    config::core::{
6        ConfigSource, ConfigSourceKind, ConfigStyles, NextestVersionConfig, NextestVersionEval,
7        NextestVersionReq,
8    },
9    write_str::WriteStr,
10};
11use owo_colors::{OwoColorize, Style};
12use semver::Version;
13use std::io;
14
15/// Show version-related configuration.
16pub struct ShowNextestVersion<'a> {
17    version_cfg: &'a NextestVersionConfig,
18    current_version: &'a Version,
19    override_version_check: bool,
20}
21
22impl<'a> ShowNextestVersion<'a> {
23    /// Construct a new [`ShowNextestVersion`].
24    pub fn new(
25        version_cfg: &'a NextestVersionConfig,
26        current_version: &'a Version,
27        override_version_check: bool,
28    ) -> Self {
29        Self {
30            version_cfg,
31            current_version,
32            override_version_check,
33        }
34    }
35
36    /// Write the version configuration in human-readable form.
37    pub fn write_human(&self, writer: &mut dyn WriteStr, colorize: bool) -> io::Result<()> {
38        let mut styles = Styles::default();
39        if colorize {
40            styles.colorize();
41        }
42
43        writeln!(
44            writer,
45            "current nextest version: {}",
46            self.current_version.style(styles.version)
47        )?;
48
49        write!(writer, "version requirements:")?;
50
51        let mut any_requirements = false;
52        if let NextestVersionReq::Version { version, source } = &self.version_cfg.required {
53            if !any_requirements {
54                writeln!(writer)?;
55            }
56            any_requirements = true;
57            write!(writer, "    - required: {}", version.style(styles.version))?;
58            self.write_source(writer, source, &styles)?;
59        }
60
61        if let NextestVersionReq::Version { version, source } = &self.version_cfg.recommended {
62            if !any_requirements {
63                writeln!(writer)?;
64            }
65            any_requirements = true;
66            write!(
67                writer,
68                "    - recommended: {}",
69                version.style(styles.version)
70            )?;
71            self.write_source(writer, source, &styles)?;
72        }
73
74        if any_requirements {
75            write!(writer, "evaluation result: ")?;
76            let eval = self
77                .version_cfg
78                .eval(self.current_version, self.override_version_check);
79            match eval {
80                NextestVersionEval::Satisfied => {
81                    writeln!(writer, "{}", "ok".style(styles.satisfied))?;
82                }
83                NextestVersionEval::Error { .. } => {
84                    writeln!(
85                        writer,
86                        "{}",
87                        "does not meet required version".style(styles.error)
88                    )?;
89                }
90                NextestVersionEval::Warn { .. } => {
91                    writeln!(
92                        writer,
93                        "{}",
94                        "does not meet recommended version".style(styles.warning)
95                    )?;
96                }
97                NextestVersionEval::ErrorOverride { .. } => {
98                    writeln!(
99                        writer,
100                        "does not meet required version, but is {}",
101                        "overridden".style(styles.overridden),
102                    )?;
103                }
104                crate::config::core::NextestVersionEval::WarnOverride { .. } => {
105                    writeln!(
106                        writer,
107                        "does not meet recommended version, but is {}",
108                        "overridden".style(styles.overridden),
109                    )?;
110                }
111            }
112        } else {
113            writeln!(writer, " (none)")?;
114        }
115
116        Ok(())
117    }
118
119    fn write_source(
120        &self,
121        writer: &mut dyn WriteStr,
122        source: &ConfigSource,
123        styles: &Styles,
124    ) -> io::Result<()> {
125        match source.kind() {
126            ConfigSourceKind::Tool(tool) => {
127                writeln!(writer, " (by tool {})", tool.style(styles.config.tool))
128            }
129            ConfigSourceKind::ExplicitRepository | ConfigSourceKind::DiscoveredRepository => {
130                writeln!(
131                    writer,
132                    " (from {})",
133                    source.path().display().style(styles.config.path)
134                )
135            }
136        }
137    }
138}
139
140#[derive(Clone, Debug, Default)]
141struct Styles {
142    version: Style,
143    config: ConfigStyles,
144    satisfied: Style,
145    error: Style,
146    warning: Style,
147    overridden: Style,
148}
149
150impl Styles {
151    fn colorize(&mut self) {
152        self.version = Style::new().bold();
153        self.config.colorize();
154        self.satisfied = Style::new().bold().green();
155        self.error = Style::new().bold().red();
156        self.warning = Style::new().bold().yellow();
157        self.overridden = Style::new().bold();
158    }
159}