diff --git a/crates/mdbook-core/src/config.rs b/crates/mdbook-core/src/config.rs index c53d03a3e1..771204822b 100644 --- a/crates/mdbook-core/src/config.rs +++ b/crates/mdbook-core/src/config.rs @@ -366,7 +366,7 @@ impl TextDirection { #[serde(default, rename_all = "kebab-case", deny_unknown_fields)] #[non_exhaustive] pub struct BuildConfig { - /// Where to put built artefacts relative to the book's root directory. + /// Where to put built artifacts relative to the book's root directory. pub build_dir: PathBuf, /// Should non-existent markdown files specified in `SUMMARY.md` be created /// if they don't exist? diff --git a/guide/src/cli/build.md b/guide/src/cli/build.md index 36e053fd7c..a342741798 100644 --- a/guide/src/cli/build.md +++ b/guide/src/cli/build.md @@ -30,7 +30,7 @@ your default web browser after building it. #### `--dest-dir` The `--dest-dir` (`-d`) option allows you to change the output directory for the -book. Relative paths are interpreted relative to the book's root directory. If +book. Relative paths are interpreted relative to the current directory. If not specified it will default to the value of the `build.build-dir` key in `book.toml`, or to `./book`. diff --git a/guide/src/cli/clean.md b/guide/src/cli/clean.md index f09328054a..a2f94b62b4 100644 --- a/guide/src/cli/clean.md +++ b/guide/src/cli/clean.md @@ -20,7 +20,7 @@ mdbook clean path/to/book The `--dest-dir` (`-d`) option allows you to override the book's output directory, which will be deleted by this command. Relative paths are interpreted -relative to the book's root directory. If not specified it will default to the +relative to the current directory. If not specified it will default to the value of the `build.build-dir` key in `book.toml`, or to `./book`. ```bash diff --git a/guide/src/cli/serve.md b/guide/src/cli/serve.md index 4603df8e76..43aa42ecfa 100644 --- a/guide/src/cli/serve.md +++ b/guide/src/cli/serve.md @@ -40,7 +40,7 @@ default web browser after starting the server. #### `--dest-dir` The `--dest-dir` (`-d`) option allows you to change the output directory for the -book. Relative paths are interpreted relative to the book's root directory. If +book. Relative paths are interpreted relative to the current directory. If not specified it will default to the value of the `build.build-dir` key in `book.toml`, or to `./book`. diff --git a/guide/src/cli/watch.md b/guide/src/cli/watch.md index be2f5be450..364dd9e571 100644 --- a/guide/src/cli/watch.md +++ b/guide/src/cli/watch.md @@ -23,7 +23,7 @@ your default web browser. #### `--dest-dir` The `--dest-dir` (`-d`) option allows you to change the output directory for the -book. Relative paths are interpreted relative to the book's root directory. If +book. Relative paths are interpreted relative to the current directory. If not specified it will default to the value of the `build.build-dir` key in `book.toml`, or to `./book`. diff --git a/src/cmd/build.rs b/src/cmd/build.rs index a04adc5f07..b4ac48574b 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -2,7 +2,6 @@ use super::command_prelude::*; use crate::{get_book_dir, open}; use anyhow::Result; use mdbook_driver::MDBook; -use std::path::PathBuf; // Create clap subcommand arguments pub fn make_subcommand() -> Command { @@ -18,9 +17,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let book_dir = get_book_dir(args); let mut book = MDBook::load(book_dir)?; - if let Some(dest_dir) = args.get_one::("dest-dir") { - book.config.build.build_dir = dest_dir.into(); - } + set_dest_dir(args, &mut book); book.build()?; diff --git a/src/cmd/clean.rs b/src/cmd/clean.rs index a07bb2ae6e..1bea7da043 100644 --- a/src/cmd/clean.rs +++ b/src/cmd/clean.rs @@ -21,7 +21,9 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let book = MDBook::load(book_dir)?; let dir_to_remove = match args.get_one::("dest-dir") { - Some(dest_dir) => dest_dir.into(), + Some(dest_dir) => std::env::current_dir() + .expect("current dir should be valid") + .join(dest_dir), None => book.root.join(&book.config.build.build_dir), }; diff --git a/src/cmd/command_prelude.rs b/src/cmd/command_prelude.rs index d5df3af9f2..b2a91ae972 100644 --- a/src/cmd/command_prelude.rs +++ b/src/cmd/command_prelude.rs @@ -1,6 +1,7 @@ //! Helpers for building the command-line arguments for commands. pub use clap::{Arg, ArgMatches, Command, arg}; +use mdbook_driver::MDBook; use std::path::PathBuf; pub trait CommandExt: Sized { @@ -15,7 +16,7 @@ pub trait CommandExt: Sized { .value_parser(clap::value_parser!(PathBuf)) .help( "Output directory for the book\n\ - Relative paths are interpreted relative to the book's root directory.\n\ + Relative paths are interpreted relative to the current directory.\n\ If omitted, mdBook uses build.build-dir from book.toml \ or defaults to `./book`.", ), @@ -57,3 +58,12 @@ impl CommandExt for Command { self.arg(arg) } } + +pub fn set_dest_dir(args: &ArgMatches, book: &mut MDBook) { + if let Some(dest_dir) = args.get_one::("dest-dir") { + let build_dir = std::env::current_dir() + .expect("current dir should be valid") + .join(dest_dir); + book.config.build.build_dir = build_dir; + } +} diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 5fc20f9ac0..6d8a06167d 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -62,9 +62,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { book.config .set("output.html.live-reload-endpoint", LIVE_RELOAD_ENDPOINT) .expect("live-reload-endpoint update failed"); - if let Some(dest_dir) = args.get_one::("dest-dir") { - book.config.build.build_dir = dest_dir.into(); - } + set_dest_dir(args, book); // Override site-url for local serving of the 404 file book.config.set("output.html.site-url", "/").unwrap(); }; diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index 4f63750567..bd9c19b233 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -38,9 +38,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> { let mut book = MDBook::load(&book_dir)?; let update_config = |book: &mut MDBook| { - if let Some(dest_dir) = args.get_one::("dest-dir") { - book.config.build.build_dir = dest_dir.into(); - } + set_dest_dir(args, book); }; update_config(&mut book); diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 6bbf061d22..7b6cfc4d3d 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -66,3 +66,22 @@ fn book_toml_isnt_required() { str![[r##"

Chapter 1

"##]], ); } + +// Dest dir relative path behavior. +#[test] +fn dest_dir_relative_path() { + let mut test = BookTest::from_dir("build/basic_build"); + let current_dir = test.dir.join("work"); + std::fs::create_dir_all(¤t_dir).unwrap(); + test.run("build", |cmd| { + 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` + +"#]]); + }); + assert!(current_dir.join("foo/index.html").exists()); +}