Finish move of utils to mdbook-core

This updates everything for the move of utils to mdbook-core. There will
be followup commits that will be moving and refactoring these utils.
This simply moves them over unchanged (except visibility).
This commit is contained in:
Eric Huss 2025-07-21 12:20:21 -07:00
parent a224bfd7d7
commit fc76a47d6e
31 changed files with 84 additions and 56 deletions

5
Cargo.lock generated
View file

@ -1299,6 +1299,11 @@ name = "mdbook-core"
version = "0.5.0-alpha.1" version = "0.5.0-alpha.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"log",
"pulldown-cmark 0.10.3",
"regex",
"tempfile",
"toml",
] ]
[[package]] [[package]]

View file

@ -22,7 +22,12 @@ rust-version = "1.85.0" # Keep in sync with installation.md and .github/workflow
[workspace.dependencies] [workspace.dependencies]
anyhow = "1.0.98" anyhow = "1.0.98"
log = "0.4.27"
mdbook-core = { path = "crates/mdbook-core" } mdbook-core = { path = "crates/mdbook-core" }
pulldown-cmark = { version = "0.10.3", default-features = false, features = ["html"] } # Do not update, part of the public api.
regex = "1.11.1"
tempfile = "3.20.0"
toml = "0.5.11" # Do not update, see https://github.com/rust-lang/mdBook/issues/2037
[package] [package]
name = "mdbook" name = "mdbook"
@ -50,18 +55,18 @@ clap_complete = "4.3.2"
env_logger = "0.11.1" env_logger = "0.11.1"
handlebars = "6.0" handlebars = "6.0"
hex = "0.4.3" hex = "0.4.3"
log = "0.4.17" log.workspace = true
mdbook-core.workspace = true mdbook-core.workspace = true
memchr = "2.5.0" memchr = "2.5.0"
opener = "0.8.1" opener = "0.8.1"
pulldown-cmark = { version = "0.10.0", default-features = false, features = ["html"] } # Do not update, part of the public api. pulldown-cmark.workspace = true
regex = "1.8.1" regex.workspace = true
serde = { version = "1.0.163", features = ["derive"] } serde = { version = "1.0.163", features = ["derive"] }
serde_json = "1.0.96" serde_json = "1.0.96"
sha2 = "0.10.8" sha2 = "0.10.8"
shlex = "1.3.0" shlex = "1.3.0"
tempfile = "3.4.0" tempfile.workspace = true
toml = "0.5.11" # Do not update, see https://github.com/rust-lang/mdBook/issues/2037 toml.workspace = true
topological-sort = "0.2.2" topological-sort = "0.2.2"
# Watch feature # Watch feature

View file

@ -9,6 +9,13 @@ rust-version.workspace = true
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
log.workspace = true
pulldown-cmark.workspace = true
regex.workspace = true
toml.workspace = true
[dev-dependencies]
tempfile.workspace = true
[lints] [lints]
workspace = true workspace = true

View file

@ -10,3 +10,4 @@ pub const MDBOOK_VERSION: &str = env!("CARGO_PKG_VERSION");
pub mod errors { pub mod errors {
pub use anyhow::{Error, Result}; pub use anyhow::{Error, Result};
} }
pub mod utils;

View file

@ -29,7 +29,7 @@ pub fn write_file<P: AsRef<Path>>(build_dir: &Path, filename: P, content: &[u8])
/// ///
/// ```rust /// ```rust
/// # use std::path::Path; /// # use std::path::Path;
/// # use mdbook::utils::fs::path_to_root; /// # use mdbook_core::utils::fs::path_to_root;
/// let path = Path::new("some/relative/path"); /// let path = Path::new("some/relative/path");
/// assert_eq!(path_to_root(path), "../../"); /// assert_eq!(path_to_root(path), "../../");
/// ``` /// ```

View file

