Skip to content

Commit

Permalink
Initial implementation of stderr logging (#1654)
Browse files Browse the repository at this point in the history
* Initial implementation of stderr logging

* prepare for release
  • Loading branch information
xd009642 authored Nov 29, 2024
1 parent 4bf70fa commit bf43ef3
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 26 deletions.
12 changes: 6 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
From 2019 onwards, all notable changes to tarpaulin will be documented in this
file.

## [Unreleased]
### Changed
- For `LD_LIBRARY_PATH` get all link paths from build script outputs
- Use `PATH` on windows and `DYLIB_LIBRARY_PATH` for mac instead of `LD_LIBRARY_PATH`

## [0.31.3] 2024-10-10
## [0.31.3] 2024-11-29
### Added
- The `CARGO_TARPAULIN_CONFIG_FILE` environment variable may be used to set the
path to the configuration file. The command line argument has precedence,
but this environment variable has precedence over `tarpaulin.toml` and `.tarpaulin.toml`.

### Changed
- For `LD_LIBRARY_PATH` get all link paths from build script outputs
- Use `PATH` on windows and `DYLIB_LIBRARY_PATH` for mac instead of `LD_LIBRARY_PATH`
- Add `--stderr` flag to print tarpaulin logs to stderr

## [0.31.2] 2024-08-20
### Changed
- Removed debug printout of function map
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cargo-tarpaulin"
version = "0.31.2"
version = "0.31.3"
authors = ["Daniel McKenna <[email protected]>"]
description = "Cargo-Tarpaulin is a tool to determine code coverage achieved via tests"
repository = "https://github.com/xd009642/tarpaulin"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Options:
--debug Show debug output - this is used for diagnosing issues with tarpaulin
-v, --verbose Show extra output
--dump-traces Log tracing events and save to a json file. Also, enabled when --debug is used
--stderr Print tarpaulin logs to stderr instead - test output will still be printed to stdout
--run-types <TYPE> Type of the coverage run [possible values: Tests, Doctests, Benchmarks, Examples, Lib, Bins, AllTargets]
--benches Test all benches
--doc Test only this library's documentation
Expand Down
3 changes: 3 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ pub struct LoggingArgs {
/// Log tracing events and save to a json file. Also, enabled when --debug is used
#[arg(long)]
pub dump_traces: bool,
/// Print tarpaulin logs to stderr instead - test output will still be printed to stdout
#[arg(long)]
pub stderr: bool,
}

#[derive(Debug, Clone, Copy, Args)]
Expand Down
5 changes: 5 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ pub struct Config {
profraw_folder: PathBuf,
/// Option to fail immediately after a single test fails
pub fail_immediately: bool,
/// Log to stderr instead
pub stderr: bool,
}

fn default_test_timeout() -> Duration {
Expand Down Expand Up @@ -264,6 +266,7 @@ impl Default for Config {
objects: vec![],
profraw_folder: PathBuf::from("profraws"),
fail_immediately: false,
stderr: false,
}
}
}
Expand Down Expand Up @@ -351,6 +354,7 @@ impl From<ConfigArgs> for ConfigWrapper {
objects: canonicalize_paths(args.objects),
profraw_folder: PathBuf::from("profraws"),
fail_immediately: args.fail_immediately,
stderr: args.logging.stderr,
};
if args.ignore_config {
Self(vec![args_config])
Expand Down Expand Up @@ -614,6 +618,7 @@ impl Config {
self.branch_coverage |= other.branch_coverage;
self.dump_traces |= other.dump_traces;
self.offline |= other.offline;
self.stderr |= other.stderr;
if self.manifest != other.manifest && self.manifest == default_manifest() {
self.manifest = other.manifest.clone();
}
Expand Down
14 changes: 10 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::test_loader::*;
use crate::traces::*;
use std::ffi::OsString;
use std::fs::{create_dir_all, remove_dir_all};
use std::io;
use tracing::{debug, error, info, warn};
use tracing_subscriber::{filter::LevelFilter, EnvFilter};

Expand All @@ -29,7 +30,7 @@ pub mod traces;
const RUST_LOG_ENV: &str = "RUST_LOG";

#[cfg(not(tarpaulin_include))]
pub fn setup_logging(color: Color, debug: bool, verbose: bool) {
pub fn setup_logging(color: Color, debug: bool, verbose: bool, stderr: bool) {
//By default, we set tarpaulin to info,debug,trace while all dependencies stay at INFO
let base_exceptions = |env: EnvFilter| {
if debug {
Expand Down Expand Up @@ -66,11 +67,16 @@ pub fn setup_logging(color: Color, debug: bool, verbose: bool) {

let with_ansi = color != Color::Never;

let res = tracing_subscriber::FmtSubscriber::builder()
let builder = tracing_subscriber::FmtSubscriber::builder()
.with_max_level(tracing::Level::ERROR)
.with_env_filter(filter)
.with_ansi(with_ansi)
.try_init();
.with_ansi(with_ansi);

let res = if stderr {
builder.with_writer(io::stderr).try_init()
} else {
builder.try_init()
};

if let Err(e) = res {
eprintln!("Logging may be misconfigured: {e}");
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ fn main() -> Result<(), String> {
logging_args.color.unwrap_or(Color::Auto),
logging_args.debug,
logging_args.verbose,
logging_args.stderr,
);

let config = ConfigWrapper::from(args.config);
Expand Down
45 changes: 32 additions & 13 deletions src/report/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::traces::*;
use cargo_metadata::Metadata;
use serde::Serialize;
use std::fs::{create_dir_all, File};
use std::io::BufReader;
use std::io::{self, BufReader, Write};
use tracing::{error, info};

pub mod cobertura;
Expand Down Expand Up @@ -108,7 +108,12 @@ fn generate_requested_reports(config: &Config, result: &TraceMap) -> Result<(),
}

fn print_missing_lines(config: &Config, result: &TraceMap) {
println!("|| Uncovered Lines:");
let mut w: Box<dyn Write> = if config.stderr {
Box::new(io::stderr().lock())
} else {
Box::new(io::stdout().lock())
};
writeln!(w, "|| Uncovered Lines:").unwrap();
for (key, value) in result.iter() {
let path = config.strip_base_dir(key);
let mut uncovered_lines = vec![];
Expand All @@ -123,7 +128,7 @@ fn print_missing_lines(config: &Config, result: &TraceMap) {
.fold((vec![], vec![]), accumulate_lines);
let (groups, _) = accumulate_lines((groups, last_group), u64::max_value());
if !groups.is_empty() {
println!("|| {}: {}", path.display(), groups.join(", "));
writeln!(w, "|| {}: {}", path.display(), groups.join(", ")).unwrap();
}
}
}
Expand All @@ -147,11 +152,17 @@ fn get_previous_result(config: &Config) -> Option<TraceMap> {
}

fn print_summary(config: &Config, result: &TraceMap) {
let mut w: Box<dyn Write> = if config.stderr {
Box::new(io::stderr().lock())
} else {
Box::new(io::stdout().lock())
};
let last = match get_previous_result(config) {
Some(l) => l,
None => TraceMap::new(),
};
println!("|| Tested/Total Lines:");
// All the `writeln` unwraps are fine, it's basically what the `println` macro does
writeln!(w, "|| Tested/Total Lines:").unwrap();
for file in result.files() {
if result.coverable_in_path(file) == 0 {
continue;
Expand All @@ -161,41 +172,49 @@ fn print_summary(config: &Config, result: &TraceMap) {
let last_percent = coverage_percentage(last.get_child_traces(file));
let current_percent = coverage_percentage(result.get_child_traces(file));
let delta = 100.0f64 * (current_percent - last_percent);
println!(
writeln!(
w,
"|| {}: {}/{} {:+.2}%",
path.display(),
result.covered_in_path(file),
result.coverable_in_path(file),
delta
);
)
.unwrap();
} else {
println!(
writeln!(
w,
"|| {}: {}/{}",
path.display(),
result.covered_in_path(file),
result.coverable_in_path(file)
);
)
.unwrap();
}
}
let percent = result.coverage_percentage() * 100.0f64;
if result.total_coverable() == 0 {
println!("No coverable lines found");
writeln!(w, "No coverable lines found").unwrap();
} else if last.is_empty() {
println!(
writeln!(
w,
"|| \n{:.2}% coverage, {}/{} lines covered",
percent,
result.total_covered(),
result.total_coverable()
);
)
.unwrap();
} else {
let delta = percent - 100.0f64 * last.coverage_percentage();
println!(
writeln!(
w,
"|| \n{:.2}% coverage, {}/{} lines covered, {:+.2}% change in coverage",
percent,
result.total_covered(),
result.total_coverable(),
delta
);
)
.unwrap();
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn check_percentage_with_config(

// Note to contributors. If an integration test fails, uncomment this to be able to see the
// tarpaulin logs
//cargo_tarpaulin::setup_logging(true, true);
//cargo_tarpaulin::setup_logging(true, true, false);
let event_log = if config.dump_traces {
let mut paths = HashSet::new();
paths.insert(config.manifest());
Expand Down

0 comments on commit bf43ef3

Please sign in to comment.