Skip to content

Commit 235c1f8

Browse files
committed
Factor out handle_render_command_error
This moves `handle_render_command_error` out to the crate root so that it can later be shared with `CmdPreprocessor`.
1 parent 5d44ef9 commit 235c1f8

File tree

3 files changed

+44
-41
lines changed

3 files changed

+44
-41
lines changed

crates/mdbook-driver/src/builtin_renderers/mod.rs

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use anyhow::{Context, Result, bail};
66
use log::{error, info, trace, warn};
77
use mdbook_renderer::{RenderContext, Renderer};
88
use std::fs;
9-
use std::io::{self, ErrorKind};
109
use std::process::Stdio;
1110

1211
pub use self::markdown_renderer::MarkdownRenderer;
@@ -49,41 +48,6 @@ impl CmdRenderer {
4948
}
5049
}
5150

52-
impl CmdRenderer {
53-
fn handle_render_command_error(&self, ctx: &RenderContext, error: io::Error) -> Result<()> {
54-
if let ErrorKind::NotFound = error.kind() {
55-
// Look for "output.{self.name}.optional".
56-
// If it exists and is true, treat this as a warning.
57-
// Otherwise, fail the build.
58-
59-
let optional_key = format!("output.{}.optional", self.name);
60-
61-
let is_optional = match ctx.config.get(&optional_key) {
62-
Ok(Some(value)) => value,
63-
Err(e) => bail!("expected bool for `{optional_key}`: {e}"),
64-
Ok(None) => false,
65-
};
66-
67-
if is_optional {
68-
warn!(
69-
"The command `{}` for backend `{}` was not found, \
70-
but was marked as optional.",
71-
self.cmd, self.name
72-
);
73-
return Ok(());
74-
} else {
75-
error!(
76-
"The command `{0}` wasn't found, is the \"{1}\" backend installed? \
77-
If you want to ignore this error when the \"{1}\" backend is not installed, \
78-
set `optional = true` in the `[output.{1}]` section of the book.toml configuration file.",
79-
self.cmd, self.name
80-
);
81-
}
82-
}
83-
Err(error).with_context(|| "Unable to start the backend")?
84-
}
85-
}
86-
8751
impl Renderer for CmdRenderer {
8852
fn name(&self) -> &str {
8953
&self.name
@@ -92,6 +56,13 @@ impl Renderer for CmdRenderer {
9256
fn render(&self, ctx: &RenderContext) -> Result<()> {
9357
info!("Invoking the \"{}\" renderer", self.name);
9458

59+
let optional_key = format!("output.{}.optional", self.name);
60+
let optional = match ctx.config.get(&optional_key) {
61+
Ok(Some(value)) => value,
62+
Err(e) => bail!("expected bool for `{optional_key}`: {e}"),
63+
Ok(None) => false,
64+
};
65+
9566
let _ = fs::create_dir_all(&ctx.destination);
9667

9768
let mut cmd = crate::compose_command(&self.cmd, &ctx.root)?;
@@ -103,7 +74,11 @@ impl Renderer for CmdRenderer {
10374
.spawn()
10475
{
10576
Ok(c) => c,
106-
Err(e) => return self.handle_render_command_error(ctx, e),
77+
Err(e) => {
78+
return crate::handle_command_error(
79+
e, optional, "output", "backend", &self.name, &self.cmd,
80+
);
81+
}
10782
};
10883

10984
let mut stdin = child.stdin.take().expect("Child has stdin");

crates/mdbook-driver/src/lib.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ pub mod init;
6464
mod load;
6565
mod mdbook;
6666

67-
use anyhow::{Result, bail};
67+
use anyhow::{Context, Result, bail};
68+
use log::{error, warn};
6869
pub use mdbook::MDBook;
6970
pub use mdbook_core::{book, config, errors};
7071
use shlex::Shlex;
@@ -95,3 +96,30 @@ fn compose_command(cmd: &str, root: &Path) -> Result<Command> {
9596

9697
Ok(cmd)
9798
}
99+
100+
/// Handles a failure for a preprocessor or renderer.
101+
fn handle_command_error(
102+
error: std::io::Error,
103+
optional: bool,
104+
key: &str,
105+
what: &str,
106+
name: &str,
107+
cmd: &str,
108+
) -> Result<()> {
109+
if let std::io::ErrorKind::NotFound = error.kind() {
110+
if optional {
111+
warn!(
112+
"The command `{cmd}` for {what} `{name}` was not found, \
113+
but is marked as optional.",
114+
);
115+
return Ok(());
116+
} else {
117+
error!(
118+
"The command `{cmd}` wasn't found, is the `{name}` {what} installed? \
119+
If you want to ignore this error when the `{name}` {what} is not installed, \
120+
set `optional = true` in the `[{key}.{name}]` section of the book.toml configuration file.",
121+
);
122+
}
123+
}
124+
Err(error).with_context(|| format!("Unable to run the {what} `{name}`"))?
125+
}

tests/testsuite/renderer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ fn missing_renderer() {
8585
[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started
8686
[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the missing backend
8787
[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "missing" renderer
88-
[TIMESTAMP] [ERROR] (mdbook_driver::builtin_renderers): 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.
88+
[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.
8989
[TIMESTAMP] [ERROR] (mdbook_core::utils): Error: Rendering failed
90-
[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to start the backend
90+
[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: Unable to run the backend `missing`
9191
[TIMESTAMP] [ERROR] (mdbook_core::utils): [TAB]Caused By: [NOT_FOUND]
9292
9393
"#]]);
@@ -102,7 +102,7 @@ fn missing_optional_not_fatal() {
102102
[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Book building has started
103103
[TIMESTAMP] [INFO] (mdbook_driver::mdbook): Running the missing backend
104104
[TIMESTAMP] [INFO] (mdbook_driver::builtin_renderers): Invoking the "missing" renderer
105-
[TIMESTAMP] [WARN] (mdbook_driver::builtin_renderers): The command `trduyvbhijnorgevfuhn` for backend `missing` was not found, but was marked as optional.
105+
[TIMESTAMP] [WARN] (mdbook_driver): The command `trduyvbhijnorgevfuhn` for backend `missing` was not found, but is marked as optional.
106106
107107
"#]]);
108108
});

0 commit comments

Comments
 (0)