Skip to content

Commit

Permalink
Enable suppressing all output ("silent mode") (#592)
Browse files Browse the repository at this point in the history
* feat: add silent mode

* rename log to log_info, log_level None as silent

* fix log levels to keep original behaviour, fix nits

* Remove leftover `silent` field.

---------

Co-authored-by: Predrag Gruevski <[email protected]>
  • Loading branch information
markhaehnel and obi1kenobi authored Dec 8, 2023
1 parent f47ce50 commit 745f4ae
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 88 deletions.
134 changes: 79 additions & 55 deletions src/check_release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub(super) fn run_check_release(
),
)?;
config
.verbose(|config| {
.log_verbose(|config| {
config.shell_status(
"Starting",
format_args!(
Expand All @@ -153,7 +153,7 @@ pub(super) fn run_check_release(
RequiredSemverUpdate::Minor => "minor",
};
config
.verbose(|config| {
.log_verbose(|config| {
if config.is_stderr_tty() {
colored!(
config.stderr(),
Expand Down Expand Up @@ -182,7 +182,7 @@ pub(super) fn run_check_release(

if peeked.is_none() {
config
.verbose(|config| {
.log_verbose(|config| {
if config.is_stderr_tty() {
write!(config.stderr(), "\r")?;
}
Expand All @@ -206,7 +206,7 @@ pub(super) fn run_check_release(
queries_with_errors.push(QueryWithResults::new(query_id.as_str(), results_iter));

config
.verbose(|config| {
.log_verbose(|config| {
if config.is_stderr_tty() {
write!(config.stderr(), "\r")?;
}
Expand Down Expand Up @@ -251,58 +251,72 @@ pub(super) fn run_check_release(
for query_with_results in queries_with_errors {
let semver_query = &queries[query_with_results.name];
required_versions.push(semver_query.required_update);
colored_ln(config.stdout(), |w| {
colored!(
w,
"\n--- failure {}: {} ---\n",
&semver_query.id,
&semver_query.human_readable_name,
)
})
.expect("print failed");
config
.log_info(|config| {
colored_ln(config.stdout(), |w| {
colored!(
w,
"\n--- failure {}: {} ---\n",
&semver_query.id,
&semver_query.human_readable_name,
)
})?;
Ok(())
})
.expect("print failed");

if let Some(ref_link) = semver_query.reference_link.as_deref() {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}Description:{}\n{}\n{:>12} {}\n{:>12} {}\n",
bold!(true),
reset!(),
&semver_query.error_message,
"ref:",
ref_link,
"impl:",
format!(
"https://github.com/obi1kenobi/cargo-semver-checks/tree/v{}/src/lints/{}.ron",
crate_version!(),
semver_query.id,
config.log_info(|config| {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}Description:{}\n{}\n{:>12} {}\n{:>12} {}\n",
bold!(true),
reset!(),
&semver_query.error_message,
"ref:",
ref_link,
"impl:",
format!(
"https://github.com/obi1kenobi/cargo-semver-checks/tree/v{}/src/lints/{}.ron",
crate_version!(),
semver_query.id,
)
)
)
})?;
Ok(())
})
.expect("print failed");
} else {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}Description:{}\n{}\n{:>12} {}\n",
bold!(true),
reset!(),
&semver_query.error_message,
"impl:",
format!(
"https://github.com/obi1kenobi/cargo-semver-checks/tree/v{}/src/lints/{}.ron",
crate_version!(),
semver_query.id,
config.log_info(|config| {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}Description:{}\n{}\n{:>12} {}\n",
bold!(true),
reset!(),
&semver_query.error_message,
"impl:",
format!(
"https://github.com/obi1kenobi/cargo-semver-checks/tree/v{}/src/lints/{}.ron",
crate_version!(),
semver_query.id,
)
)
)
})?;
Ok(())
})
.expect("print failed");
}

colored_ln(config.stdout(), |w| {
colored!(w, "{}Failed in:{}", bold!(true), reset!(),)
})
.expect("print failed");
config
.log_info(|config| {
colored_ln(config.stdout(), |w| {
colored!(w, "{}Failed in:{}", bold!(true), reset!())
})?;
Ok(())
})
.expect("print failed");

let start_instant = std::time::Instant::now();
for semver_violation_result in query_with_results.results {
Expand All @@ -317,11 +331,15 @@ pub(super) fn run_check_release(
.render_template(template, &pretty_result)
.context("Error instantiating semver query template.")
.expect("could not materialize template");
colored_ln(config.stdout(), |w| colored!(w, " {}", message,))
config
.log_info(|config| {
colored_ln(config.stdout(), |w| colored!(w, " {}", message,))?;
Ok(())
})
.expect("print failed");

config
.extra_verbose(|config| {
.log_extra_verbose(|config| {
colored_ln(config.stdout(), |w| {
let serde_pretty = serde_json::to_string_pretty(&pretty_result)
.expect("serde failed");
Expand All @@ -335,14 +353,20 @@ pub(super) fn run_check_release(
})
.expect("print failed");
} else {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}\n",
serde_json::to_string_pretty(&pretty_result).expect("serde failed"),
)
})
.expect("print failed");
config
.log_info(|config| {
colored_ln(config.stdout(), |w| {
colored!(
w,
"{}\n",
serde_json::to_string_pretty(&pretty_result)
.expect("serde failed"),
)
})
.expect("print failed");
Ok(())
})
.expect("print failed");
}
}
total_duration += start_instant.elapsed();
Expand Down
109 changes: 85 additions & 24 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,19 @@ impl GlobalConfig {
self
}

pub fn is_info(&self) -> bool {
self.level.is_some() && self.level.unwrap() >= log::Level::Info
}

pub fn is_verbose(&self) -> bool {
log::Level::Debug <= self.level.unwrap_or(log::Level::Error)
self.level.is_some() && self.level.unwrap() >= log::Level::Debug
}

pub fn is_extra_verbose(&self) -> bool {
self.level.is_some() && self.level.unwrap() >= log::Level::Trace
}

pub fn verbose(
pub fn log_verbose(
&mut self,
callback: impl Fn(&mut Self) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
Expand All @@ -83,15 +91,21 @@ impl GlobalConfig {
Ok(())
}

pub fn is_extra_verbose(&self) -> bool {
log::Level::Trace <= self.level.unwrap_or(log::Level::Error)
pub fn log_extra_verbose(
&mut self,
callback: impl Fn(&mut Self) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
if self.is_extra_verbose() {
callback(self)?;
}
Ok(())
}

pub fn extra_verbose(
pub fn log_info(
&mut self,
callback: impl Fn(&mut Self) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
if self.is_extra_verbose() {
if self.is_info() {
callback(self)?;
}
Ok(())
Expand All @@ -117,25 +131,27 @@ impl GlobalConfig {
color: termcolor::Color,
justified: bool,
) -> anyhow::Result<()> {
use std::io::Write;
use termcolor::WriteColor;

self.stderr().set_color(
termcolor::ColorSpec::new()
.set_fg(Some(color))
.set_bold(true),
)?;
if justified {
write!(self.stderr(), "{status:>12}")?;
} else {
write!(self.stderr(), "{status}")?;
self.stderr()
.set_color(termcolor::ColorSpec::new().set_bold(true))?;
write!(self.stderr(), ":")?;
if self.is_info() {
use std::io::Write;
use termcolor::WriteColor;

self.stderr().set_color(
termcolor::ColorSpec::new()
.set_fg(Some(color))
.set_bold(true),
)?;
if justified {
write!(self.stderr(), "{status:>12}")?;
} else {
write!(self.stderr(), "{status}")?;
self.stderr()
.set_color(termcolor::ColorSpec::new().set_bold(true))?;
write!(self.stderr(), ":")?;
}
self.stderr().reset()?;

writeln!(self.stderr(), " {message}")?;
}
self.stderr().reset()?;

writeln!(self.stderr(), " {message}")?;

Ok(())
}
Expand All @@ -157,3 +173,48 @@ impl GlobalConfig {
self.shell_print("warning", message, termcolor::Color::Yellow, false)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_log_level_info() {
let mut config = GlobalConfig::new();
config = config.set_level(Some(log::Level::Info));

assert!(config.is_info());
assert!(!config.is_verbose());
assert!(!config.is_extra_verbose());
}

#[test]
fn test_log_level_debug() {
let mut config = GlobalConfig::new();
config = config.set_level(Some(log::Level::Debug));

assert!(config.is_info());
assert!(config.is_verbose());
assert!(!config.is_extra_verbose());
}

#[test]
fn test_log_level_trace() {
let mut config = GlobalConfig::new();
config = config.set_level(Some(log::Level::Trace));

assert!(config.is_info());
assert!(config.is_verbose());
assert!(config.is_extra_verbose());
}

#[test]
fn test_log_level_none() {
let mut config = GlobalConfig::new();
config = config.set_level(None);

assert!(!config.is_info());
assert!(!config.is_verbose());
assert!(!config.is_extra_verbose());
}
}
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ impl Check {
self
}

pub fn with_log_level(&mut self, log_level: log::Level) -> &mut Self {
self.log_level = Some(log_level);
/// Set the log level.
/// If not set or set to `None`, logging is disabled.
pub fn with_log_level(&mut self, log_level: Option<log::Level>) -> &mut Self {
self.log_level = log_level;
self
}

Expand Down Expand Up @@ -354,9 +356,7 @@ impl Check {

pub fn check_release(&self) -> anyhow::Result<Report> {
let mut config = GlobalConfig::new().set_level(self.log_level);
let rustdoc_cmd = RustdocCommand::new()
.deps(false)
.silence(!config.is_verbose());
let rustdoc_cmd = RustdocCommand::new().deps(false).silence(config.is_info());

// If both the current and baseline rustdoc are given explicitly as a file path,
// we don't need to use the installed rustc, and this check can be skipped.
Expand Down Expand Up @@ -461,7 +461,7 @@ impl Check {
&& metadata.workspace_members.len() > 1
&& selected.publish == Some(vec![]);
if is_implied {
config.verbose(|config| {
config.log_verbose(|config| {
config.shell_status(
"Skipping",
format_args!("{crate_name} v{version} (current)"),
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,9 @@ impl From<CheckRelease> for cargo_semver_checks::Check {
if let Some(baseline) = custom_baseline {
check.with_baseline(baseline);
}
if let Some(log_level) = value.verbosity.log_level() {
check.with_log_level(log_level);
}

check.with_log_level(value.verbosity.log_level());

if let Some(release_type) = value.release_type {
check.with_release_type(release_type);
}
Expand Down

0 comments on commit 745f4ae

Please sign in to comment.