@ -12,7 +12,7 @@ use std::sync::LazyLock;
pub mod fs; pub mod fs;
mod string; mod string;
pub(crate) mod toml_ext; pub mod toml_ext;
pub use self::string::{ pub use self::string::{
take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines, take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines,
@ -424,7 +424,8 @@ pub fn log_backtrace(e: &Error) {
} }
} }
pub(crate) fn special_escape(mut s: &str) -> String { /// Escape characters to make it safe for an HTML string.
pub fn special_escape(mut s: &str) -> String {
let mut escaped = String::with_capacity(s.len()); let mut escaped = String::with_capacity(s.len());
let needs_escape: &[char] = &['<', '>', '\'', '"', '\\', '&']; let needs_escape: &[char] = &['<', '>', '\'', '"', '\\', '&'];
while let Some(next) = s.find(needs_escape) { while let Some(next) = s.find(needs_escape) {
@ -444,7 +445,8 @@ pub(crate) fn special_escape(mut s: &str) -> String {
escaped escaped
} }
pub(crate) fn bracket_escape(mut s: &str) -> String { /// Escape `<` and `>` for HTML.
pub fn bracket_escape(mut s: &str) -> String {
let mut escaped = String::with_capacity(s.len()); let mut escaped = String::with_capacity(s.len());
let needs_escape: &[char] = &['<', '>']; let needs_escape: &[char] = &['<', '>'];
while let Some(next) = s.find(needs_escape) { while let Some(next) = s.find(needs_escape) {

View file

@ -1,9 +1,16 @@
//! Helper for working with toml types.
use toml::value::{Table, Value}; use toml::value::{Table, Value};
pub(crate) trait TomlExt { /// Helper for working with toml types.
pub trait TomlExt {
/// Read a dotted key.
fn read(&self, key: &str) -> Option<&Value>; fn read(&self, key: &str) -> Option<&Value>;
/// Read a dotted key for a mutable value.
fn read_mut(&mut self, key: &str) -> Option<&mut Value>; fn read_mut(&mut self, key: &str) -> Option<&mut Value>;
/// Insert with a dotted key.
fn insert(&mut self, key: &str, value: Value); fn insert(&mut self, key: &str, value: Value);
/// Delete a dotted key value.
fn delete(&mut self, key: &str) -> Option<Value>; fn delete(&mut self, key: &str) -> Option<Value>;
} }

View file

@ -6,9 +6,9 @@ use std::path::{Path, PathBuf};
use super::summary::{Link, SectionNumber, Summary, SummaryItem, parse_summary}; use super::summary::{Link, SectionNumber, Summary, SummaryItem, parse_summary};
use crate::config::BuildConfig; use crate::config::BuildConfig;
use crate::utils::bracket_escape;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use log::debug; use log::debug;
use mdbook_core::utils::bracket_escape;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Load a book into memory from its `src/` directory. /// Load a book into memory from its `src/` directory.

View file

@ -5,9 +5,9 @@ use std::path::PathBuf;
use super::MDBook; use super::MDBook;
use crate::config::Config; use crate::config::Config;
use crate::theme; use crate::theme;
use crate::utils::fs::write_file;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use log::{debug, error, info, trace}; use log::{debug, error, info, trace};
use mdbook_core::utils::fs::write_file;
/// A helper for setting up a new book and its directory structure. /// A helper for setting up a new book and its directory structure.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

View file

@ -27,7 +27,7 @@ use crate::preprocess::{
CmdPreprocessor, IndexPreprocessor, LinkPreprocessor, Preprocessor, PreprocessorContext, CmdPreprocessor, IndexPreprocessor, LinkPreprocessor, Preprocessor, PreprocessorContext,
}; };
use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer}; use crate::renderer::{CmdRenderer, HtmlHandlebars, MarkdownRenderer, RenderContext, Renderer};
use crate::utils; use mdbook_core::utils;
use crate::config::{Config, RustEdition}; use crate::config::{Config, RustEdition};

View file

@ -10,7 +10,7 @@ use clap::builder::NonEmptyStringValueParser;
use futures_util::StreamExt; use futures_util::StreamExt;
use futures_util::sink::SinkExt; use futures_util::sink::SinkExt;
use mdbook::MDBook; use mdbook::MDBook;
use mdbook::utils::fs::get_404_output_file; use mdbook_core::utils::fs::get_404_output_file;
use std::net::{SocketAddr, ToSocketAddrs}; use std::net::{SocketAddr, ToSocketAddrs};
use std::path::PathBuf; use std::path::PathBuf;
use tokio::sync::broadcast; use tokio::sync::broadcast;

View file

@ -50,6 +50,8 @@
use crate::utils::{self, toml_ext::TomlExt}; use crate::utils::{self, toml_ext::TomlExt};
use anyhow::{Context, Error, Result, bail}; use anyhow::{Context, Error, Result, bail};
use log::{debug, trace, warn}; use log::{debug, trace, warn};
use mdbook_core::utils::log_backtrace;
use mdbook_core::utils::toml_ext::TomlExt;
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
@ -182,7 +184,7 @@ impl Config {
Ok(Some(config)) => Some(config), Ok(Some(config)) => Some(config),
Ok(None) => None, Ok(None) => None,
Err(e) => { Err(e) => {
utils::log_backtrace(&e); log_backtrace(&e);
None None
} }
} }
@ -812,7 +814,7 @@ impl<'de, T> Updateable<'de> for T where T: Serialize + Deserialize<'de> {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::utils::fs::get_404_output_file; use mdbook_core::utils::fs::get_404_output_file;
use serde_json::json; use serde_json::json;
const COMPLEX_CONFIG: &str = r#" const COMPLEX_CONFIG: &str = r#"

View file

@ -86,7 +86,6 @@ pub mod preprocess;
pub mod renderer; pub mod renderer;
#[path = "front-end/mod.rs"] #[path = "front-end/mod.rs"]
pub mod theme; pub mod theme;
pub mod utils;
pub use crate::book::BookItem; pub use crate::book::BookItem;
pub use crate::book::MDBook; pub use crate::book::MDBook;

View file

@ -11,7 +11,7 @@ use clap::{Arg, ArgMatches, Command};
use clap_complete::Shell; use clap_complete::Shell;
use env_logger::Builder; use env_logger::Builder;
use log::LevelFilter; use log::LevelFilter;
use mdbook::utils; use mdbook_core::utils;
use std::env; use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::io::Write; use std::io::Write;

View file

@ -1,8 +1,8 @@
use crate::utils::{ use anyhow::{Context, Result};
use mdbook_core::utils::{
take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines, take_anchored_lines, take_lines, take_rustdoc_include_anchored_lines,
take_rustdoc_include_lines, take_rustdoc_include_lines,
}; };
use anyhow::{Context, Result};
use regex::{CaptureMatches, Captures, Regex}; use regex::{CaptureMatches, Captures, Regex};
use std::fs; use std::fs;
use std::ops::{Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeTo}; use std::ops::{Bound, Range, RangeBounds, RangeFrom, RangeFull, RangeTo};

View file

@ -4,8 +4,8 @@ use crate::renderer::html_handlebars::StaticFiles;
use crate::renderer::html_handlebars::helpers; use crate::renderer::html_handlebars::helpers;
use crate::renderer::{RenderContext, Renderer}; use crate::renderer::{RenderContext, Renderer};
use crate::theme::{self, Theme}; use crate::theme::{self, Theme};
use crate::utils; use mdbook_core::utils;
use crate::utils::fs::get_404_output_file; use mdbook_core::utils::fs::get_404_output_file;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::BTreeMap; use std::collections::BTreeMap;

View file

@ -5,8 +5,8 @@ use handlebars::{
Context, Handlebars, Helper, Output, RenderContext, RenderError, RenderErrorReason, Renderable, Context, Handlebars, Helper, Output, RenderContext, RenderError, RenderErrorReason, Renderable,
}; };
use crate::utils;
use log::{debug, trace}; use log::{debug, trace};
use mdbook_core::utils;
use serde_json::json; use serde_json::json;
type StringMap = BTreeMap<String, String>; type StringMap = BTreeMap<String, String>;

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::utils; use mdbook_core::utils;
use handlebars::{ use handlebars::{
Context, Handlebars, Helper, HelperDef, Output, RenderContext, RenderError, RenderErrorReason, Context, Handlebars, Helper, HelperDef, Output, RenderContext, RenderError, RenderErrorReason,

View file

@ -1,7 +1,7 @@
use std::path::Path; use std::path::Path;
use std::{cmp::Ordering, collections::BTreeMap}; use std::{cmp::Ordering, collections::BTreeMap};
use crate::utils::special_escape; use mdbook_core::utils::special_escape;
use handlebars::{ use handlebars::{
Context, Handlebars, Helper, HelperDef, Output, RenderContext, RenderError, RenderErrorReason, Context, Handlebars, Helper, HelperDef, Output, RenderContext, RenderError, RenderErrorReason,

View file

@ -6,6 +6,7 @@ use std::sync::LazyLock;
use anyhow::{Context, Result, bail}; use anyhow::{Context, Result, bail};
use elasticlunr::{Index, IndexBuilder}; use elasticlunr::{Index, IndexBuilder};
use log::{debug, warn}; use log::{debug, warn};
use mdbook_core::utils;
use pulldown_cmark::*; use pulldown_cmark::*;
use serde::Serialize; use serde::Serialize;
@ -13,7 +14,6 @@ use crate::book::{Book, BookItem, Chapter};
use crate::config::{Search, SearchChapterSettings}; use crate::config::{Search, SearchChapterSettings};
use crate::renderer::html_handlebars::StaticFiles; use crate::renderer::html_handlebars::StaticFiles;
use crate::theme::searcher; use crate::theme::searcher;
use crate::utils;
const MAX_WORD_LENGTH_TO_INDEX: usize = 80; const MAX_WORD_LENGTH_TO_INDEX: usize = 80;

View file

@ -2,11 +2,11 @@
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use log::{debug, warn}; use log::{debug, warn};
use mdbook_core::utils;
use crate::config::HtmlConfig; use crate::config::HtmlConfig;
use crate::renderer::html_handlebars::helpers::resources::ResourceHelper; use crate::renderer::html_handlebars::helpers::resources::ResourceHelper;
use crate::theme::{self, Theme, playground_editor}; use crate::theme::{self, Theme, playground_editor};
use crate::utils;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
@ -227,7 +227,7 @@ impl StaticFiles {
} }
pub fn write_files(self, destination: &Path) -> Result<ResourceHelper> { pub fn write_files(self, destination: &Path) -> Result<ResourceHelper> {
use crate::utils::fs::write_file; use mdbook_core::utils::fs::write_file;
use regex::bytes::{Captures, Regex}; use regex::bytes::{Captures, Regex};
// The `{{ resource "name" }}` directive in static resources look like // The `{{ resource "name" }}` directive in static resources look like
// handlebars syntax, even if they technically aren't. // handlebars syntax, even if they technically aren't.
@ -302,7 +302,7 @@ mod tests {
use super::*; use super::*;
use crate::config::HtmlConfig; use crate::config::HtmlConfig;
use crate::theme::Theme; use crate::theme::Theme;
use crate::utils::fs::write_file; use mdbook_core::utils::fs::write_file;
use tempfile::TempDir; use tempfile::TempDir;
#[test] #[test]

View file

@ -1,8 +1,8 @@
use crate::book::BookItem; use crate::book::BookItem;
use crate::renderer::{RenderContext, Renderer}; use crate::renderer::{RenderContext, Renderer};
use crate::utils;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use log::trace; use log::trace;
use mdbook_core::utils;
use std::fs; use std::fs;
#[derive(Default)] #[derive(Default)]

View file

@ -35,7 +35,7 @@ impl BookTest {
let dir = Path::new("tests/testsuite").join(dir); let dir = Path::new("tests/testsuite").join(dir);
assert!(dir.exists(), "{dir:?} should exist"); assert!(dir.exists(), "{dir:?} should exist");
let tmp = Self::new_tmp(); let tmp = Self::new_tmp();
mdbook::utils::fs::copy_files_except_ext( mdbook_core::utils::fs::copy_files_except_ext(
&dir, &dir,
&tmp, &tmp,
true, true,

View file

@ -24,8 +24,8 @@ fn basic_build() {
fn failure_on_missing_file() { fn failure_on_missing_file() {
BookTest::from_dir("build/missing_file").run("build", |cmd| { BookTest::from_dir("build/missing_file").run("build", |cmd| {
cmd.expect_failure().expect_stderr(str![[r#" cmd.expect_failure().expect_stderr(str![[r#"
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Chapter file not found, ./chapter_1.md [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Chapter file not found, ./chapter_1.md
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: [NOT_FOUND] [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND]
"#]]); "#]]);
}); });
@ -48,8 +48,8 @@ fn no_reserved_filename() {
cmd.expect_failure().expect_stderr(str![[r#" cmd.expect_failure().expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: print.md is reserved for internal use [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: print.md is reserved for internal use
"#]]); "#]]);
}); });

View file

@ -22,10 +22,10 @@ fn footnotes() {
cmd.expect_stderr(str![[r#" cmd.expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [WARN] (mdbook::utils): footnote `multiple-definitions` in <unknown> defined multiple times - not updating to new definition [TIMESTAMP] [WARN] (mdbook_core::utils): footnote `multiple-definitions` in <unknown> defined multiple times - not updating to new definition
[TIMESTAMP] [WARN] (mdbook::utils): footnote `unused` in `<unknown>` is defined but not referenced [TIMESTAMP] [WARN] (mdbook_core::utils): footnote `unused` in `<unknown>` is defined but not referenced
[TIMESTAMP] [WARN] (mdbook::utils): footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition [TIMESTAMP] [WARN] (mdbook_core::utils): footnote `multiple-definitions` in footnotes.md defined multiple times - not updating to new definition
[TIMESTAMP] [WARN] (mdbook::utils): footnote `unused` in `footnotes.md` is defined but not referenced [TIMESTAMP] [WARN] (mdbook_core::utils): footnote `unused` in `footnotes.md` is defined but not referenced
[TIMESTAMP] [INFO] (mdbook::renderer::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book` [TIMESTAMP] [INFO] (mdbook::renderer::html_handlebars::hbs_renderer): HTML book written to `[ROOT]/book`
"#]]); "#]]);

View file

@ -64,7 +64,7 @@ fn failing_preprocessor() {
.expect_stderr(str![[r#" .expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
Boom!!1! Boom!!1!
[TIMESTAMP] [ERROR] (mdbook::utils): Error: The "nop-preprocessor" preprocessor exited unsuccessfully with [EXIT_STATUS]: 1 status [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: The "nop-preprocessor" preprocessor exited unsuccessfully with [EXIT_STATUS]: 1 status
"#]]); "#]]);
}); });

View file

@ -24,9 +24,9 @@ fn redirect_removed_with_fragments_only() {
cmd.expect_failure().expect_stderr(str![[r#" cmd.expect_failure().expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: Unable to emit redirects [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to emit redirects
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: redirect entry for `old-file.html` only has source paths with `#` fragments [TIMESTAMP] [ERROR] (mdbook_core::utils): [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. There must be an entry without the `#` fragment to determine the default destination.
"#]]); "#]]);
@ -40,8 +40,8 @@ fn redirect_existing_page() {
cmd.expect_failure().expect_stderr(str![[r#" cmd.expect_failure().expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: redirect found for existing chapter at `/chapter_1.html` [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: redirect found for existing chapter at `/chapter_1.html`
Either delete the redirect or remove the chapter. Either delete the redirect or remove the chapter.
"#]]); "#]]);

View file

@ -68,8 +68,8 @@ fn failing_command() {
[TIMESTAMP] [INFO] (mdbook::book): Running the failing backend [TIMESTAMP] [INFO] (mdbook::book): Running the failing backend
[TIMESTAMP] [INFO] (mdbook::renderer): Invoking the "failing" renderer [TIMESTAMP] [INFO] (mdbook::renderer): Invoking the "failing" renderer
[TIMESTAMP] [ERROR] (mdbook::renderer): Renderer exited with non-zero return code. [TIMESTAMP] [ERROR] (mdbook::renderer): Renderer exited with non-zero return code.
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: The "failing" renderer failed [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: The "failing" renderer failed
"#]]); "#]]);
}); });
@ -86,9 +86,9 @@ fn missing_renderer() {
[TIMESTAMP] [INFO] (mdbook::book): Running the missing backend [TIMESTAMP] [INFO] (mdbook::book): Running the missing backend
[TIMESTAMP] [INFO] (mdbook::renderer): Invoking the "missing" renderer [TIMESTAMP] [INFO] (mdbook::renderer): Invoking the "missing" renderer
[TIMESTAMP] [ERROR] (mdbook::renderer): 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::renderer): 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::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: Unable to start the backend [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to start the backend
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: [NOT_FOUND] [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND]
"#]]); "#]]);
}); });

View file

@ -137,8 +137,8 @@ fn chapter_settings_validation_error() {
cmd.expect_failure().expect_stderr(str![[r#" cmd.expect_failure().expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: [output.html.search.chapter] key `does-not-exist` does not match any chapter paths [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [output.html.search.chapter] key `does-not-exist` does not match any chapter paths
"#]]); "#]]);
}); });

View file

@ -48,7 +48,7 @@ test failing_include.md - Failing_Include (line 3) ... FAILED
thread 'main' panicked at failing_include.md:3:1: thread 'main' panicked at failing_include.md:3:1:
failing! failing!
... ...
[TIMESTAMP] [ERROR] (mdbook::utils): Error: One or more tests failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: One or more tests failed
"#]]); "#]]);
}); });
@ -82,7 +82,7 @@ fn chapter_not_found() {
cmd.expect_failure() cmd.expect_failure()
.expect_stdout(str![[""]]) .expect_stdout(str![[""]])
.expect_stderr(str![[r#" .expect_stderr(str![[r#"
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Chapter not found: bogus [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Chapter not found: bogus
"#]]); "#]]);
}); });

View file

@ -11,8 +11,8 @@ cmd.expect_failure()
.expect_stderr(str![[r#" .expect_stderr(str![[r#"
[TIMESTAMP] [INFO] (mdbook::book): Book building has started [TIMESTAMP] [INFO] (mdbook::book): Book building has started
[TIMESTAMP] [INFO] (mdbook::book): Running the html backend [TIMESTAMP] [INFO] (mdbook::book): Running the html backend
[TIMESTAMP] [ERROR] (mdbook::utils): Error: Rendering failed [TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
[TIMESTAMP] [ERROR] (mdbook::utils): [TAB]Caused By: theme dir [ROOT]/./non-existent-directory does not exist [TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: theme dir [ROOT]/./non-existent-directory does not exist
"#]]); "#]]);
}); });