diff --git a/README.md b/README.md index 1b83f3a..e1733d3 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,21 @@ and `src/main.rs` (or `src/lib.rs`). Place all required dependencies in the `Car Then, point `manifest_dir` to that directory, as shown above. +## Working with `cargo` workspaces and build features + +If you are working with a `cargo` workspace, you'll need to have the `--workspace` argument +passed to the invocation of `cargo build`. Likewise, if you need to build your crate with +specific features enabled, you'll need to pass them via `--features first,second` - as a +comma separated list. In the `mdbook-keeper` config, you can do so via: + +```toml +is_workspace = true +build_features = ["first", "second"] +``` + +Both of these are optional: if they are not present in the config, the manifest dir is not +considered a workspace and no features get enabled. + ## Other Configuration Options All of these options can be placed in the `book.toml` file, after `[preprocessor.keeper]`. diff --git a/src/lib.rs b/src/lib.rs index b0a0357..c5e2118 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,23 @@ mod skeptic; #[cfg(test)] mod tests; -use std::fs::File; -use std::io::prelude::*; +use std::{fs::File, io::prelude::*}; use atty::Stream; use colored::{control::set_override, Colorize}; use glob::glob; -use mdbook::book::{Book, BookItem}; -use mdbook::errors::Error; -use mdbook::preprocess::{Preprocessor, PreprocessorContext}; +use mdbook::{ + book::{Book, BookItem}, + errors::Error, + preprocess::{Preprocessor, PreprocessorContext}, +}; use serde::{Deserialize, Serialize}; use slug::slugify; -use std::collections::HashMap; -use std::path::{Path, PathBuf}; -use std::process::Command; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + process::Command, +}; use toml::value::Table; use run_tests::{handle_test, CompileType, TestResult}; @@ -79,6 +82,20 @@ struct KeeperConfigParser { #[serde(default)] manifest_dir: Option, + /// This allows you to specify if the manifest dir is + /// of a cargo workspace. If set to true, `--workspace` + /// will be passed to the invocation of `cargo build`. + #[serde(default)] + is_workspace: Option, + + /// This allows you to specify the features you want to + /// invoke `cargo build` with. If you set this to + /// `["first", "second"], it causes `--features + /// first,second` to be added to the invocation of + /// `cargo build`. + #[serde(default)] + build_features: Vec, + /// Whether to show terminal colours. #[serde(default)] terminal_colors: Option, @@ -89,6 +106,8 @@ struct KeeperConfig { test_dir: PathBuf, target_dir: PathBuf, manifest_dir: Option, + is_workspace: bool, + build_features: Vec, terminal_colors: bool, externs: Vec, } @@ -123,6 +142,7 @@ impl KeeperConfig { }); let manifest_dir = keeper_config.manifest_dir.map(PathBuf::from); + let is_workspace = keeper_config.is_workspace.unwrap_or(false); let terminal_colors = keeper_config .terminal_colors @@ -134,6 +154,8 @@ impl KeeperConfig { test_dir, target_dir, manifest_dir, + is_workspace, + build_features: keeper_config.build_features, terminal_colors, externs: keeper_config.externs, } @@ -146,6 +168,7 @@ impl KeeperConfig { if let Some(manifest_dir) = &self.manifest_dir { let cargo = std::env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); + let mut command = Command::new(cargo); command .arg("build") @@ -153,6 +176,14 @@ impl KeeperConfig { .env("CARGO_TARGET_DIR", &self.target_dir) .env("CARGO_MANIFEST_DIR", manifest_dir); + if self.is_workspace { + command.arg("--workspace"); + } + + if !self.build_features.is_empty() { + command.args(["--features", &self.build_features.join(",")]); + } + let mut join_handle = command.spawn().expect("failed to execute process"); let build_was_ok = join_handle.wait().expect("Could not join on thread");