Remove legacy config support
This removes the old legacy config that allowed certain things at the top level. The legacy switch was added in https://github.com/rust-lang/mdBook/pull/457 Closes https://github.com/rust-lang/mdBook/issues/2653
This commit is contained in:
parent
8befcc74d1
commit
eda77b81db
2 changed files with 0 additions and 146 deletions
|
|
@ -226,39 +226,6 @@ impl Config {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_legacy(mut table: Value) -> Config {
|
|
||||||
let mut cfg = Config::default();
|
|
||||||
|
|
||||||
// we use a macro here instead of a normal loop because the $out
|
|
||||||
// variable can be different types. This way we can make type inference
|
|
||||||
// figure out what try_into() deserializes to.
|
|
||||||
macro_rules! get_and_insert {
|
|
||||||
($table:expr, $key:expr => $out:expr) => {
|
|
||||||
let got = $table
|
|
||||||
.as_table_mut()
|
|
||||||
.and_then(|t| t.remove($key))
|
|
||||||
.and_then(|v| v.try_into().ok());
|
|
||||||
if let Some(value) = got {
|
|
||||||
$out = value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get_and_insert!(table, "title" => cfg.book.title);
|
|
||||||
get_and_insert!(table, "authors" => cfg.book.authors);
|
|
||||||
get_and_insert!(table, "source" => cfg.book.src);
|
|
||||||
get_and_insert!(table, "description" => cfg.book.description);
|
|
||||||
|
|
||||||
if let Some(dest) = table.delete("output.html.destination") {
|
|
||||||
if let Ok(destination) = dest.try_into() {
|
|
||||||
cfg.build.build_dir = destination;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.rest = table;
|
|
||||||
cfg
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
|
@ -276,18 +243,6 @@ impl<'de> serde::Deserialize<'de> for Config {
|
||||||
fn deserialize<D: Deserializer<'de>>(de: D) -> std::result::Result<Self, D::Error> {
|
fn deserialize<D: Deserializer<'de>>(de: D) -> std::result::Result<Self, D::Error> {
|
||||||
let raw = Value::deserialize(de)?;
|
let raw = Value::deserialize(de)?;
|
||||||
|
|
||||||
if is_legacy_format(&raw) {
|
|
||||||
warn!("It looks like you are using the legacy book.toml format.");
|
|
||||||
warn!("We'll parse it for now, but you should probably convert to the new format.");
|
|
||||||
warn!("See the mdbook documentation for more details, although as a rule of thumb");
|
|
||||||
warn!("just move all top level configuration entries like `title`, `author` and");
|
|
||||||
warn!("`description` under a table called `[book]`, move the `destination` entry");
|
|
||||||
warn!("from `[output.html]`, renamed to `build-dir`, under a table called");
|
|
||||||
warn!("`[build]`, and it should all work.");
|
|
||||||
warn!("Documentation: https://rust-lang.github.io/mdBook/format/config.html");
|
|
||||||
return Ok(Config::from_legacy(raw));
|
|
||||||
}
|
|
||||||
|
|
||||||
warn_on_invalid_fields(&raw);
|
warn_on_invalid_fields(&raw);
|
||||||
|
|
||||||
use serde::de::Error;
|
use serde::de::Error;
|
||||||
|
|
@ -365,24 +320,6 @@ fn warn_on_invalid_fields(table: &Value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_legacy_format(table: &Value) -> bool {
|
|
||||||
let legacy_items = [
|
|
||||||
"title",
|
|
||||||
"authors",
|
|
||||||
"source",
|
|
||||||
"description",
|
|
||||||
"output.html.destination",
|
|
||||||
];
|
|
||||||
|
|
||||||
for item in &legacy_items {
|
|
||||||
if table.read(item).is_some() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configuration options which are specific to the book and required for
|
/// Configuration options which are specific to the book and required for
|
||||||
/// loading it from disk.
|
/// loading it from disk.
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
|
@ -1006,57 +943,6 @@ mod tests {
|
||||||
assert_eq!(got_baz, baz_should_be);
|
assert_eq!(got_baz, baz_should_be);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The config file format has slightly changed (metadata stuff is now under
|
|
||||||
/// the `book` table instead of being at the top level) so we're adding a
|
|
||||||
/// **temporary** compatibility check. You should be able to still load the
|
|
||||||
/// old format, emitting a warning.
|
|
||||||
#[test]
|
|
||||||
fn can_still_load_the_previous_format() {
|
|
||||||
let src = r#"
|
|
||||||
title = "mdBook Documentation"
|
|
||||||
description = "Create book from markdown files. Like Gitbook but implemented in Rust"
|
|
||||||
authors = ["Mathieu David"]
|
|
||||||
source = "./source"
|
|
||||||
|
|
||||||
[output.html]
|
|
||||||
destination = "my-book" # the output files will be generated in `root/my-book` instead of `root/book`
|
|
||||||
theme = "my-theme"
|
|
||||||
smart-punctuation = true
|
|
||||||
additional-css = ["custom.css", "custom2.css"]
|
|
||||||
additional-js = ["custom.js"]
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let book_should_be = BookConfig {
|
|
||||||
title: Some(String::from("mdBook Documentation")),
|
|
||||||
description: Some(String::from(
|
|
||||||
"Create book from markdown files. Like Gitbook but implemented in Rust",
|
|
||||||
)),
|
|
||||||
authors: vec![String::from("Mathieu David")],
|
|
||||||
src: PathBuf::from("./source"),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let build_should_be = BuildConfig {
|
|
||||||
build_dir: PathBuf::from("my-book"),
|
|
||||||
create_missing: true,
|
|
||||||
use_default_preprocessors: true,
|
|
||||||
extra_watch_dirs: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let html_should_be = HtmlConfig {
|
|
||||||
theme: Some(PathBuf::from("my-theme")),
|
|
||||||
smart_punctuation: true,
|
|
||||||
additional_css: vec![PathBuf::from("custom.css"), PathBuf::from("custom2.css")],
|
|
||||||
additional_js: vec![PathBuf::from("custom.js")],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let got = Config::from_str(src).unwrap();
|
|
||||||
assert_eq!(got.book, book_should_be);
|
|
||||||
assert_eq!(got.build, build_should_be);
|
|
||||||
assert_eq!(got.html_config().unwrap(), html_should_be);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_a_config_item() {
|
fn set_a_config_item() {
|
||||||
let mut cfg = Config::default();
|
let mut cfg = Config::default();
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ pub(crate) trait TomlExt {
|
||||||
fn read(&self, key: &str) -> Option<&Value>;
|
fn read(&self, key: &str) -> Option<&Value>;
|
||||||
/// Insert with a dotted key.
|
/// 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>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TomlExt for Value {
|
impl TomlExt for Value {
|
||||||
|
|
@ -37,16 +35,6 @@ impl TomlExt for Value {
|
||||||
table.insert(key.to_string(), value);
|
table.insert(key.to_string(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(&mut self, key: &str) -> Option<Value> {
|
|
||||||
if let Some((head, tail)) = split(key) {
|
|
||||||
self.get_mut(head)?.delete(tail)
|
|
||||||
} else if let Some(table) = self.as_table_mut() {
|
|
||||||
table.remove(key)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split(key: &str) -> Option<(&str, &str)> {
|
fn split(key: &str) -> Option<(&str, &str)> {
|
||||||
|
|
@ -103,24 +91,4 @@ mod tests {
|
||||||
let inserted = value.read("first.second").unwrap();
|
let inserted = value.read("first.second").unwrap();
|
||||||
assert_eq!(inserted, &item);
|
assert_eq!(inserted, &item);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn delete_a_top_level_item() {
|
|
||||||
let src = "top = true";
|
|
||||||
let mut value: Value = toml::from_str(src).unwrap();
|
|
||||||
|
|
||||||
let got = value.delete("top").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(got, Value::Boolean(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn delete_a_nested_item() {
|
|
||||||
let src = "[table]\n nested = true";
|
|
||||||
let mut value: Value = toml::from_str(src).unwrap();
|
|
||||||
|
|
||||||
let got = value.delete("table.nested").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(got, Value::Boolean(true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue