diff --git a/Cargo.lock b/Cargo.lock index df36d277a4..2cc45ea11c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -559,29 +559,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "env_filter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1132,30 +1109,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jiff" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde", -] - -[[package]] -name = "jiff-static" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - [[package]] name = "js-sys" version = "0.3.77" @@ -1186,6 +1139,12 @@ dependencies = [ "libc", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.174" @@ -1291,6 +1250,15 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "matchit" version = "0.8.4" @@ -1306,11 +1274,9 @@ dependencies = [ "chrono", "clap", "clap_complete", - "env_logger", "futures-util", "glob", "ignore", - "log", "mdbook-core", "mdbook-driver", "mdbook-html", @@ -1331,6 +1297,8 @@ dependencies = [ "tokio", "toml", "tower-http", + "tracing", + "tracing-subscriber", "walkdir", ] @@ -1339,12 +1307,12 @@ name = "mdbook-core" version = "0.5.0-alpha.1" dependencies = [ "anyhow", - "log", "regex", "serde", "serde_json", "tempfile", "toml", + "tracing", ] [[package]] @@ -1353,7 +1321,6 @@ version = "0.5.0-alpha.1" dependencies = [ "anyhow", "indexmap", - "log", "mdbook-core", "mdbook-html", "mdbook-markdown", @@ -1367,6 +1334,7 @@ dependencies = [ "tempfile", "toml", "topological-sort", + "tracing", ] [[package]] @@ -1379,7 +1347,6 @@ dependencies = [ "font-awesome-as-a-crate", "handlebars", "hex", - "log", "mdbook-core", "mdbook-markdown", "mdbook-renderer", @@ -1391,15 +1358,16 @@ dependencies = [ "sha2", "tempfile", "toml", + "tracing", ] [[package]] name = "mdbook-markdown" version = "0.5.0-alpha.1" dependencies = [ - "log", "pulldown-cmark", "regex", + "tracing", ] [[package]] @@ -1437,11 +1405,11 @@ name = "mdbook-summary" version = "0.5.0-alpha.1" dependencies = [ "anyhow", - "log", "mdbook-core", "memchr", "pulldown-cmark", "serde", + "tracing", ] [[package]] @@ -1544,6 +1512,15 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "num-modular" version = "0.6.1" @@ -1781,21 +1758,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] - [[package]] name = "potential_utf" version = "0.1.2" @@ -2126,6 +2088,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2333,6 +2304,15 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -2504,9 +2484,21 @@ checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + [[package]] name = "tracing-core" version = "0.1.34" @@ -2514,6 +2506,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2598,6 +2620,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index c458b371f6..b271014977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,6 @@ chrono = { version = "0.4.41", default-features = false, features = ["clock"] } clap = { version = "4.5.41", features = ["cargo", "wrap_help"] } clap_complete = "4.5.55" elasticlunr-rs = "3.0.2" -env_logger = "0.11.8" font-awesome-as-a-crate = "0.3.0" futures-util = "0.3.31" glob = "0.3.3" @@ -40,7 +39,6 @@ handlebars = "6.3.2" hex = "0.4.3" indexmap = "2.10.0" ignore = "0.4.23" -log = "0.4.27" mdbook-core = { path = "crates/mdbook-core" } mdbook-driver = { path = "crates/mdbook-driver" } mdbook-html = { path = "crates/mdbook-html" } @@ -68,6 +66,8 @@ tokio = "1.46.1" toml = "0.9.2" topological-sort = "0.2.2" tower-http = "0.6.6" +tracing = "0.1.41" +tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } walkdir = "2.5.0" [package] @@ -93,8 +93,6 @@ anyhow.workspace = true chrono.workspace = true clap.workspace = true clap_complete.workspace = true -env_logger.workspace = true -log.workspace = true mdbook-core.workspace = true mdbook-driver.workspace = true mdbook-html.workspace = true @@ -104,6 +102,8 @@ mdbook-renderer.workspace = true mdbook-summary.workspace = true opener.workspace = true toml.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true # Watch feature ignore = { workspace = true, optional = true } diff --git a/crates/mdbook-core/Cargo.toml b/crates/mdbook-core/Cargo.toml index 6841704b90..a964b72a7b 100644 --- a/crates/mdbook-core/Cargo.toml +++ b/crates/mdbook-core/Cargo.toml @@ -9,11 +9,11 @@ rust-version.workspace = true [dependencies] anyhow.workspace = true -log.workspace = true regex.workspace = true serde.workspace = true serde_json.workspace = true toml.workspace = true +tracing.workspace = true [dev-dependencies] tempfile.workspace = true diff --git a/crates/mdbook-core/src/config.rs b/crates/mdbook-core/src/config.rs index 85319e49e0..98ca169dd5 100644 --- a/crates/mdbook-core/src/config.rs +++ b/crates/mdbook-core/src/config.rs @@ -46,7 +46,6 @@ use crate::utils::TomlExt; use crate::utils::log_backtrace; use anyhow::{Context, Error, Result, bail}; -use log::{debug, trace}; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; use std::env; @@ -56,6 +55,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use toml::Value; use toml::value::Table; +use tracing::{debug, trace}; /// The overall configuration object for MDBook, essentially an in-memory /// representation of `book.toml`. @@ -162,6 +162,10 @@ impl Config { env::vars().filter_map(|(key, value)| parse_env(&key).map(|index| (index, value))); for (key, value) in overrides { + if key == "log" { + // MDBOOK_LOG is used to control logging. + continue; + } trace!("{} => {}", key, value); let parsed_value = serde_json::from_str(&value) .unwrap_or_else(|_| serde_json::Value::String(value.to_string())); diff --git a/crates/mdbook-core/src/utils/fs.rs b/crates/mdbook-core/src/utils/fs.rs index c8500a739f..d32f5705c6 100644 --- a/crates/mdbook-core/src/utils/fs.rs +++ b/crates/mdbook-core/src/utils/fs.rs @@ -1,10 +1,10 @@ //! Filesystem utilities and helpers. use anyhow::{Context, Result}; -use log::{debug, trace}; use std::fs::{self, File}; use std::io::Write; use std::path::{Component, Path, PathBuf}; +use tracing::{debug, trace}; /// Naively replaces any path separator with a forward-slash '/' pub fn normalize_path(path: &str) -> String { diff --git a/crates/mdbook-core/src/utils/mod.rs b/crates/mdbook-core/src/utils/mod.rs index c36b16e960..1a026f1ac8 100644 --- a/crates/mdbook-core/src/utils/mod.rs +++ b/crates/mdbook-core/src/utils/mod.rs @@ -1,11 +1,12 @@ //! Various helpers and utilities. use anyhow::Error; -use log::error; use regex::Regex; use std::borrow::Cow; use std::collections::HashMap; +use std::fmt::Write; use std::sync::LazyLock; +use tracing::error; pub mod fs; mod string; @@ -79,11 +80,13 @@ pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap` for HTML. diff --git a/crates/mdbook-driver/Cargo.toml b/crates/mdbook-driver/Cargo.toml index 9f7936a4ad..9c6281e8a2 100644 --- a/crates/mdbook-driver/Cargo.toml +++ b/crates/mdbook-driver/Cargo.toml @@ -10,7 +10,6 @@ rust-version.workspace = true [dependencies] anyhow.workspace = true indexmap.workspace = true -log.workspace = true mdbook-core.workspace = true mdbook-html.workspace = true mdbook-markdown.workspace = true @@ -24,6 +23,7 @@ shlex.workspace = true tempfile.workspace = true toml.workspace = true topological-sort.workspace = true +tracing.workspace = true [lints] workspace = true diff --git a/crates/mdbook-driver/src/builtin_preprocessors/cmd.rs b/crates/mdbook-driver/src/builtin_preprocessors/cmd.rs index 498b055db2..efd5c4b97e 100644 --- a/crates/mdbook-driver/src/builtin_preprocessors/cmd.rs +++ b/crates/mdbook-driver/src/builtin_preprocessors/cmd.rs @@ -1,10 +1,10 @@ use anyhow::{Context, Result, ensure}; -use log::{debug, trace, warn}; use mdbook_core::book::Book; use mdbook_preprocessor::{Preprocessor, PreprocessorContext}; use std::io::Write; use std::path::PathBuf; use std::process::{Child, Stdio}; +use tracing::{debug, trace, warn}; /// A custom preprocessor which will shell out to a 3rd-party program. /// diff --git a/crates/mdbook-driver/src/builtin_preprocessors/index.rs b/crates/mdbook-driver/src/builtin_preprocessors/index.rs index 046b20defc..ad353fa3aa 100644 --- a/crates/mdbook-driver/src/builtin_preprocessors/index.rs +++ b/crates/mdbook-driver/src/builtin_preprocessors/index.rs @@ -1,9 +1,9 @@ use anyhow::Result; -use log::warn; use mdbook_core::book::{Book, BookItem}; use mdbook_preprocessor::{Preprocessor, PreprocessorContext}; use regex::Regex; use std::{path::Path, sync::LazyLock}; +use tracing::warn; /// A preprocessor for converting file name `README.md` to `index.md` since /// `README.md` is the de facto index file in markdown-based documentation. diff --git a/crates/mdbook-driver/src/builtin_preprocessors/links.rs b/crates/mdbook-driver/src/builtin_preprocessors/links.rs index e6466ee924..e68ad9b353 100644 --- a/crates/mdbook-driver/src/builtin_preprocessors/links.rs +++ b/crates/mdbook-driver/src/builtin_preprocessors/links.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use log::{error, warn}; use mdbook_core::book::{Book, BookItem}; use mdbook_core::utils::{ take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines, @@ -11,6 +10,7 @@ use std::fs; use std::ops::{Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeTo}; use std::path::{Path, PathBuf}; use std::sync::LazyLock; +use tracing::{error, warn}; const ESCAPE_CHAR: char = '\\'; const MAX_LINK_NESTED_DEPTH: usize = 10; diff --git a/crates/mdbook-driver/src/builtin_renderers/markdown_renderer.rs b/crates/mdbook-driver/src/builtin_renderers/markdown_renderer.rs index d626cf175d..d0f0a744e8 100644 --- a/crates/mdbook-driver/src/builtin_renderers/markdown_renderer.rs +++ b/crates/mdbook-driver/src/builtin_renderers/markdown_renderer.rs @@ -1,9 +1,9 @@ use anyhow::{Context, Result}; -use log::trace; use mdbook_core::book::BookItem; use mdbook_core::utils; use mdbook_renderer::{RenderContext, Renderer}; use std::fs; +use tracing::trace; /// A renderer to output the Markdown after the preprocessors have run. Mostly useful /// when debugging preprocessors. diff --git a/crates/mdbook-driver/src/builtin_renderers/mod.rs b/crates/mdbook-driver/src/builtin_renderers/mod.rs index b319ff1f66..65cff5c7e9 100644 --- a/crates/mdbook-driver/src/builtin_renderers/mod.rs +++ b/crates/mdbook-driver/src/builtin_renderers/mod.rs @@ -3,10 +3,10 @@ //! The HTML renderer can be found in the [`mdbook_html`] crate. use anyhow::{Context, Result, bail}; -use log::{error, info, trace, warn}; use mdbook_renderer::{RenderContext, Renderer}; use std::fs; use std::process::Stdio; +use tracing::{error, info, trace, warn}; pub use self::markdown_renderer::MarkdownRenderer; @@ -30,7 +30,7 @@ mod markdown_renderer; /// whatever it wants, to avoid spamming users it is recommended to avoid /// unnecessary output. /// -/// To help choose the appropriate output level, the `RUST_LOG` environment +/// To help choose the appropriate output level, the `MDBOOK_LOG` environment /// variable will be passed through to the subprocess, if set. /// /// If the subprocess wishes to indicate that rendering failed, it should exit diff --git a/crates/mdbook-driver/src/init.rs b/crates/mdbook-driver/src/init.rs index df5945ca6a..78a2de6364 100644 --- a/crates/mdbook-driver/src/init.rs +++ b/crates/mdbook-driver/src/init.rs @@ -6,10 +6,10 @@ use std::path::PathBuf; use super::MDBook; use anyhow::{Context, Result}; -use log::{debug, error, info, trace}; use mdbook_core::config::Config; use mdbook_core::utils::fs::write_file; use mdbook_html::theme; +use tracing::{debug, error, info, trace}; /// A helper for setting up a new book and its directory structure. #[derive(Debug, Clone, PartialEq)] diff --git a/crates/mdbook-driver/src/lib.rs b/crates/mdbook-driver/src/lib.rs index c2b3123f07..f89ef8115d 100644 --- a/crates/mdbook-driver/src/lib.rs +++ b/crates/mdbook-driver/src/lib.rs @@ -65,12 +65,12 @@ mod load; mod mdbook; use anyhow::{Context, Result, bail}; -use log::{error, warn}; pub use mdbook::MDBook; pub use mdbook_core::{book, config, errors}; use shlex::Shlex; use std::path::{Path, PathBuf}; use std::process::Command; +use tracing::{error, warn}; /// Creates a [`Command`] for command renderers and preprocessors. fn compose_command(cmd: &str, root: &Path) -> Result { diff --git a/crates/mdbook-driver/src/load.rs b/crates/mdbook-driver/src/load.rs index 401f08fcc9..ab7b13b49e 100644 --- a/crates/mdbook-driver/src/load.rs +++ b/crates/mdbook-driver/src/load.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use log::debug; use mdbook_core::book::{Book, BookItem, Chapter}; use mdbook_core::config::BuildConfig; use mdbook_core::utils::bracket_escape; @@ -7,6 +6,7 @@ use mdbook_summary::{Link, Summary, SummaryItem, parse_summary}; use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::Path; +use tracing::debug; /// Load a book into memory from its `src/` directory. pub(crate) fn load_book>(src_dir: P, cfg: &BuildConfig) -> Result { diff --git a/crates/mdbook-driver/src/mdbook.rs b/crates/mdbook-driver/src/mdbook.rs index d173502ba4..27683bd737 100644 --- a/crates/mdbook-driver/src/mdbook.rs +++ b/crates/mdbook-driver/src/mdbook.rs @@ -6,7 +6,6 @@ use crate::init::BookBuilder; use crate::load::{load_book, load_book_from_disk}; use anyhow::{Context, Error, Result, bail}; use indexmap::IndexMap; -use log::{debug, error, info, log_enabled, trace, warn}; use mdbook_core::book::{Book, BookItem, BookItems}; use mdbook_core::config::{Config, RustEdition}; use mdbook_core::utils; @@ -21,6 +20,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use tempfile::Builder as TempFileBuilder; use topological_sort::TopologicalSort; +use tracing::{debug, error, info, trace, warn}; #[cfg(test)] mod tests; @@ -58,7 +58,7 @@ impl MDBook { config.update_from_env(); - if log_enabled!(log::Level::Trace) { + if tracing::enabled!(tracing::Level::TRACE) { for line in format!("Config: {config:#?}").lines() { trace!("{}", line); } diff --git a/crates/mdbook-html/Cargo.toml b/crates/mdbook-html/Cargo.toml index e7b288cc87..0b5e5fcb1a 100644 --- a/crates/mdbook-html/Cargo.toml +++ b/crates/mdbook-html/Cargo.toml @@ -14,7 +14,6 @@ elasticlunr-rs = { workspace = true, optional = true } font-awesome-as-a-crate.workspace = true handlebars.workspace = true hex.workspace = true -log.workspace = true mdbook-core.workspace = true mdbook-markdown.workspace = true mdbook-renderer.workspace = true @@ -23,6 +22,7 @@ regex.workspace = true serde.workspace = true serde_json.workspace = true sha2.workspace = true +tracing.workspace = true [dev-dependencies] pretty_assertions.workspace = true diff --git a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs index 86c16eb142..2fa6efbc3e 100644 --- a/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs +++ b/crates/mdbook-html/src/html_handlebars/hbs_renderer.rs @@ -3,7 +3,6 @@ use super::static_files::StaticFiles; use crate::theme::Theme; use anyhow::{Context, Result, bail}; use handlebars::Handlebars; -use log::{debug, info, trace, warn}; use mdbook_core::book::{Book, BookItem, Chapter}; use mdbook_core::config::{BookConfig, Code, Config, HtmlConfig, Playground, RustEdition}; use mdbook_core::utils; @@ -18,6 +17,8 @@ use std::collections::HashMap; use std::fs::{self, File}; use std::path::{Path, PathBuf}; use std::sync::LazyLock; +use tracing::error; +use tracing::{debug, info, trace, warn}; /// The HTML renderer for mdBook. #[derive(Default)] @@ -286,7 +287,7 @@ impl HtmlHandlebars { return Ok(()); } - log::debug!("Emitting redirects"); + debug!("Emitting redirects"); let redirects = combine_fragment_redirects(redirects); for (original, (dest, fragment_map)) in redirects { @@ -306,7 +307,7 @@ impl HtmlHandlebars { destination." ); } - log::debug!("Redirecting \"{}\" → \"{}\"", original, dest); + debug!("Redirecting \"{}\" → \"{}\"", original, dest); self.emit_redirect(handlebars, &filename, &dest, &fragment_map)?; } @@ -1034,7 +1035,7 @@ fn combine_fragment_redirects(redirects: &HashMap) -> CombinedRe if let Some((source_path, source_fragment)) = original.rsplit_once('#') { let e = combined.entry(source_path.to_string()).or_default(); if let Some(old) = e.1.insert(format!("#{source_fragment}"), new.clone()) { - log::error!( + error!( "internal error: found duplicate fragment redirect \ {old} for {source_path}#{source_fragment}" ); diff --git a/crates/mdbook-html/src/html_handlebars/helpers/fontawesome.rs b/crates/mdbook-html/src/html_handlebars/helpers/fontawesome.rs index f1b04c03b3..3ece0973bd 100644 --- a/crates/mdbook-html/src/html_handlebars/helpers/fontawesome.rs +++ b/crates/mdbook-html/src/html_handlebars/helpers/fontawesome.rs @@ -2,8 +2,8 @@ use font_awesome_as_a_crate as fa; use handlebars::{ Context, Handlebars, Helper, Output, RenderContext, RenderError, RenderErrorReason, }; -use log::trace; use std::str::FromStr; +use tracing::trace; pub(crate) fn fa_helper( h: &Helper<'_>, diff --git a/crates/mdbook-html/src/html_handlebars/search.rs b/crates/mdbook-html/src/html_handlebars/search.rs index a424f80132..9575ea3168 100644 --- a/crates/mdbook-html/src/html_handlebars/search.rs +++ b/crates/mdbook-html/src/html_handlebars/search.rs @@ -2,7 +2,6 @@ use super::static_files::StaticFiles; use crate::theme::searcher; use anyhow::{Context, Result, bail}; use elasticlunr::{Index, IndexBuilder}; -use log::{debug, warn}; use mdbook_core::book::{Book, BookItem, Chapter}; use mdbook_core::config::{Search, SearchChapterSettings}; use mdbook_core::utils; @@ -14,6 +13,7 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; use std::sync::LazyLock; +use tracing::{debug, warn}; const MAX_WORD_LENGTH_TO_INDEX: usize = 80; diff --git a/crates/mdbook-html/src/html_handlebars/static_files.rs b/crates/mdbook-html/src/html_handlebars/static_files.rs index 8c370214ca..62f07f5032 100644 --- a/crates/mdbook-html/src/html_handlebars/static_files.rs +++ b/crates/mdbook-html/src/html_handlebars/static_files.rs @@ -3,7 +3,6 @@ use super::helpers::resources::ResourceHelper; use crate::theme::{self, Theme, playground_editor}; use anyhow::{Context, Result}; -use log::debug; use mdbook_core::config::HtmlConfig; use mdbook_core::utils; use std::borrow::Cow; @@ -11,6 +10,7 @@ use std::collections::HashMap; use std::fs::{self, File}; use std::path::{Path, PathBuf}; use std::sync::LazyLock; +use tracing::debug; /// Map static files to their final names and contents. /// diff --git a/crates/mdbook-html/src/theme/mod.rs b/crates/mdbook-html/src/theme/mod.rs index e863f283f3..ab5b0fb252 100644 --- a/crates/mdbook-html/src/theme/mod.rs +++ b/crates/mdbook-html/src/theme/mod.rs @@ -1,10 +1,10 @@ #![allow(missing_docs)] use anyhow::Result; -use log::warn; use std::fs::File; use std::io::Read; use std::path::{Path, PathBuf}; +use tracing::{info, warn}; pub mod fonts; pub mod playground_editor; @@ -133,7 +133,7 @@ impl Theme { if entry.file_name() == "fonts.css" { None } else if entry.file_type().ok()?.is_dir() { - log::info!("skipping font directory {:?}", entry.path()); + info!("skipping font directory {:?}", entry.path()); None } else { Some(entry.path()) diff --git a/crates/mdbook-markdown/Cargo.toml b/crates/mdbook-markdown/Cargo.toml index 0dc3e723d6..f64140749c 100644 --- a/crates/mdbook-markdown/Cargo.toml +++ b/crates/mdbook-markdown/Cargo.toml @@ -8,9 +8,9 @@ repository.workspace = true rust-version.workspace = true [dependencies] -log.workspace = true pulldown-cmark.workspace = true regex.workspace = true +tracing.workspace = true [lints] workspace = true diff --git a/crates/mdbook-markdown/src/lib.rs b/crates/mdbook-markdown/src/lib.rs index dda97757bf..22c11f8a03 100644 --- a/crates/mdbook-markdown/src/lib.rs +++ b/crates/mdbook-markdown/src/lib.rs @@ -15,6 +15,7 @@ use std::collections::HashMap; use std::fmt::Write; use std::path::Path; use std::sync::LazyLock; +use tracing::warn; #[doc(inline)] pub use pulldown_cmark; @@ -126,7 +127,7 @@ pub fn render_markdown(text: &str, options: &HtmlRenderOptions<'_>) -> String { Event::Start(Tag::FootnoteDefinition(name)) => { prev_was_footnote = false; if !in_footnote.is_empty() { - log::warn!( + warn!( "internal bug: nested footnote not expected in {:?}", options.path ); @@ -139,7 +140,7 @@ pub fn render_markdown(text: &str, options: &HtmlRenderOptions<'_>) -> String { let name = std::mem::take(&mut in_footnote_name); if footnote_defs.contains_key(&name) { - log::warn!( + warn!( "footnote `{name}` in {} defined multiple times - \ not updating to new definition", options.path.display() @@ -212,7 +213,7 @@ fn add_footnote_defs( // Remove unused. defs.retain(|(name, _)| { if !numbers.contains_key(name) { - log::warn!( + warn!( "footnote `{name}` in `{}` is defined but not referenced", options.path.display() ); diff --git a/crates/mdbook-summary/Cargo.toml b/crates/mdbook-summary/Cargo.toml index 4d52abb2d2..d6b8e4a227 100644 --- a/crates/mdbook-summary/Cargo.toml +++ b/crates/mdbook-summary/Cargo.toml @@ -9,11 +9,11 @@ rust-version.workspace = true [dependencies] anyhow.workspace = true -log.workspace = true mdbook-core.workspace = true memchr.workspace = true pulldown-cmark.workspace = true serde.workspace = true +tracing.workspace = true [lints] workspace = true diff --git a/crates/mdbook-summary/src/lib.rs b/crates/mdbook-summary/src/lib.rs index 2039a63e9b..9cf959f510 100644 --- a/crates/mdbook-summary/src/lib.rs +++ b/crates/mdbook-summary/src/lib.rs @@ -5,7 +5,6 @@ //! file structure for [mdBook](https://rust-lang.github.io/mdBook/). use anyhow::{Context, Error, Result, bail}; -use log::{debug, trace, warn}; pub use mdbook_core::book::SectionNumber; use memchr::Memchr; use pulldown_cmark::{DefaultBrokenLinkCallback, Event, HeadingLevel, Tag, TagEnd}; @@ -13,6 +12,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::fmt::Display; use std::path::{Path, PathBuf}; +use tracing::{debug, trace, warn}; /// Parse the text from a `SUMMARY.md` file into a sort of "recipe" to be /// used when loading a book from disk. diff --git a/guide/src/for_developers/backends.md b/guide/src/for_developers/backends.md index 1c0dc40e7e..2ab3b3b7f7 100644 --- a/guide/src/for_developers/backends.md +++ b/guide/src/for_developers/backends.md @@ -317,7 +317,7 @@ the "rule of silence" and only generate output when necessary (e.g. an error in generation or a warning). All environment variables are passed through to the backend, allowing you to use -the usual `RUST_LOG` to control logging verbosity. +the usual `MDBOOK_LOG` to control logging verbosity. ## Wrapping up diff --git a/src/cmd/build.rs b/src/cmd/build.rs index b4ac48574b..41536cae85 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -2,6 +2,7 @@ use super::command_prelude::*; use crate::{get_book_dir, open}; use anyhow::Result; use mdbook_driver::MDBook; +use tracing::error; // Create clap subcommand arguments pub fn make_subcommand() -> Command { diff --git a/src/cmd/init.rs b/src/cmd/init.rs index 9b0c35bc35..df01825745 100644 --- a/src/cmd/init.rs +++ b/src/cmd/init.rs @@ -6,6 +6,7 @@ use mdbook_driver::MDBook; use std::io; use std::io::Write; use std::process::Command; +use tracing::debug; // Create clap subcommand arguments pub fn make_subcommand() -> ClapCommand { diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 6d8a06167d..7bb216da63 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -15,6 +15,7 @@ use std::net::{SocketAddr, ToSocketAddrs}; use std::path::PathBuf; use tokio::sync::broadcast; use tower_http::services::{ServeDir, ServeFile}; +use tracing::{error, info, trace}; /// The HTTP endpoint for the websocket used to trigger reloads when a file changes. const LIVE_RELOAD_ENDPOINT: &str = "__livereload"; diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index bd9c19b233..0c6fa87c86 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -3,6 +3,7 @@ use crate::{get_book_dir, open}; use anyhow::Result; use mdbook_driver::MDBook; use std::path::{Path, PathBuf}; +use tracing::error; mod native; mod poller; diff --git a/src/cmd/watch/native.rs b/src/cmd/watch/native.rs index 0eb04e0a25..b4cbc9a774 100644 --- a/src/cmd/watch/native.rs +++ b/src/cmd/watch/native.rs @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf}; use std::sync::mpsc::channel; use std::thread::sleep; use std::time::Duration; +use tracing::{error, info, warn}; pub fn rebuild_on_change( book_dir: &Path, @@ -71,7 +72,7 @@ pub fn rebuild_on_change( .filter_map(|event| match event { Ok(events) => Some(events), Err(error) => { - log::warn!("error while watching for changes: {error}"); + warn!("error while watching for changes: {error}"); None } }) diff --git a/src/cmd/watch/poller.rs b/src/cmd/watch/poller.rs index 65a5118882..666a6c77ca 100644 --- a/src/cmd/watch/poller.rs +++ b/src/cmd/watch/poller.rs @@ -11,6 +11,7 @@ use std::collections::HashMap; use std::fs::FileType; use std::path::{Path, PathBuf}; use std::time::{Duration, Instant, SystemTime}; +use tracing::{debug, error, info, trace, warn}; use walkdir::WalkDir; /// Calls the closure when a book source file is changed, blocking indefinitely. diff --git a/src/main.rs b/src/main.rs index b35d001928..2bd834252e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,20 +4,15 @@ #[macro_use] extern crate clap; -#[macro_use] -extern crate log; use anyhow::anyhow; -use chrono::Local; use clap::{Arg, ArgMatches, Command}; use clap_complete::Shell; -use env_logger::Builder; -use log::LevelFilter; use mdbook_core::utils; use std::env; use std::ffi::OsStr; -use std::io::Write; use std::path::PathBuf; +use tracing::{error, info}; mod cmd; @@ -99,29 +94,36 @@ fn create_clap_command() -> Command { } fn init_logger() { - let mut builder = Builder::new(); - - builder.format(|formatter, record| { - writeln!( - formatter, - "{} [{}] ({}): {}", - Local::now().format("%Y-%m-%d %H:%M:%S"), - record.level(), - record.target(), - record.args() - ) - }); - - if let Ok(var) = env::var("RUST_LOG") { - builder.parse_filters(&var); - } else { - // if no RUST_LOG provided, default to logging at the Info level - builder.filter(None, LevelFilter::Info); - // Filter extraneous html5ever not-implemented messages - builder.filter(Some("html5ever"), LevelFilter::Error); - } - - builder.init(); + let filter = tracing_subscriber::EnvFilter::builder() + .with_env_var("MDBOOK_LOG") + .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) + .from_env_lossy(); + let log_env = std::env::var("MDBOOK_LOG"); + // Silence some particularly noisy dependencies unless the user + // specifically asks for them. + let silence_unless_specified = |filter: tracing_subscriber::EnvFilter, target| { + if !log_env.as_ref().map_or(false, |s| { + s.split(',').any(|directive| directive.starts_with(target)) + }) { + filter.add_directive(format!("{target}=warn").parse().unwrap()) + } else { + filter + } + }; + let filter = silence_unless_specified(filter, "handlebars"); + let filter = silence_unless_specified(filter, "html5ever"); + + // Don't show the target by default, since it generally isn't useful + // unless you are overriding the level. + let with_target = log_env.is_ok(); + + tracing_subscriber::fmt() + .without_time() + .with_ansi(std::io::IsTerminal::is_terminal(&std::io::stderr())) + .with_writer(std::io::stderr) + .with_env_filter(filter) + .with_target(with_target) + .init(); } fn get_book_dir(args: &ArgMatches) -> PathBuf { diff --git a/tests/testsuite/book_test.rs b/tests/testsuite/book_test.rs index 5b7369d811..5b9db06812 100644 --- a/tests/testsuite/book_test.rs +++ b/tests/testsuite/book_test.rs @@ -360,7 +360,7 @@ impl BookCommand { /// Use this to debug a command. /// - /// Pass the value that you would normally pass to `RUST_LOG`, and this + /// Pass the value that you would normally pass to `MDBOOK_LOG`, and this /// will enable logging, print the command that runs and its output. /// /// This will fail if you use it in CI. @@ -378,7 +378,7 @@ impl BookCommand { let mut cmd = Command::new(env!("CARGO_BIN_EXE_mdbook")); cmd.current_dir(&self.dir) .args(&self.args) - .env_remove("RUST_LOG") + .env_remove("MDBOOK_LOG") // Don't read the system git config which is out of our control. .env("GIT_CONFIG_NOSYSTEM", "1") .env("GIT_CONFIG_GLOBAL", &self.dir) @@ -389,7 +389,7 @@ impl BookCommand { .env_remove("GIT_COMMITTER_NAME"); if let Some(debug) = &self.debug { - cmd.env("RUST_LOG", debug); + cmd.env("MDBOOK_LOG", debug); } for (k, v) in &self.env { @@ -479,23 +479,9 @@ static LITERAL_REDACTIONS: &[(&str, &str)] = &[ ("[EXE]", std::env::consts::EXE_SUFFIX), ]; -/// This makes it easier to write regex replacements that are guaranteed to only -/// get compiled once -macro_rules! regex { - ($re:literal $(,)?) => {{ - static RE: std::sync::OnceLock = std::sync::OnceLock::new(); - RE.get_or_init(|| regex::Regex::new($re).unwrap()) - }}; -} - fn assert(root: &Path) -> snapbox::Assert { let mut subs = snapbox::Redactions::new(); subs.insert("[ROOT]", root.to_path_buf()).unwrap(); - subs.insert( - "[TIMESTAMP]", - regex!(r"(?m)(?20\d\d-\d{2}-\d{2} \d{2}:\d{2}:\d{2})"), - ) - .unwrap(); subs.insert("[VERSION]", mdbook_core::MDBOOK_VERSION) .unwrap(); diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 7b6cfc4d3d..e3851c1271 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -10,9 +10,9 @@ use crate::prelude::*; fn basic_build() { BookTest::from_dir("build/basic_build").run("build", |cmd| { cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }); @@ -24,8 +24,8 @@ fn basic_build() { fn failure_on_missing_file() { BookTest::from_dir("build/missing_file").run("build", |cmd| { cmd.expect_failure().expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Chapter file not found, ./chapter_1.md -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND] +ERROR Chapter file not found, ./chapter_1.md +[TAB]Caused by: [NOT_FOUND] "#]]); }); @@ -46,10 +46,10 @@ fn create_missing() { fn no_reserved_filename() { BookTest::from_dir("build/no_reserved_filename").run("build", |cmd| { cmd.expect_failure().expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: print.md is reserved for internal use + INFO Book building has started + INFO Running the html backend +ERROR Rendering failed +[TAB]Caused by: print.md is reserved for internal use "#]]); }); @@ -77,9 +77,9 @@ fn dest_dir_relative_path() { cmd.args(&["--dest-dir", "foo", ".."]) .current_dir(¤t_dir) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/work/foo` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/work/foo` "#]]); }); diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index 52c45d337c..f5b14875a2 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -120,8 +120,8 @@ fn bad_config_top_level() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Invalid configuration file -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: TOML parse error at line 1, column 1 +ERROR Invalid configuration file +[TAB]Caused by: TOML parse error at line 1, column 1 | 1 | foo = 123 | ^^^ @@ -145,8 +145,8 @@ fn bad_config_top_level_table() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Invalid configuration file -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: TOML parse error at line 1, column 2 +ERROR Invalid configuration file +[TAB]Caused by: TOML parse error at line 1, column 2 | 1 | [other] | ^^^^^ @@ -171,8 +171,8 @@ fn bad_config_in_book_table() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Invalid configuration file -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: TOML parse error at line 3, column 1 +ERROR Invalid configuration file +[TAB]Caused by: TOML parse error at line 3, column 1 | 3 | foo = 123 | ^^^ @@ -196,8 +196,8 @@ fn bad_config_in_rust_table() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Invalid configuration file -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: TOML parse error at line 2, column 1 +ERROR Invalid configuration file +[TAB]Caused by: TOML parse error at line 2, column 1 | 2 | title = "bad-config" | ^^^^^ diff --git a/tests/testsuite/includes.rs b/tests/testsuite/includes.rs index 300df28e9f..7bf9480885 100644 --- a/tests/testsuite/includes.rs +++ b/tests/testsuite/includes.rs @@ -45,10 +45,10 @@ fn recursive_include() { BookTest::from_dir("includes/all_includes") .run("build", |cmd| { cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [ERROR] (mdbook_driver::builtin_preprocessors::links): Stack depth exceeded in recursive.md. Check for cyclic includes -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started +ERROR Stack depth exceeded in recursive.md. Check for cyclic includes + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }) diff --git a/tests/testsuite/init.rs b/tests/testsuite/init.rs index 852f1a2fb3..06b4f5f518 100644 --- a/tests/testsuite/init.rs +++ b/tests/testsuite/init.rs @@ -19,7 +19,7 @@ All done, no errors... "#]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::init): Creating a new book with stub content + INFO Creating a new book with stub content "#]]); }) @@ -84,7 +84,7 @@ All done, no errors... "#]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::init): Creating a new book with stub content + INFO Creating a new book with stub content "#]]); }) @@ -115,7 +115,7 @@ All done, no errors... "#]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::init): Creating a new book with stub content + INFO Creating a new book with stub content "#]]) .args(&["--title", "Example title"]); diff --git a/tests/testsuite/markdown.rs b/tests/testsuite/markdown.rs index cc1cb89681..8317b2a66c 100644 --- a/tests/testsuite/markdown.rs +++ b/tests/testsuite/markdown.rs @@ -20,13 +20,13 @@ fn footnotes() { BookTest::from_dir("markdown/footnotes") .run("build", |cmd| { cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [WARN] (mdbook_markdown): footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition -[TIMESTAMP] [WARN] (mdbook_markdown): footnote `unused` in `footnotes.md` is defined but not referenced -[TIMESTAMP] [WARN] (mdbook_markdown): footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition -[TIMESTAMP] [WARN] (mdbook_markdown): footnote `unused` in `footnotes.md` is defined but not referenced -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + WARN footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition + WARN footnote `unused` in `footnotes.md` is defined but not referenced + WARN footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition + WARN footnote `unused` in `footnotes.md` is defined but not referenced + INFO HTML book written to `[ROOT]/book` "#]]); }) diff --git a/tests/testsuite/preprocessor.rs b/tests/testsuite/preprocessor.rs index 7c9296794e..cd8b9efad1 100644 --- a/tests/testsuite/preprocessor.rs +++ b/tests/testsuite/preprocessor.rs @@ -49,9 +49,9 @@ fn runs_preprocessors() { fn nop_preprocessor() { BookTest::from_dir("preprocessor/nop_preprocessor").run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }); @@ -60,17 +60,16 @@ fn nop_preprocessor() { // Failing preprocessor generates an error. #[test] fn failing_preprocessor() { - BookTest::from_dir("preprocessor/failing_preprocessor") - .run("build", |cmd| { - cmd.expect_failure() - .expect_stdout(str![[""]]) - .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started + BookTest::from_dir("preprocessor/failing_preprocessor").run("build", |cmd| { + cmd.expect_failure() + .expect_stdout(str![[""]]) + .expect_stderr(str![[r#" + INFO Book building has started Boom!!1! -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: The "nop-preprocessor" preprocessor exited unsuccessfully with [EXIT_STATUS]: 1 status +ERROR The "nop-preprocessor" preprocessor exited unsuccessfully with [EXIT_STATUS]: 1 status "#]]); - }); + }); } fn example() -> CmdPreprocessor { @@ -128,9 +127,9 @@ fn relative_command_path() { ) .run("build", |cmd| { cmd.expect_stdout(str![""]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }) @@ -143,9 +142,9 @@ fn relative_command_path() { cmd.current_dir(cmd.dir.join("src")) .expect_stdout(str![""]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/src/../book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/src/../book` "#]]); }) @@ -160,10 +159,10 @@ fn missing_preprocessor() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [ERROR] (mdbook_driver): The command `trduyvbhijnorgevfuhn` wasn't found, is the `missing` preprocessor installed? If you want to ignore this error when the `missing` preprocessor is not installed, set `optional = true` in the `[preprocessor.missing]` section of the book.toml configuration file. -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Unable to run the preprocessor `missing` -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND] + INFO Book building has started +ERROR The command `trduyvbhijnorgevfuhn` wasn't found, is the `missing` preprocessor installed? If you want to ignore this error when the `missing` preprocessor is not installed, set `optional = true` in the `[preprocessor.missing]` section of the book.toml configuration file. +ERROR Unable to run the preprocessor `missing` +[TAB]Caused by: [NOT_FOUND] "#]]); }); @@ -174,10 +173,10 @@ fn missing_preprocessor() { fn missing_optional_not_fatal() { BookTest::from_dir("preprocessor/missing_optional_not_fatal").run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [WARN] (mdbook_driver): The command `trduyvbhijnorgevfuhn` for preprocessor `missing` was not found, but is marked as optional. -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + WARN The command `trduyvbhijnorgevfuhn` for preprocessor `missing` was not found, but is marked as optional. + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }); @@ -239,14 +238,14 @@ fn extension_compatibility() { // that the built book is identical with the preprocessor enabled. test.run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [WARN] (mdbook_driver): The command `./my-preprocessor` for preprocessor `my-preprocessor` was not found, but is marked as optional. -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book/html` -[TIMESTAMP] [WARN] (mdbook_driver): The command `./my-preprocessor` for preprocessor `my-preprocessor` was not found, but is marked as optional. -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the my-renderer backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "my-renderer" renderer -[TIMESTAMP] [WARN] (mdbook_driver): The command `./my-renderer` for backend `my-renderer` was not found, but is marked as optional. + INFO Book building has started + WARN The command `./my-preprocessor` for preprocessor `my-preprocessor` was not found, but is marked as optional. + INFO Running the html backend + INFO HTML book written to `[ROOT]/book/html` + WARN The command `./my-preprocessor` for preprocessor `my-preprocessor` was not found, but is marked as optional. + INFO Running the my-renderer backend + INFO Invoking the "my-renderer" renderer + WARN The command `./my-renderer` for backend `my-renderer` was not found, but is marked as optional. "#]]); }); @@ -441,11 +440,11 @@ fn extension_compatibility() { ) .run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book/html` -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the my-renderer backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "my-renderer" renderer + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book/html` + INFO Running the my-renderer backend + INFO Invoking the "my-renderer" renderer "#]]); }) diff --git a/tests/testsuite/redirects.rs b/tests/testsuite/redirects.rs index c73703caeb..84c776832d 100644 --- a/tests/testsuite/redirects.rs +++ b/tests/testsuite/redirects.rs @@ -22,11 +22,11 @@ fn redirects_are_emitted_correctly() { fn redirect_removed_with_fragments_only() { BookTest::from_dir("redirects/redirect_removed_with_fragments_only").run("build", |cmd| { cmd.expect_failure().expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to emit redirects -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: redirect entry for `old-file.html` only has source paths with `#` fragments + INFO Book building has started + INFO Running the html backend +ERROR Rendering failed +[TAB]Caused by: Unable to emit redirects +[TAB]Caused by: redirect entry for `old-file.html` only has source paths with `#` fragments There must be an entry without the `#` fragment to determine the default destination. "#]]); @@ -38,10 +38,10 @@ There must be an entry without the `#` fragment to determine the default destina fn redirect_existing_page() { BookTest::from_dir("redirects/redirect_existing_page").run("build", |cmd| { cmd.expect_failure().expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: redirect found for existing chapter at `/chapter_1.html` + INFO Book building has started + INFO Running the html backend +ERROR Rendering failed +[TAB]Caused by: redirect found for existing chapter at `/chapter_1.html` Either delete the redirect or remove the chapter. "#]]); diff --git a/tests/testsuite/renderer.rs b/tests/testsuite/renderer.rs index b8070c5c9d..2dbe272735 100644 --- a/tests/testsuite/renderer.rs +++ b/tests/testsuite/renderer.rs @@ -64,12 +64,12 @@ fn failing_command() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the failing backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "failing" renderer -[TIMESTAMP] [ERROR] (mdbook_driver::builtin_renderers): Renderer exited with non-zero return code. -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: The "failing" renderer failed + INFO Book building has started + INFO Running the failing backend + INFO Invoking the "failing" renderer +ERROR Renderer exited with non-zero return code. +ERROR Rendering failed +[TAB]Caused by: The "failing" renderer failed "#]]); }); @@ -82,13 +82,13 @@ fn missing_renderer() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the missing backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "missing" renderer -[TIMESTAMP] [ERROR] (mdbook_driver): The command `trduyvbhijnorgevfuhn` wasn't found, is the `missing` backend installed? If you want to ignore this error when the `missing` backend is not installed, set `optional = true` in the `[output.missing]` section of the book.toml configuration file. -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to run the backend `missing` -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND] + INFO Book building has started + INFO Running the missing backend + INFO Invoking the "missing" renderer +ERROR The command `trduyvbhijnorgevfuhn` wasn't found, is the `missing` backend installed? If you want to ignore this error when the `missing` backend is not installed, set `optional = true` in the `[output.missing]` section of the book.toml configuration file. +ERROR Rendering failed +[TAB]Caused by: Unable to run the backend `missing` +[TAB]Caused by: [NOT_FOUND] "#]]); }); @@ -99,10 +99,10 @@ fn missing_renderer() { fn missing_optional_not_fatal() { BookTest::from_dir("renderer/missing_optional_not_fatal").run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the missing backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "missing" renderer -[TIMESTAMP] [WARN] (mdbook_driver): The command `trduyvbhijnorgevfuhn` for backend `missing` was not found, but is marked as optional. + INFO Book building has started + INFO Running the missing backend + INFO Invoking the "missing" renderer + WARN The command `trduyvbhijnorgevfuhn` for backend `missing` was not found, but is marked as optional. "#]]); }); @@ -131,9 +131,9 @@ Hello World! "#]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the arguments backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "arguments" renderer + INFO Book building has started + INFO Running the arguments backend + INFO Invoking the "arguments" renderer "#]]); }); @@ -156,9 +156,9 @@ fn backends_receive_render_context_via_stdin() { ) .run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the cat-to-file backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "cat-to-file" renderer + INFO Book building has started + INFO Running the cat-to-file backend + INFO Invoking the "cat-to-file" renderer "#]]); }) @@ -233,9 +233,9 @@ fn relative_command_path() { ) .run("build", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the myrenderer backend -[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "myrenderer" renderer + INFO Book building has started + INFO Running the myrenderer backend + INFO Invoking the "myrenderer" renderer "#]]); }) diff --git a/tests/testsuite/search.rs b/tests/testsuite/search.rs index 5471399c32..0596f9c7f1 100644 --- a/tests/testsuite/search.rs +++ b/tests/testsuite/search.rs @@ -126,10 +126,10 @@ fn with_no_source_path() { fn chapter_settings_validation_error() { BookTest::from_dir("search/chapter_settings_validation_error").run("build", |cmd| { cmd.expect_failure().expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [output.html.search.chapter] key `does-not-exist` does not match any chapter paths + INFO Book building has started + INFO Running the html backend +ERROR Rendering failed +[TAB]Caused by: [output.html.search.chapter] key `does-not-exist` does not match any chapter paths "#]]); }); diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index dc43988eca..e83a94ef33 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -7,9 +7,9 @@ use crate::prelude::*; fn passing_tests() { BookTest::from_dir("test/passing_tests").run("test", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Intro': "intro.md" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Passing 1': "passing1.md" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Passing 2': "passing2.md" + INFO Testing chapter 'Intro': "intro.md" + INFO Testing chapter 'Passing 1': "passing1.md" + INFO Testing chapter 'Passing 2': "passing2.md" "#]]); }); @@ -27,8 +27,8 @@ fn failing_tests() { // still includes a little bit of output, so if that is a problem, // add more redactions. .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Failing Tests': "failing.md" -[TIMESTAMP] [ERROR] (mdbook_driver::mdbook): rustdoc returned an error: + INFO Testing chapter 'Failing Tests': "failing.md" +ERROR rustdoc returned an error: --- stdout @@ -38,8 +38,8 @@ test failing.md - Failing_Tests (line 3) ... FAILED thread [..] panicked at failing.md:3:1: fail ... -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Failing Include': "failing_include.md" -[TIMESTAMP] [ERROR] (mdbook_driver::mdbook): rustdoc returned an error: + INFO Testing chapter 'Failing Include': "failing_include.md" +ERROR rustdoc returned an error: --- stdout ... @@ -48,7 +48,7 @@ test failing_include.md - Failing_Include (line 3) ... FAILED thread [..] panicked at failing_include.md:3:1: failing! ... -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: One or more tests failed +ERROR One or more tests failed "#]]); }); @@ -62,14 +62,14 @@ fn test_individual_chapter() { cmd.args(&["Passing 1"]) .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Passing 1': "passing1.md" + INFO Testing chapter 'Passing 1': "passing1.md" "#]]); }) // Can also be a source path. .run("test -c passing2.md", |cmd| { cmd.expect_stdout(str![[""]]).expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Testing chapter 'Passing 2': "passing2.md" + INFO Testing chapter 'Passing 2': "passing2.md" "#]]); }); @@ -82,7 +82,7 @@ fn chapter_not_found() { cmd.expect_failure() .expect_stdout(str![[""]]) .expect_stderr(str![[r#" -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Chapter not found: bogus +ERROR Chapter not found: bogus "#]]); }); diff --git a/tests/testsuite/theme.rs b/tests/testsuite/theme.rs index 97cb2a1823..0cbb372493 100644 --- a/tests/testsuite/theme.rs +++ b/tests/testsuite/theme.rs @@ -5,14 +5,12 @@ use crate::prelude::*; // Checks what happens if the theme directory is missing. #[test] fn missing_theme() { - BookTest::from_dir("theme/missing_theme") - .run("build", |cmd| { -cmd.expect_failure() - .expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed -[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: theme dir [ROOT]/./non-existent-directory does not exist + BookTest::from_dir("theme/missing_theme").run("build", |cmd| { + cmd.expect_failure().expect_stderr(str![[r#" + INFO Book building has started + INFO Running the html backend +ERROR Rendering failed +[TAB]Caused by: theme dir [ROOT]/./non-existent-directory does not exist "#]]); }); @@ -24,9 +22,9 @@ fn empty_theme() { BookTest::from_dir("theme/empty_theme").run("build", |cmd| { std::fs::create_dir(cmd.dir.join("theme")).unwrap(); cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }); @@ -147,9 +145,9 @@ fn empty_fonts_css() { BookTest::from_dir("theme/empty_fonts_css") .run("build", |cmd| { cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); }) @@ -163,9 +161,9 @@ fn custom_fonts_css() { BookTest::from_dir("theme/custom_fonts_css") .run("build", |cmd| { cmd.expect_stderr(str![[r#" -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started -[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the html backend -[TIMESTAMP] [INFO] (mdbook_html::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` + INFO Book building has started + INFO Running the html backend + INFO HTML book written to `[ROOT]/book` "#]]); })