From c2ac4508ae05028a542c81f269230b0aa22f973b Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Fri, 24 Apr 2020 16:40:48 -0700 Subject: [PATCH 01/32] Initial commit of color-spantrace --- .gitignore | 2 + Cargo.toml | 16 +++++ examples/usage.rs | 21 ++++++ src/lib.rs | 161 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 examples/usage.rs create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a640afa --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "color-spantrace" +version = "0.1.0" +authors = ["Jane Lusby "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +console = "0.10.0" +tracing-error = "0.1.2" +tracing-core = "0.1.10" + +[dev-dependencies] +tracing-subscriber = "0.2.5" +tracing = "0.1.13" diff --git a/examples/usage.rs b/examples/usage.rs new file mode 100644 index 0000000..dd4863e --- /dev/null +++ b/examples/usage.rs @@ -0,0 +1,21 @@ +use tracing::instrument; +use tracing_error::{prelude::*, ErrorLayer, SpanTrace}; +use tracing_subscriber::{prelude::*, registry::Registry}; + +#[instrument] +fn main() { + Registry::default().with(ErrorLayer::default()).init(); + + let span_trace = one(42); + println!("{}", color_spantrace::colorize(&span_trace)); +} + +#[instrument] +fn one(i: u32) -> SpanTrace { + two() +} + +#[instrument] +fn two() -> SpanTrace { + SpanTrace::capture() +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..586ac24 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,161 @@ +use console::style; +use std::fmt; +use std::fs::File; +use std::io::{BufRead, BufReader, ErrorKind}; +use tracing_error::SpanTrace; + +pub fn colorize(span_trace: &SpanTrace) -> impl fmt::Display + '_ { + ColorSpanTrace { span_trace } +} + +struct ColorSpanTrace<'a> { + span_trace: &'a SpanTrace, +} + +macro_rules! try_bool { + ($e:expr, $dest:ident) => {{ + let ret = $e.unwrap_or_else(|e| $dest = Err(e)); + + if $dest.is_err() { + return false; + } + + ret + }}; +} + +struct Frame<'a> { + metadata: &'a tracing_core::Metadata<'static>, + fields: &'a str, +} + +/// Defines how verbose the backtrace is supposed to be. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +enum Verbosity { + /// Print a small message including the panic payload and the panic location. + Minimal, + /// Everything in `Minimal` and additionally print a backtrace. + Medium, + /// Everything in `Medium` plus source snippets for all backtrace locations. + Full, +} + +impl Verbosity { + /// Get the verbosity level from the `RUST_LIB_BACKTRACE` env variable. + fn from_env() -> Self { + match std::env::var("RUST_LIB_BACKTRACE") { + Ok(ref x) if x == "full" => Verbosity::Full, + Ok(_) => Verbosity::Medium, + Err(_) => Verbosity::Minimal, + } + } +} + +impl Frame<'_> { + fn print(&self, i: u32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.print_header(i, f)?; + self.print_fields(f)?; + self.print_source_location(f)?; + Ok(()) + } + + fn print_header(&self, i: u32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:>4}: {}", + i, + style(format_args!( + "{}::{}", + self.metadata.target(), + self.metadata.name() + )) + .red() + .dim() + ) + } + + fn print_fields(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if !self.fields.is_empty() { + write!(f, " with {}", style(self.fields).bold())?; + } + + Ok(()) + } + + fn print_source_location(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(file) = self.metadata.file() { + let lineno = self + .metadata + .line() + .map_or("".to_owned(), |x| x.to_string()); + write!(f, "\n at {}:{}", file, lineno)?; + } else { + write!(f, "\n at ")?; + } + + Ok(()) + } + + fn print_source_if_avail(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let (lineno, filename) = match (self.metadata.line(), self.metadata.file()) { + (Some(a), Some(b)) => (a, b), + // Without a line number and file name, we can't sensibly proceed. + _ => return Ok(()), + }; + + let file = match File::open(filename) { + Ok(file) => file, + Err(ref e) if e.kind() == ErrorKind::NotFound => return Ok(()), + e @ Err(_) => e.unwrap(), + }; + + // Extract relevant lines. + let reader = BufReader::new(file); + let start_line = lineno - 2.min(lineno - 1); + let surrounding_src = reader.lines().skip(start_line as usize - 1).take(5); + for (line, cur_line_no) in surrounding_src.zip(start_line..) { + if cur_line_no == lineno { + write!( + f, + "\n{}", + style(format_args!("{:>10} > {}", cur_line_no, line.unwrap())).bold() + )?; + } else { + write!(f, "\n{:>10} │ {}", cur_line_no, line.unwrap())?; + } + } + + Ok(()) + } +} + +impl fmt::Display for ColorSpanTrace<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut err = Ok(()); + let mut span = 0; + + let verbosity = Verbosity::from_env(); + + writeln!(f, "{:━^80}", " SPANTRACE ")?; + self.span_trace.with_spans(|metadata, fields| { + let frame = Frame { metadata, fields }; + + if span > 0 { + try_bool!(write!(f, "\n",), err); + } + + try_bool!(frame.print(span, f), err); + + match verbosity { + Verbosity::Full => try_bool!(frame.print_source_if_avail(f), err), + Verbosity::Medium => {} + Verbosity::Minimal => {} + } + + span += 1; + true + }); + + err + } +} From 20b490cd170a13e744dc32b2e069e11f271309f1 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Fri, 1 May 2020 11:26:45 -0700 Subject: [PATCH 02/32] update to match color-backtrace --- Cargo.toml | 1 + src/lib.rs | 62 +++++++++++++++++++++++++----------------------------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a640afa..a31ea1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" console = "0.10.0" tracing-error = "0.1.2" tracing-core = "0.1.10" +bat = "0.15.0" [dev-dependencies] tracing-subscriber = "0.2.5" diff --git a/src/lib.rs b/src/lib.rs index 586ac24..e2230a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ use console::style; +use std::env; use std::fmt; use std::fs::File; use std::io::{BufRead, BufReader, ErrorKind}; +use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use tracing_error::SpanTrace; pub fn colorize(span_trace: &SpanTrace) -> impl fmt::Display + '_ { @@ -29,26 +31,25 @@ struct Frame<'a> { fields: &'a str, } -/// Defines how verbose the backtrace is supposed to be. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -enum Verbosity { - /// Print a small message including the panic payload and the panic location. - Minimal, - /// Everything in `Minimal` and additionally print a backtrace. - Medium, - /// Everything in `Medium` plus source snippets for all backtrace locations. - Full, -} - -impl Verbosity { - /// Get the verbosity level from the `RUST_LIB_BACKTRACE` env variable. - fn from_env() -> Self { - match std::env::var("RUST_LIB_BACKTRACE") { - Ok(ref x) if x == "full" => Verbosity::Full, - Ok(_) => Verbosity::Medium, - Err(_) => Verbosity::Minimal, - } +fn enabled() -> bool { + // Cache the result of reading the environment variables to make + // backtrace captures speedy, because otherwise reading environment + // variables every time can be somewhat slow. + static ENABLED: AtomicUsize = AtomicUsize::new(0); + match ENABLED.load(SeqCst) { + 0 => {} + 1 => return false, + _ => return true, } + let enabled = match env::var("RUST_LIB_BACKTRACE") { + Ok(s) => s != "0", + Err(_) => match env::var("RUST_BACKTRACE") { + Ok(s) => s != "0", + Err(_) => false, + }, + }; + ENABLED.store(enabled as usize + 1, SeqCst); + return enabled; } impl Frame<'_> { @@ -62,7 +63,7 @@ impl Frame<'_> { fn print_header(&self, i: u32, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "{:>4}: {}", + "{:>2}: {}", i, style(format_args!( "{}::{}", @@ -70,13 +71,12 @@ impl Frame<'_> { self.metadata.name() )) .red() - .dim() ) } fn print_fields(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.fields.is_empty() { - write!(f, " with {}", style(self.fields).bold())?; + write!(f, " with {}", style(self.fields).cyan())?; } Ok(()) @@ -88,9 +88,9 @@ impl Frame<'_> { .metadata .line() .map_or("".to_owned(), |x| x.to_string()); - write!(f, "\n at {}:{}", file, lineno)?; + write!(f, "\n at {}:{}", file, lineno)?; } else { - write!(f, "\n at ")?; + write!(f, "\n at ")?; } Ok(()) @@ -118,10 +118,10 @@ impl Frame<'_> { write!( f, "\n{}", - style(format_args!("{:>10} > {}", cur_line_no, line.unwrap())).bold() + style(format_args!("{:>8} > {}", cur_line_no, line.unwrap())).bold() )?; } else { - write!(f, "\n{:>10} │ {}", cur_line_no, line.unwrap())?; + write!(f, "\n{:>8} │ {}", cur_line_no, line.unwrap())?; } } @@ -134,9 +134,7 @@ impl fmt::Display for ColorSpanTrace<'_> { let mut err = Ok(()); let mut span = 0; - let verbosity = Verbosity::from_env(); - - writeln!(f, "{:━^80}", " SPANTRACE ")?; + writeln!(f, "{:━^80}\n", " SPANTRACE ")?; self.span_trace.with_spans(|metadata, fields| { let frame = Frame { metadata, fields }; @@ -146,10 +144,8 @@ impl fmt::Display for ColorSpanTrace<'_> { try_bool!(frame.print(span, f), err); - match verbosity { - Verbosity::Full => try_bool!(frame.print_source_if_avail(f), err), - Verbosity::Medium => {} - Verbosity::Minimal => {} + if enabled() { + try_bool!(frame.print_source_if_avail(f), err); } span += 1; From efd40618c8dc3f915c77dc120aafe8e26d20b4af Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Fri, 1 May 2020 17:39:05 -0700 Subject: [PATCH 03/32] get that bat outtahere --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a31ea1d..a640afa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ edition = "2018" console = "0.10.0" tracing-error = "0.1.2" tracing-core = "0.1.10" -bat = "0.15.0" [dev-dependencies] tracing-subscriber = "0.2.5" From b7274c9f2fec9092863258d191a2b29a7ab9bf60 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 13:01:19 -0700 Subject: [PATCH 04/32] switch to ansi_term --- Cargo.toml | 2 +- src/lib.rs | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a640afa..43e96a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -console = "0.10.0" tracing-error = "0.1.2" tracing-core = "0.1.10" +ansi_term = "0.12.1" [dev-dependencies] tracing-subscriber = "0.2.5" diff --git a/src/lib.rs b/src/lib.rs index e2230a1..39e3927 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -use console::style; +use ansi_term::{Color::*, Style}; use std::env; use std::fmt; use std::fs::File; @@ -63,20 +63,17 @@ impl Frame<'_> { fn print_header(&self, i: u32, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "{:>2}: {}", + "{:>2}: {}{}{}", i, - style(format_args!( - "{}::{}", - self.metadata.target(), - self.metadata.name() - )) - .red() + Red.paint(self.metadata.target()), + Red.paint("::"), + Red.paint(self.metadata.name()), ) } fn print_fields(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.fields.is_empty() { - write!(f, " with {}", style(self.fields).cyan())?; + write!(f, " with {}", Cyan.paint(self.fields))?; } Ok(()) @@ -113,12 +110,15 @@ impl Frame<'_> { let reader = BufReader::new(file); let start_line = lineno - 2.min(lineno - 1); let surrounding_src = reader.lines().skip(start_line as usize - 1).take(5); + let bold = Style::new().bold(); for (line, cur_line_no) in surrounding_src.zip(start_line..) { if cur_line_no == lineno { write!( f, - "\n{}", - style(format_args!("{:>8} > {}", cur_line_no, line.unwrap())).bold() + "\n{:>8}{}{}", + bold.paint(cur_line_no.to_string()), + bold.paint(" > "), + bold.paint(line.unwrap()) )?; } else { write!(f, "\n{:>8} │ {}", cur_line_no, line.unwrap())?; From b0c867c7296f717d6fdadb59a208468b416a318d Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 13:23:34 -0700 Subject: [PATCH 05/32] Prep for release --- README.md | 104 +++++++++++++++++++++++++++++++++++++++++++ examples/usage.rs | 2 +- pictures/full.png | Bin 0 -> 115896 bytes pictures/minimal.png | Bin 0 -> 73705 bytes 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100644 pictures/full.png create mode 100644 pictures/minimal.png diff --git a/README.md b/README.md new file mode 100644 index 0000000..a932bf8 --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +color-spantrace +=============== + +[![Build Status][actions-badge]][actions-url] +[![Latest Version](https://img.shields.io/crates/v/color-spantrace.svg)](https://crates.io/crates/color-spantrace) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/color-spantrace) + +[actions-badge]: https://github.com/yaahc/color-spantrace/workflows/Continuous%20integration/badge.svg +[actions-url]: https://github.com/yaahc/color-spantrace/actions?query=workflow%3A%22Continuous+integration%22 + +A rust library for colorizing [`tracing_error::SpanTrace`] objects in the style +of [`color-backtrace`]. + +## Setup + +Add the following to your `Cargo.toml`: + +``` +[dependencies] +color-spantrace = "0.1" +tracing = "0.1.13" +tracing-error = "0.1.2" +tracing-subscriber = "0.2.5" +``` + +Setup a tracing subscriber with an `ErrorLayer`: + +```rust +use tracing_error::ErrorLayer; +use tracing_subscriber::{prelude::*, registry::Registry}; + +Registry::default().with(ErrorLayer::default()).init(); +``` + +Create spans and enter them: + +```rust +use tracing::instrument; +use tracing_error::SpanTrace; + +#[instrument] +fn foo() -> SpanTrace { + SpanTrace::capture() +} +``` + +And finally colorize the `SpanTrace`: + +```rust +println!("{}", color_spantrace::colorize(&span_trace)); +``` + +## Example + +This example is taken from `examples/usage.rs`: + +```rust +use tracing::instrument; +use tracing_error::{ErrorLayer, SpanTrace}; +use tracing_subscriber::{prelude::*, registry::Registry}; + +#[instrument] +fn main() { + Registry::default().with(ErrorLayer::default()).init(); + + let span_trace = one(42); + println!("{}", color_spantrace::colorize(&span_trace)); +} + +#[instrument] +fn one(i: u32) -> SpanTrace { + two() +} + +#[instrument] +fn two() -> SpanTrace { + SpanTrace::capture() +} +``` + +This creates the following output + +### Minimal Format + +![minimal format](./pictures/minimal.png) + +### Full Format + +![Full format](./pictures/full.png) + +#### License + + +Licensed under either of Apache License, Version +2.0 or MIT license at your option. + + +
+ + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in this crate by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + diff --git a/examples/usage.rs b/examples/usage.rs index dd4863e..21cca48 100644 --- a/examples/usage.rs +++ b/examples/usage.rs @@ -1,5 +1,5 @@ use tracing::instrument; -use tracing_error::{prelude::*, ErrorLayer, SpanTrace}; +use tracing_error::{ErrorLayer, SpanTrace}; use tracing_subscriber::{prelude::*, registry::Registry}; #[instrument] diff --git a/pictures/full.png b/pictures/full.png new file mode 100644 index 0000000000000000000000000000000000000000..489da117473aa044c5d7b18eacab696d9acf1dc6 GIT binary patch literal 115896 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

9&d#{&*Cj6xjU^M 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 Date: Wed, 6 May 2020 13:25:25 -0700 Subject: [PATCH 06/32] Add ci --- .github/workflows/ci.yml | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6b3c3f8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,81 @@ +on: [push, pull_request] + +name: Continuous integration + +jobs: + check: + name: Check + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + - uses: actions-rs/cargo@v1 + with: + command: check + + test: + name: Test Suite + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - nightly + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + - uses: actions-rs/cargo@v1 + with: + command: test + # - uses: actions-rs/cargo@v1 + # with: + # command: test + # args: --no-default-features + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings From b867bf4261b262495ad6a61d8480aac0c919f72e Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 13:27:01 -0700 Subject: [PATCH 07/32] Fix links in readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a932bf8..66a68d7 100644 --- a/README.md +++ b/README.md @@ -102,3 +102,6 @@ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +[`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html +[`color-spantrace`]: https://github.com/athre0z/color-backtrace From 6b58982ee5681198c9129bcc200bf02f9a9acb69 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 13:27:29 -0700 Subject: [PATCH 08/32] Fix link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66a68d7..cde1512 100644 --- a/README.md +++ b/README.md @@ -104,4 +104,4 @@ be dual licensed as above, without any additional terms or conditions. [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html -[`color-spantrace`]: https://github.com/athre0z/color-backtrace +[`color-backtrace`]: https://github.com/athre0z/color-backtrace From 2e78274bdb0a0f8c4eeeddbf71248ac81db4f3fb Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 14:54:27 -0700 Subject: [PATCH 09/32] clippy --- Cargo.toml | 5 +++++ src/lib.rs | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 43e96a5..611955d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,11 @@ name = "color-spantrace" version = "0.1.0" authors = ["Jane Lusby "] edition = "2018" +license = "MIT OR Apache-2.0" +description = "A pretty printer for tracing_error::SpanTrace based on color-backtrace" +repository = "https://github.com/yaahc/color-spantrace" +documentation = "https://docs.rs/color-spantrace" +readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/lib.rs b/src/lib.rs index 39e3927..5103e65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.0")] use ansi_term::{Color::*, Style}; use std::env; use std::fmt; @@ -49,7 +50,8 @@ fn enabled() -> bool { }, }; ENABLED.store(enabled as usize + 1, SeqCst); - return enabled; + + enabled } impl Frame<'_> { From 208cb84f69c438d70f32488daeffff90655146ec Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 15:51:03 -0700 Subject: [PATCH 10/32] final prep before release --- README.md | 5 ++++- src/lib.rs | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cde1512..9a913c8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ of [`color-backtrace`]. Add the following to your `Cargo.toml`: -``` +```toml [dependencies] color-spantrace = "0.1" tracing = "0.1.13" @@ -47,6 +47,9 @@ fn foo() -> SpanTrace { And finally colorize the `SpanTrace`: ```rust +use tracing_error::SpanTrace; + +let span_trace = SpanTrace::capture(); println!("{}", color_spantrace::colorize(&span_trace)); ``` diff --git a/src/lib.rs b/src/lib.rs index 5103e65..a045649 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,50 @@ +//! A rust library for colorizing [`tracing_error::SpanTrace`] objects in the style +//! of [`color-backtrace`]. +//! +//! ## Setup +//! +//! Add the following to your `Cargo.toml`: +//! +//! ```toml +//! [dependencies] +//! color-spantrace = "0.1" +//! tracing = "0.1.13" +//! tracing-error = "0.1.2" +//! tracing-subscriber = "0.2.5" +//! ``` +//! +//! Setup a tracing subscriber with an `ErrorLayer`: +//! +//! ```rust +//! use tracing_error::ErrorLayer; +//! use tracing_subscriber::{prelude::*, registry::Registry}; +//! +//! Registry::default().with(ErrorLayer::default()).init(); +//! ``` +//! +//! Create spans and enter them: +//! +//! ```rust +//! use tracing::instrument; +//! use tracing_error::SpanTrace; +//! +//! #[instrument] +//! fn foo() -> SpanTrace { +//! SpanTrace::capture() +//! } +//! ``` +//! +//! And finally colorize the `SpanTrace`: +//! +//! ```rust +//! use tracing_error::SpanTrace; +//! +//! let span_trace = SpanTrace::capture(); +//! println!("{}", color_spantrace::colorize(&span_trace)); +//! ``` +//! +//! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html +//! [`color-backtrace`]: https://github.com/athre0z/color-backtrace #![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.0")] use ansi_term::{Color::*, Style}; use std::env; @@ -7,6 +54,21 @@ use std::io::{BufRead, BufReader, ErrorKind}; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use tracing_error::SpanTrace; +/// Display a [`SpanTrace`] with colors and source +/// +/// This function returns an `impl Display` type which can be then used in place of the original +/// SpanTrace when writing it too the screen or buffer. +/// +/// # Example +/// +/// ```rust +/// use tracing_error::SpanTrace; +/// +/// let span_trace = SpanTrace::capture(); +/// println!("{}", color_spantrace::colorize(&span_trace)); +/// ``` +/// +/// [`SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html pub fn colorize(span_trace: &SpanTrace) -> impl fmt::Display + '_ { ColorSpanTrace { span_trace } } From fb630e15741d46489a9b20a977059e5a79c4670d Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 6 May 2020 18:47:03 -0700 Subject: [PATCH 11/32] match color-backtrace behavior --- Cargo.toml | 2 +- src/lib.rs | 73 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 611955d..bddd51a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.0" +version = "0.1.1" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index a045649..d762ef6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,13 +45,35 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.0")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.1")] +#![warn( + missing_debug_implementations, + missing_docs, + missing_doc_code_examples, + rust_2018_idioms, + unreachable_pub, + bad_style, + const_err, + dead_code, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused, + unused_allocation, + unused_comparisons, + unused_parens, + while_true +)] use ansi_term::{Color::*, Style}; use std::env; use std::fmt; use std::fs::File; use std::io::{BufRead, BufReader, ErrorKind}; -use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use tracing_error::SpanTrace; /// Display a [`SpanTrace`] with colors and source @@ -94,26 +116,33 @@ struct Frame<'a> { fields: &'a str, } -fn enabled() -> bool { - // Cache the result of reading the environment variables to make - // backtrace captures speedy, because otherwise reading environment - // variables every time can be somewhat slow. - static ENABLED: AtomicUsize = AtomicUsize::new(0); - match ENABLED.load(SeqCst) { - 0 => {} - 1 => return false, - _ => return true, +/// Defines how verbose the backtrace is supposed to be. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +enum Verbosity { + /// Print a small message including the panic payload and the panic location. + Minimal, + /// Everything in `Minimal` and additionally print a backtrace. + Medium, + /// Everything in `Medium` plus source snippets for all backtrace locations. + Full, +} + +impl Verbosity { + fn lib_from_env() -> Self { + Self::convert_env( + env::var("RUST_LIB_BACKTRACE") + .or_else(|_| env::var("RUST_BACKTRACE")) + .ok(), + ) + } + + fn convert_env(env: Option) -> Self { + match env { + Some(ref x) if x == "full" => Verbosity::Full, + Some(_) => Verbosity::Medium, + None => Verbosity::Minimal, + } } - let enabled = match env::var("RUST_LIB_BACKTRACE") { - Ok(s) => s != "0", - Err(_) => match env::var("RUST_BACKTRACE") { - Ok(s) => s != "0", - Err(_) => false, - }, - }; - ENABLED.store(enabled as usize + 1, SeqCst); - - enabled } impl Frame<'_> { @@ -208,7 +237,7 @@ impl fmt::Display for ColorSpanTrace<'_> { try_bool!(frame.print(span, f), err); - if enabled() { + if Verbosity::lib_from_env() == Verbosity::Full { try_bool!(frame.print_source_if_avail(f), err); } From 385547736aede053981e4ec9246961b96920a806 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Tue, 2 Jun 2020 18:07:53 -0700 Subject: [PATCH 12/32] fix intensity of colors (#2) --- Cargo.toml | 2 +- src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bddd51a..c73a80e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.1" +version = "0.1.2" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index d762ef6..7be5e23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,7 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.1")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.2")] #![warn( missing_debug_implementations, missing_docs, @@ -69,7 +69,10 @@ unused_parens, while_true )] -use ansi_term::{Color::*, Style}; +use ansi_term::{ + Color::{Cyan, Red}, + Style, +}; use std::env; use std::fmt; use std::fs::File; @@ -158,15 +161,15 @@ impl Frame<'_> { f, "{:>2}: {}{}{}", i, - Red.paint(self.metadata.target()), - Red.paint("::"), - Red.paint(self.metadata.name()), + Red.make_intense().paint(self.metadata.target()), + Red.make_intense().paint("::"), + Red.make_intense().paint(self.metadata.name()), ) } fn print_fields(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.fields.is_empty() { - write!(f, " with {}", Cyan.paint(self.fields))?; + write!(f, " with {}", Cyan.make_intense().paint(self.fields))?; } Ok(()) @@ -248,3 +251,35 @@ impl fmt::Display for ColorSpanTrace<'_> { err } } + +// TODO: remove when / if ansi_term merges these changes upstream +trait ColorExt { + fn make_intense(self) -> Self; +} + +impl ColorExt for ansi_term::Color { + fn make_intense(self) -> Self { + use ansi_term::Color::*; + + match self { + Black => Fixed(8), + Red => Fixed(9), + Green => Fixed(10), + Yellow => Fixed(11), + Blue => Fixed(12), + Purple => Fixed(13), + Cyan => Fixed(14), + White => Fixed(15), + Fixed(color) if color < 8 => Fixed(color + 8), + other => other, + } + } +} +impl ColorExt for ansi_term::Style { + fn make_intense(mut self) -> Self { + if let Some(color) = self.foreground { + self.foreground = Some(color.make_intense()); + } + self + } +} From 84615473ed48b4cdfd3936bfd421168d3e57e7bd Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Tue, 2 Jun 2020 18:45:04 -0700 Subject: [PATCH 13/32] Dedupdep (#3) * dedupe ansi_term dep * bump version for release --- Cargo.toml | 4 ++-- src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c73a80e..310e5c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.2" +version = "0.1.3" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" @@ -14,7 +14,7 @@ readme = "README.md" [dependencies] tracing-error = "0.1.2" tracing-core = "0.1.10" -ansi_term = "0.12.1" +ansi_term = "0.11" [dev-dependencies] tracing-subscriber = "0.2.5" diff --git a/src/lib.rs b/src/lib.rs index 7be5e23..f88b61e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,7 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.2")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.3")] #![warn( missing_debug_implementations, missing_docs, From 1f1aeb7773a206f97094f6d6a8597f3d2e1bcc62 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Thu, 25 Jun 2020 15:32:12 -0700 Subject: [PATCH 14/32] colorize line numbers and fix indentation issue (#7) --- src/lib.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f88b61e..1c1c937 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,7 +70,7 @@ while_true )] use ansi_term::{ - Color::{Cyan, Red}, + Color::{Cyan, Purple, Red}, Style, }; use std::env; @@ -181,7 +181,12 @@ impl Frame<'_> { .metadata .line() .map_or("".to_owned(), |x| x.to_string()); - write!(f, "\n at {}:{}", file, lineno)?; + write!( + f, + "\n at {}:{}", + Purple.paint(file), + Purple.paint(lineno) + )?; } else { write!(f, "\n at ")?; } @@ -202,20 +207,24 @@ impl Frame<'_> { e @ Err(_) => e.unwrap(), }; + use std::fmt::Write; + // Extract relevant lines. let reader = BufReader::new(file); let start_line = lineno - 2.min(lineno - 1); let surrounding_src = reader.lines().skip(start_line as usize - 1).take(5); let bold = Style::new().bold(); + let mut buf = String::new(); for (line, cur_line_no) in surrounding_src.zip(start_line..) { if cur_line_no == lineno { write!( - f, - "\n{:>8}{}{}", - bold.paint(cur_line_no.to_string()), - bold.paint(" > "), - bold.paint(line.unwrap()) + &mut buf, + "{:>8} > {}", + cur_line_no.to_string(), + line.unwrap() )?; + write!(f, "\n{}", bold.paint(&buf))?; + buf.clear(); } else { write!(f, "\n{:>8} │ {}", cur_line_no, line.unwrap())?; } From 07693446435e96fb748a362c6dcbad2cccc30518 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Sun, 5 Jul 2020 19:05:18 -0700 Subject: [PATCH 15/32] bump version for new release (#8) --- Cargo.toml | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 310e5c2..605d582 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.3" +version = "0.1.4" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index 1c1c937..82912e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,7 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.3")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.4")] #![warn( missing_debug_implementations, missing_docs, From a1335a718c8195ac1cc94a093210ebbb72d43e16 Mon Sep 17 00:00:00 2001 From: d4h0 <183805+d4h0@users.noreply.github.com> Date: Wed, 2 Dec 2020 05:58:10 +0400 Subject: [PATCH 16/32] Support for custom styles and owo_colors (#11) * init * Add missing test data * Implement requested changes * Rename test/styles.rs and tests/data/style_control.txt * bump version on owo-colors and run rustfmt * update control to include source lines * tweek the documentation a little * bump version and prep for release * (cargo-release) start next development iteration 0.1.6-alpha.0 Co-authored-by: d4h0 Co-authored-by: Jane Lusby --- CHANGELOG.md | 14 +++ Cargo.toml | 44 ++++++++- src/lib.rs | 175 ++++++++++++++++++++++++++--------- tests/data/theme_control.txt | 9 ++ tests/themes.rs | 92 ++++++++++++++++++ 5 files changed, 286 insertions(+), 48 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 tests/data/theme_control.txt create mode 100644 tests/themes.rs diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2e4c665 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [Unreleased] - ReleaseDate +### Added +- Support custom color themes for spantrace format + + +[Unreleased]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 diff --git a/Cargo.toml b/Cargo.toml index 605d582..49a10e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.4" +version = "0.1.6-alpha.0" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" @@ -14,8 +14,48 @@ readme = "README.md" [dependencies] tracing-error = "0.1.2" tracing-core = "0.1.10" -ansi_term = "0.11" +owo-colors = "1.2.0" +once_cell = "1.4.1" [dev-dependencies] tracing-subscriber = "0.2.5" tracing = "0.1.13" +ansi-parser = "0.6.5" # used for testing color schemes + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "Unreleased" +replace="{{version}}" + +[[package.metadata.release.pre-release-replacements]] +file = "src/lib.rs" +search = "#!\\[doc\\(html_root_url.*" +replace = "#![doc(html_root_url = \"https://docs.rs/{{crate_name}}/{{version}}\")]" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "\\.\\.\\.HEAD" +replace="...{{tag_name}}" +exactly = 1 + +[[package.metadata.release.pre-release-replacements]] +file = "CHANGELOG.md" +search = "ReleaseDate" +replace="{{date}}" + +[[package.metadata.release.pre-release-replacements]] +file="CHANGELOG.md" +search="" +replace="\n\n## [Unreleased] - ReleaseDate" +exactly=1 + +[[package.metadata.release.pre-release-replacements]] +file="CHANGELOG.md" +search="" +replace="\n[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD" +exactly=1 diff --git a/src/lib.rs b/src/lib.rs index 82912e5..16d2ea8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,20 @@ //! println!("{}", color_spantrace::colorize(&span_trace)); //! ``` //! +//! ## Output Format +//! +//! Running `examples/usage.rs` from the `color-spantrace` repo produces the following output: +//! +//!

 cargo run --example usage
+//!     Finished dev [unoptimized + debuginfo] target(s) in 0.04s
+//!      Running `target/debug/examples/usage`
+//! ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+//!
+//!  0: usage::two
+//!     at examples/usage.rs:18
+//!  1: usage::one with i=42
+//!     at examples/usage.rs:13
+//! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace #![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.4")] @@ -69,16 +83,109 @@ unused_parens, while_true )] -use ansi_term::{ - Color::{Cyan, Purple, Red}, - Style, -}; +use once_cell::sync::OnceCell; +use owo_colors::{style, Style}; use std::env; use std::fmt; use std::fs::File; use std::io::{BufRead, BufReader, ErrorKind}; use tracing_error::SpanTrace; +static THEME: OnceCell = OnceCell::new(); + +/// A struct that represents theme that is used by `color_spantrace` +#[derive(Debug, Copy, Clone, Default)] +pub struct Theme { + file: Style, + line_number: Style, + target: Style, + fields: Style, + active_line: Style, +} + +impl Theme { + /// Create blank theme + pub fn new() -> Self { + Self::default() + } + + /// A theme for a dark background. This is the default + pub fn dark() -> Self { + Self { + file: style().purple(), + line_number: style().purple(), + active_line: style().white().bold(), + target: style().bright_red(), + fields: style().bright_cyan(), + } + } + + // XXX same as with `light` in `color_eyre` + /// A theme for a light background + pub fn light() -> Self { + Self { + file: style().purple(), + line_number: style().purple(), + target: style().red(), + fields: style().blue(), + active_line: style().bold(), + } + } + + /// Styles printed paths + pub fn file(mut self, style: Style) -> Self { + self.file = style; + self + } + + /// Styles the line number of a file + pub fn line_number(mut self, style: Style) -> Self { + self.line_number = style; + self + } + + /// Styles the target (i.e. the module and function name, and so on) + pub fn target(mut self, style: Style) -> Self { + self.target = style; + self + } + + /// Styles fields associated with a the `tracing::Span`. + pub fn fields(mut self, style: Style) -> Self { + self.fields = style; + self + } + + /// Styles the selected line of displayed code + pub fn active_line(mut self, style: Style) -> Self { + self.active_line = style; + self + } +} + +/// An error returned by `set_theme` if a global theme was already set +#[derive(Debug)] +pub struct InstallThemeError; + +impl fmt::Display for InstallThemeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("could not set the provided `Theme` globally as another was already set") + } +} + +impl std::error::Error for InstallThemeError {} + +/// Sets the global theme. +/// +/// # Details +/// +/// This can only be set once and otherwise fails. +/// +/// **Note:** `colorize` sets the global theme implicitly, if it was not set already. So calling `colorize` and then `set_theme` fails +pub fn set_theme(theme: Theme) -> Result<(), InstallThemeError> { + THEME.set(theme).map_err(|_| InstallThemeError) +} + /// Display a [`SpanTrace`] with colors and source /// /// This function returns an `impl Display` type which can be then used in place of the original @@ -93,13 +200,17 @@ use tracing_error::SpanTrace; /// println!("{}", color_spantrace::colorize(&span_trace)); /// ``` /// +/// **Note:** `colorize` sets the global theme implicitly, if it was not set already. So calling `colorize` and then `set_theme` fails +/// /// [`SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html pub fn colorize(span_trace: &SpanTrace) -> impl fmt::Display + '_ { - ColorSpanTrace { span_trace } + let theme = *THEME.get_or_init(Theme::dark); + ColorSpanTrace { span_trace, theme } } struct ColorSpanTrace<'a> { span_trace: &'a SpanTrace, + theme: Theme, } macro_rules! try_bool { @@ -117,6 +228,7 @@ macro_rules! try_bool { struct Frame<'a> { metadata: &'a tracing_core::Metadata<'static>, fields: &'a str, + theme: Theme, } /// Defines how verbose the backtrace is supposed to be. @@ -161,15 +273,15 @@ impl Frame<'_> { f, "{:>2}: {}{}{}", i, - Red.make_intense().paint(self.metadata.target()), - Red.make_intense().paint("::"), - Red.make_intense().paint(self.metadata.name()), + self.theme.target.style(self.metadata.target()), + self.theme.target.style("::"), + self.theme.target.style(self.metadata.name()), ) } fn print_fields(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if !self.fields.is_empty() { - write!(f, " with {}", Cyan.make_intense().paint(self.fields))?; + write!(f, " with {}", self.theme.fields.style(self.fields))?; } Ok(()) @@ -184,8 +296,8 @@ impl Frame<'_> { write!( f, "\n at {}:{}", - Purple.paint(file), - Purple.paint(lineno) + self.theme.file.style(file), + self.theme.line_number.style(lineno), )?; } else { write!(f, "\n at ")?; @@ -213,7 +325,6 @@ impl Frame<'_> { let reader = BufReader::new(file); let start_line = lineno - 2.min(lineno - 1); let surrounding_src = reader.lines().skip(start_line as usize - 1).take(5); - let bold = Style::new().bold(); let mut buf = String::new(); for (line, cur_line_no) in surrounding_src.zip(start_line..) { if cur_line_no == lineno { @@ -223,7 +334,7 @@ impl Frame<'_> { cur_line_no.to_string(), line.unwrap() )?; - write!(f, "\n{}", bold.paint(&buf))?; + write!(f, "\n{}", self.theme.active_line.style(&buf))?; buf.clear(); } else { write!(f, "\n{:>8} │ {}", cur_line_no, line.unwrap())?; @@ -241,7 +352,11 @@ impl fmt::Display for ColorSpanTrace<'_> { writeln!(f, "{:━^80}\n", " SPANTRACE ")?; self.span_trace.with_spans(|metadata, fields| { - let frame = Frame { metadata, fields }; + let frame = Frame { + metadata, + fields, + theme: self.theme, + }; if span > 0 { try_bool!(write!(f, "\n",), err); @@ -260,35 +375,3 @@ impl fmt::Display for ColorSpanTrace<'_> { err } } - -// TODO: remove when / if ansi_term merges these changes upstream -trait ColorExt { - fn make_intense(self) -> Self; -} - -impl ColorExt for ansi_term::Color { - fn make_intense(self) -> Self { - use ansi_term::Color::*; - - match self { - Black => Fixed(8), - Red => Fixed(9), - Green => Fixed(10), - Yellow => Fixed(11), - Blue => Fixed(12), - Purple => Fixed(13), - Cyan => Fixed(14), - White => Fixed(15), - Fixed(color) if color < 8 => Fixed(color + 8), - other => other, - } - } -} -impl ColorExt for ansi_term::Style { - fn make_intense(mut self) -> Self { - if let Some(color) = self.foreground { - self.foreground = Some(color.make_intense()); - } - self - } -} diff --git a/tests/data/theme_control.txt b/tests/data/theme_control.txt new file mode 100644 index 0000000..0b97908 --- /dev/null +++ b/tests/data/theme_control.txt @@ -0,0 +1,9 @@ +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SPANTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + 0: themes::test_capture with x=42 + at tests/themes.rs:42 + 40 │ use tracing_subscriber::{prelude::*, registry::Registry}; + 41 │ + 42 > #[instrument] + 43 │ fn test_capture(x: u8) -> SpanTrace { + 44 │ if x == 42 { \ No newline at end of file diff --git a/tests/themes.rs b/tests/themes.rs new file mode 100644 index 0000000..53c9018 --- /dev/null +++ b/tests/themes.rs @@ -0,0 +1,92 @@ +/* + + # How this test works: + + 1) generate a spantrace with `test_capture` + + 2) convert the spantrace to a string + + 3) load stored spantrace control to compare to spantrace string (stored in the path of `control_file_path` below) + + 4) if `control_file_path` doesn't exist, generate corresponding file in the current working directory and request the user to fix the issue (see below) + + 5) extract ANSI escaping sequences (of control and current spantrace) + + 6) compare if the current spantrace and the control contains the same ANSI escape sequences + + 7) If not, fail and show the full strings of the control and the current spantrace + + # Re-generating the control + + If the control spantrace is lost and/or it needs to be re-generated, do the following: + + 1) Checkout the `color_spantrace` version from Git that you want to test against + + 3) Add this test file to '/tests' + + 4) If `control_file_path` exist, delete it + + 5) If you now run this test, it will generate a test control file in the current working directory + + 6) copy this file to `control_file_path` (see instructions that are shown) + +*/ + +use ansi_parser::{AnsiParser, AnsiSequence, Output}; +use std::{fs, path::Path}; +use tracing::instrument; +use tracing_error::ErrorLayer; +use tracing_error::SpanTrace; +use tracing_subscriber::{prelude::*, registry::Registry}; + +#[instrument] +fn test_capture(x: u8) -> SpanTrace { + if x == 42 { + SpanTrace::capture() + } else { + SpanTrace::capture() + } +} + +#[test] +fn test_backwards_compatibility() { + std::env::set_var("RUST_LIB_BACKTRACE", "full"); + Registry::default().with(ErrorLayer::default()).init(); + + let spantrace = test_capture(42); + let colored_spantrace = format!("{}", color_spantrace::colorize(&spantrace)); + + let control_file_name = "theme_control.txt"; + let control_file_path = ["tests/data/", control_file_name].concat(); + + // If `control_file_path` is missing, save corresponding file to current working directory, and panic with the request to move these files to `control_file_path`, and to commit them to Git. Being explicit (instead of saving directly to `control_file_path` to make sure `control_file_path` is committed to Git. These files anyway should never be missing. + + if !Path::new(&control_file_path).is_file() { + std::fs::write(control_file_name, &colored_spantrace) + .expect("\n\nError saving `colored_spanntrace` to a file"); + panic!("Required test data missing! Fix this, by moving '{}' to '{}', and commit it to Git.\n\nNote: '{0}' was just generated in the current working directory.\n\n", control_file_name, control_file_path); + } + + // `unwrap` should never fail with files generated by this test + let colored_spantrace_control = + String::from_utf8(fs::read(control_file_path).unwrap()).unwrap(); + + fn get_ansi<'a>(s: &'a str) -> impl Iterator + 'a { + s.ansi_parse().filter_map(|x| { + if let Output::Escape(ansi) = x { + Some(ansi) + } else { + None + } + }) + }; + + let colored_spantrace_ansi = get_ansi(&colored_spantrace); + let colored_spantrace_control_ansi = get_ansi(&colored_spantrace_control); + + assert!( + colored_spantrace_ansi.eq(colored_spantrace_control_ansi), + format!("\x1b[0mANSI escape sequences are not identical to control!\n\nCONTROL:\n\n{}\n\n\n\n{:?}\n\nCURRENT:\n\n{}\n\n\n\n{:?}\n\n", &colored_spantrace_control, &colored_spantrace_control, &colored_spantrace, &colored_spantrace) + // `\x1b[0m` clears previous ANSI escape sequences + ); +} From edfcda0d44d41f4860f112e542d95ea442944d86 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 2 Dec 2020 10:56:46 -0800 Subject: [PATCH 17/32] ignore all io errors while resolving source files --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 16d2ea8..5225543 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -315,8 +315,8 @@ impl Frame<'_> { let file = match File::open(filename) { Ok(file) => file, - Err(ref e) if e.kind() == ErrorKind::NotFound => return Ok(()), - e @ Err(_) => e.unwrap(), + // ignore io errors and just don't print the source + Err(_) => return Ok(()), }; use std::fmt::Write; From 804992769c552f54588c703d86fc179bf13399cb Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 2 Dec 2020 11:05:06 -0800 Subject: [PATCH 18/32] prep for release --- CHANGELOG.md | 8 +++++++- Cargo.toml | 3 +++ src/lib.rs | 2 +- tests/themes.rs | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e4c665..a647a43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Fixed +- Ignore all io errors when resolving source files instead of only file not + found errors + +## [v0.1.5] - 2020-12-01 ### Added - Support custom color themes for spantrace format -[Unreleased]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 +[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.1.5...HEAD +[v0.1.5]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 diff --git a/Cargo.toml b/Cargo.toml index 49a10e9..f8b815e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,9 @@ ansi-parser = "0.6.5" # used for testing color schemes all-features = true rustdoc-args = ["--cfg", "docsrs"] +[package.metadata.release] +no-dev-version = true + [[package.metadata.release.pre-release-replacements]] file = "CHANGELOG.md" search = "Unreleased" diff --git a/src/lib.rs b/src/lib.rs index 5225543..75be4cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,7 @@ use owo_colors::{style, Style}; use std::env; use std::fmt; use std::fs::File; -use std::io::{BufRead, BufReader, ErrorKind}; +use std::io::{BufRead, BufReader}; use tracing_error::SpanTrace; static THEME: OnceCell = OnceCell::new(); diff --git a/tests/themes.rs b/tests/themes.rs index 53c9018..21bdae0 100644 --- a/tests/themes.rs +++ b/tests/themes.rs @@ -40,6 +40,7 @@ use tracing_error::SpanTrace; use tracing_subscriber::{prelude::*, registry::Registry}; #[instrument] +#[allow(clippy::clippy::if_same_then_else)] fn test_capture(x: u8) -> SpanTrace { if x == 42 { SpanTrace::capture() From 2eebd849503cfcb5155f45649104fa2c42fb607a Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 2 Dec 2020 11:07:20 -0800 Subject: [PATCH 19/32] (cargo-release) version 0.1.6 --- CHANGELOG.md | 5 ++++- Cargo.toml | 2 +- src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a647a43..a7f8513 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate + +## [0.1.6] - 2020-12-02 ### Fixed - Ignore all io errors when resolving source files instead of only file not found errors @@ -16,5 +18,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support custom color themes for spantrace format -[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.1.5...HEAD +[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.1.6...HEAD +[0.1.6]: https://github.com/yaahc/color-spantrace/compare/v0.1.5...v0.1.6 [v0.1.5]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 diff --git a/Cargo.toml b/Cargo.toml index f8b815e..6f692db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.6-alpha.0" +version = "0.1.6" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index 75be4cb..81ddee3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.4")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.6")] #![warn( missing_debug_implementations, missing_docs, From 1d402282971ab5c5a4c314995a648115824911b7 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Sun, 26 Dec 2021 11:11:04 -0600 Subject: [PATCH 20/32] Fix lint warnings --- src/lib.rs | 2 +- tests/themes.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 81ddee3..4eb6cd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -63,7 +63,7 @@ #![warn( missing_debug_implementations, missing_docs, - missing_doc_code_examples, + rustdoc::missing_doc_code_examples, rust_2018_idioms, unreachable_pub, bad_style, diff --git a/tests/themes.rs b/tests/themes.rs index 21bdae0..994dde7 100644 --- a/tests/themes.rs +++ b/tests/themes.rs @@ -72,7 +72,7 @@ fn test_backwards_compatibility() { let colored_spantrace_control = String::from_utf8(fs::read(control_file_path).unwrap()).unwrap(); - fn get_ansi<'a>(s: &'a str) -> impl Iterator + 'a { + fn get_ansi(s: &str) -> impl Iterator + '_ { s.ansi_parse().filter_map(|x| { if let Output::Escape(ansi) = x { Some(ansi) @@ -80,14 +80,14 @@ fn test_backwards_compatibility() { None } }) - }; + } let colored_spantrace_ansi = get_ansi(&colored_spantrace); let colored_spantrace_control_ansi = get_ansi(&colored_spantrace_control); assert!( colored_spantrace_ansi.eq(colored_spantrace_control_ansi), - format!("\x1b[0mANSI escape sequences are not identical to control!\n\nCONTROL:\n\n{}\n\n\n\n{:?}\n\nCURRENT:\n\n{}\n\n\n\n{:?}\n\n", &colored_spantrace_control, &colored_spantrace_control, &colored_spantrace, &colored_spantrace) + "\x1b[0mANSI escape sequences are not identical to control!\n\nCONTROL:\n\n{}\n\n\n\n{:?}\n\nCURRENT:\n\n{}\n\n\n\n{:?}\n\n", &colored_spantrace_control, &colored_spantrace_control, &colored_spantrace, &colored_spantrace // `\x1b[0m` clears previous ANSI escape sequences ); } From 99371c3274cc4ec3940e0ed911bc4932501903c6 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Sun, 26 Dec 2021 11:09:31 -0600 Subject: [PATCH 21/32] Update tracing-error (and tracing-subscriber) --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f692db..deb7ee2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,14 +12,14 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tracing-error = "0.1.2" -tracing-core = "0.1.10" +tracing-error = "0.2.0" +tracing-core = "0.1.21" owo-colors = "1.2.0" once_cell = "1.4.1" [dev-dependencies] -tracing-subscriber = "0.2.5" -tracing = "0.1.13" +tracing-subscriber = "0.3.4" +tracing = "0.1.29" ansi-parser = "0.6.5" # used for testing color schemes [package.metadata.docs.rs] From 3080506345aa92dfeba104edb5d464a33f2d1c81 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Sun, 26 Dec 2021 11:17:16 -0600 Subject: [PATCH 22/32] Update ansi-parser --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6f692db..30e171c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ once_cell = "1.4.1" [dev-dependencies] tracing-subscriber = "0.2.5" tracing = "0.1.13" -ansi-parser = "0.6.5" # used for testing color schemes +ansi-parser = "0.8.0" # used for testing color schemes [package.metadata.docs.rs] all-features = true From 37d4dce5c4030ac837db35c6f0d9137a880135e2 Mon Sep 17 00:00:00 2001 From: "Aode (lion)" Date: Sun, 26 Dec 2021 11:54:06 -0600 Subject: [PATCH 23/32] Update owo-colors --- Cargo.toml | 2 +- tests/data/theme_control.txt | 4 ++-- tests/themes.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f692db..25e4822 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" [dependencies] tracing-error = "0.1.2" tracing-core = "0.1.10" -owo-colors = "1.2.0" +owo-colors = "3.2.0" once_cell = "1.4.1" [dev-dependencies] diff --git a/tests/data/theme_control.txt b/tests/data/theme_control.txt index 0b97908..96d8830 100644 --- a/tests/data/theme_control.txt +++ b/tests/data/theme_control.txt @@ -4,6 +4,6 @@ at tests/themes.rs:42 40 │ use tracing_subscriber::{prelude::*, registry::Registry}; 41 │ - 42 > #[instrument] + 42 > #[instrument] 43 │ fn test_capture(x: u8) -> SpanTrace { - 44 │ if x == 42 { \ No newline at end of file + 44 │ #[allow(clippy::if_same_then_else)] \ No newline at end of file diff --git a/tests/themes.rs b/tests/themes.rs index 21bdae0..f29fa59 100644 --- a/tests/themes.rs +++ b/tests/themes.rs @@ -40,8 +40,8 @@ use tracing_error::SpanTrace; use tracing_subscriber::{prelude::*, registry::Registry}; #[instrument] -#[allow(clippy::clippy::if_same_then_else)] fn test_capture(x: u8) -> SpanTrace { + #[allow(clippy::if_same_then_else)] if x == 42 { SpanTrace::capture() } else { From 9350c4f9e51c56db4e812d9a5f42acbbf6309765 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 12 Jan 2022 15:42:46 -0800 Subject: [PATCH 24/32] Update Cargo.toml --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8cbf736..db224b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] - tracing-error = "0.2.0" tracing-core = "0.1.21" owo-colors = "3.2.0" From c0ec5ffeec47a36c56bee5af03222108c5c42996 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 12 Jan 2022 15:53:26 -0800 Subject: [PATCH 25/32] Prepare for 0.2 release --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- README.md | 8 ++++---- src/lib.rs | 8 ++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f8513..5cddf79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Changed +- Updated dependency versions to match latest tracing versions ## [0.1.6] - 2020-12-02 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index a9f39f7..f3a751a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [package.metadata.release] -no-dev-version = true +dev-version = false [[package.metadata.release.pre-release-replacements]] file = "CHANGELOG.md" diff --git a/README.md b/README.md index 9a913c8..0a1bcde 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Add the following to your `Cargo.toml`: ```toml [dependencies] -color-spantrace = "0.1" -tracing = "0.1.13" -tracing-error = "0.1.2" -tracing-subscriber = "0.2.5" +color-spantrace = "0.2" +tracing = "0.1" +tracing-error = "0.2" +tracing-subscriber = "0.3" ``` Setup a tracing subscriber with an `ErrorLayer`: diff --git a/src/lib.rs b/src/lib.rs index 4eb6cd8..38340e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,10 +7,10 @@ //! //! ```toml //! [dependencies] -//! color-spantrace = "0.1" -//! tracing = "0.1.13" -//! tracing-error = "0.1.2" -//! tracing-subscriber = "0.2.5" +//! color-spantrace = "0.2" +//! tracing = "0.1" +//! tracing-error = "0.2" +//! tracing-subscriber = "0.3" //! ``` //! //! Setup a tracing subscriber with an `ErrorLayer`: From 15538366ffc69d3bae23a67fbeaf3edd7d08b107 Mon Sep 17 00:00:00 2001 From: Jane Lusby Date: Wed, 12 Jan 2022 16:01:21 -0800 Subject: [PATCH 26/32] (cargo-release) version 0.2.0 --- CHANGELOG.md | 5 ++++- Cargo.toml | 2 +- src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cddf79..fc9562e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate + +## [0.2.0] - 2022-01-12 ### Changed - Updated dependency versions to match latest tracing versions @@ -20,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support custom color themes for spantrace format -[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.1.6...HEAD +[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.2.0...HEAD +[0.2.0]: https://github.com/yaahc/color-spantrace/compare/v0.1.6...v0.2.0 [0.1.6]: https://github.com/yaahc/color-spantrace/compare/v0.1.5...v0.1.6 [v0.1.5]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 diff --git a/Cargo.toml b/Cargo.toml index f3a751a..15c81b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "color-spantrace" -version = "0.1.6" +version = "0.2.0" authors = ["Jane Lusby "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index 38340e1..3a7e45f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ //! //! [`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html //! [`color-backtrace`]: https://github.com/athre0z/color-backtrace -#![doc(html_root_url = "https://docs.rs/color-spantrace/0.1.6")] +#![doc(html_root_url = "https://docs.rs/color-spantrace/0.2.0")] #![warn( missing_debug_implementations, missing_docs, From 35031dc4996cb4d318b74c7ecea6075c87bce4f9 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 5 May 2022 10:38:25 -0700 Subject: [PATCH 27/32] Add license files --- LICENSE-APACHE | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE-MIT | 23 ++++++ 2 files changed, 225 insertions(+) create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. From e42d667d1598e77a9f4a04af8df2c0c37bb74d8d Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Tue, 3 Oct 2023 21:18:59 +0100 Subject: [PATCH 28/32] Add color-spantrace to workspace --- Cargo.toml | 1 + color-spantrace/.github/workflows/ci.yml | 81 --------- color-spantrace/CHANGELOG.md | 8 +- color-spantrace/Cargo.toml | 16 +- color-spantrace/LICENSE-APACHE | 203 +---------------------- color-spantrace/LICENSE-MIT | 24 +-- color-spantrace/README.md | 4 +- color-spantrace/src/lib.rs | 1 - 8 files changed, 17 insertions(+), 321 deletions(-) delete mode 100644 color-spantrace/.github/workflows/ci.yml mode change 100644 => 120000 color-spantrace/LICENSE-APACHE mode change 100644 => 120000 color-spantrace/LICENSE-MIT diff --git a/Cargo.toml b/Cargo.toml index a6bf453..0515a7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ + "color-spantrace", "eyre" ] diff --git a/color-spantrace/.github/workflows/ci.yml b/color-spantrace/.github/workflows/ci.yml deleted file mode 100644 index 6b3c3f8..0000000 --- a/color-spantrace/.github/workflows/ci.yml +++ /dev/null @@ -1,81 +0,0 @@ -on: [push, pull_request] - -name: Continuous integration - -jobs: - check: - name: Check - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - - uses: actions-rs/cargo@v1 - with: - command: check - - test: - name: Test Suite - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - - nightly - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - - uses: actions-rs/cargo@v1 - with: - command: test - # - uses: actions-rs/cargo@v1 - # with: - # command: test - # args: --no-default-features - - fmt: - name: Rustfmt - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - - run: rustup component add rustfmt - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - clippy: - name: Clippy - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - override: true - - run: rustup component add clippy - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings diff --git a/color-spantrace/CHANGELOG.md b/color-spantrace/CHANGELOG.md index fc9562e..3014914 100644 --- a/color-spantrace/CHANGELOG.md +++ b/color-spantrace/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support custom color themes for spantrace format -[Unreleased]: https://github.com/yaahc/color-spantrace/compare/v0.2.0...HEAD -[0.2.0]: https://github.com/yaahc/color-spantrace/compare/v0.1.6...v0.2.0 -[0.1.6]: https://github.com/yaahc/color-spantrace/compare/v0.1.5...v0.1.6 -[v0.1.5]: https://github.com/yaahc/color-spantrace/releases/tag/v0.1.5 +[Unreleased]: https://github.com/eyre-rs/color-spantrace/compare/v0.2.0...HEAD +[0.2.0]: https://github.com/eyre-rs/color-spantrace/compare/v0.1.6...v0.2.0 +[0.1.6]: https://github.com/eyre-rs/color-spantrace/compare/v0.1.5...v0.1.6 +[v0.1.5]: https://github.com/eyre-rs/color-spantrace/releases/tag/v0.1.5 diff --git a/color-spantrace/Cargo.toml b/color-spantrace/Cargo.toml index 15c81b8..e1510d8 100644 --- a/color-spantrace/Cargo.toml +++ b/color-spantrace/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "color-spantrace" version = "0.2.0" -authors = ["Jane Lusby "] -edition = "2018" -license = "MIT OR Apache-2.0" description = "A pretty printer for tracing_error::SpanTrace based on color-backtrace" -repository = "https://github.com/yaahc/color-spantrace" documentation = "https://docs.rs/color-spantrace" -readme = "README.md" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +readme = { workspace = true } +rust-version = { workspace = true } [dependencies] tracing-error = "0.2.0" tracing-core = "0.1.21" owo-colors = "3.2.0" -once_cell = "1.4.1" +once_cell = { workspace = true } [dev-dependencies] tracing-subscriber = "0.3.4" @@ -60,5 +60,5 @@ exactly=1 [[package.metadata.release.pre-release-replacements]] file="CHANGELOG.md" search="" -replace="\n[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD" +replace="\n[Unreleased]: https://github.com/eyre-rs/{{crate_name}}/compare/{{tag_name}}...HEAD" exactly=1 diff --git a/color-spantrace/LICENSE-APACHE b/color-spantrace/LICENSE-APACHE deleted file mode 100644 index d645695..0000000 --- a/color-spantrace/LICENSE-APACHE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/color-spantrace/LICENSE-APACHE b/color-spantrace/LICENSE-APACHE new file mode 120000 index 0000000..965b606 --- /dev/null +++ b/color-spantrace/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/color-spantrace/LICENSE-MIT b/color-spantrace/LICENSE-MIT deleted file mode 100644 index 31aa793..0000000 --- a/color-spantrace/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/color-spantrace/LICENSE-MIT b/color-spantrace/LICENSE-MIT new file mode 120000 index 0000000..76219eb --- /dev/null +++ b/color-spantrace/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/color-spantrace/README.md b/color-spantrace/README.md index 0a1bcde..a2eaec9 100644 --- a/color-spantrace/README.md +++ b/color-spantrace/README.md @@ -5,8 +5,8 @@ color-spantrace [![Latest Version](https://img.shields.io/crates/v/color-spantrace.svg)](https://crates.io/crates/color-spantrace) [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/color-spantrace) -[actions-badge]: https://github.com/yaahc/color-spantrace/workflows/Continuous%20integration/badge.svg -[actions-url]: https://github.com/yaahc/color-spantrace/actions?query=workflow%3A%22Continuous+integration%22 +[actions-badge]: https://github.com/eyre-rs/color-spantrace/workflows/Continuous%20integration/badge.svg +[actions-url]: https://github.com/eyre-rs/color-spantrace/actions?query=workflow%3A%22Continuous+integration%22 A rust library for colorizing [`tracing_error::SpanTrace`] objects in the style of [`color-backtrace`]. diff --git a/color-spantrace/src/lib.rs b/color-spantrace/src/lib.rs index 3a7e45f..7d51313 100644 --- a/color-spantrace/src/lib.rs +++ b/color-spantrace/src/lib.rs @@ -67,7 +67,6 @@ rust_2018_idioms, unreachable_pub, bad_style, - const_err, dead_code, improper_ctypes, non_shorthand_field_patterns, From 22b871bc0e053f77009a5e737ad594c32e5f7f57 Mon Sep 17 00:00:00 2001 From: Tei Roberts Date: Tue, 10 Oct 2023 23:38:54 +0200 Subject: [PATCH 29/32] fix: color-spantrace test due to misinterpreted relative paths --- color-spantrace/tests/themes.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/color-spantrace/tests/themes.rs b/color-spantrace/tests/themes.rs index 379aa25..c1fdcfb 100644 --- a/color-spantrace/tests/themes.rs +++ b/color-spantrace/tests/themes.rs @@ -52,19 +52,27 @@ fn test_capture(x: u8) -> SpanTrace { #[test] fn test_backwards_compatibility() { std::env::set_var("RUST_LIB_BACKTRACE", "full"); + + // This integration is ran by cargo with cwd="color-spantrace", but the string literals for + // `file!` are relative to the workspace root. This changes the cwd to the workspace root. + // + // The behavior of file! when invoked from a workspace is not document, as non-member path + // dependencies will get an absolute path. + std::env::set_current_dir("..").unwrap(); + Registry::default().with(ErrorLayer::default()).init(); let spantrace = test_capture(42); let colored_spantrace = format!("{}", color_spantrace::colorize(&spantrace)); let control_file_name = "theme_control.txt"; - let control_file_path = ["tests/data/", control_file_name].concat(); + let control_file_path = ["color-spantrace/tests/data/", control_file_name].concat(); // If `control_file_path` is missing, save corresponding file to current working directory, and panic with the request to move these files to `control_file_path`, and to commit them to Git. Being explicit (instead of saving directly to `control_file_path` to make sure `control_file_path` is committed to Git. These files anyway should never be missing. if !Path::new(&control_file_path).is_file() { std::fs::write(control_file_name, &colored_spantrace) - .expect("\n\nError saving `colored_spanntrace` to a file"); + .expect("\n\nError saving `colored_spantrace` to a file"); panic!("Required test data missing! Fix this, by moving '{}' to '{}', and commit it to Git.\n\nNote: '{0}' was just generated in the current working directory.\n\n", control_file_name, control_file_path); } From e54e98f31334c2c0ec5dcd85f1295f2b93c4adc7 Mon Sep 17 00:00:00 2001 From: Tei Roberts Date: Tue, 10 Oct 2023 23:43:32 +0200 Subject: [PATCH 30/32] fix: color-spantrace does not work in miri sandbox --- color-spantrace/tests/themes.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/color-spantrace/tests/themes.rs b/color-spantrace/tests/themes.rs index c1fdcfb..52cb27d 100644 --- a/color-spantrace/tests/themes.rs +++ b/color-spantrace/tests/themes.rs @@ -49,6 +49,7 @@ fn test_capture(x: u8) -> SpanTrace { } } +#[cfg(not(miri))] #[test] fn test_backwards_compatibility() { std::env::set_var("RUST_LIB_BACKTRACE", "full"); From 0ad6355d9f06f50a29030daf4e4aa30c0311a445 Mon Sep 17 00:00:00 2001 From: Tei Roberts Date: Tue, 10 Oct 2023 23:46:25 +0200 Subject: [PATCH 31/32] chore: clarify file! behavior --- color-spantrace/tests/themes.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/color-spantrace/tests/themes.rs b/color-spantrace/tests/themes.rs index 52cb27d..e6fbe53 100644 --- a/color-spantrace/tests/themes.rs +++ b/color-spantrace/tests/themes.rs @@ -57,8 +57,10 @@ fn test_backwards_compatibility() { // This integration is ran by cargo with cwd="color-spantrace", but the string literals for // `file!` are relative to the workspace root. This changes the cwd to the workspace root. // - // The behavior of file! when invoked from a workspace is not document, as non-member path - // dependencies will get an absolute path. + // The behavior of file! when invoked from a workspace is not documented. See: . + // + // Noteworthy: non-member path dependencies will get an absolute path, as will registry and git + // dependencies. std::env::set_current_dir("..").unwrap(); Registry::default().with(ErrorLayer::default()).init(); From 0d7f941eb213e8bb20387947db5c156fbebb1ce7 Mon Sep 17 00:00:00 2001 From: Tei Roberts Date: Tue, 10 Oct 2023 23:51:31 +0200 Subject: [PATCH 32/32] fix: unused imports under miri --- color-spantrace/tests/themes.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/color-spantrace/tests/themes.rs b/color-spantrace/tests/themes.rs index e6fbe53..2f24d63 100644 --- a/color-spantrace/tests/themes.rs +++ b/color-spantrace/tests/themes.rs @@ -32,12 +32,8 @@ */ -use ansi_parser::{AnsiParser, AnsiSequence, Output}; -use std::{fs, path::Path}; use tracing::instrument; -use tracing_error::ErrorLayer; use tracing_error::SpanTrace; -use tracing_subscriber::{prelude::*, registry::Registry}; #[instrument] fn test_capture(x: u8) -> SpanTrace { @@ -52,6 +48,10 @@ fn test_capture(x: u8) -> SpanTrace { #[cfg(not(miri))] #[test] fn test_backwards_compatibility() { + use ansi_parser::{AnsiParser, AnsiSequence, Output}; + use std::{fs, path::Path}; + use tracing_error::ErrorLayer; + use tracing_subscriber::{prelude::*, registry::Registry}; std::env::set_var("RUST_LIB_BACKTRACE", "full"); // This integration is ran by cargo with cwd="color-spantrace", but the string literals for