fmt/clippy
This commit is contained in:
parent
34708d6592
commit
a12e9512bc
|
@ -16,7 +16,7 @@ in the `docs/content` folder of the repository and the community can use [its fo
|
||||||
| Syntax highlighting | ✔ | ✔ | ✔ | ✔ |
|
| Syntax highlighting | ✔ | ✔ | ✔ | ✔ |
|
||||||
| Sass compilation | ✔ | ✔ | ✔ | ✔ |
|
| Sass compilation | ✔ | ✔ | ✔ | ✔ |
|
||||||
| Assets co-location | ✔ | ✔ | ✔ | ✔ |
|
| Assets co-location | ✔ | ✔ | ✔ | ✔ |
|
||||||
| i18n | ✕ | ✕ | ✔ | ✔ |
|
| Multilingual site | ✔ | ✕ | ✔ | ✔ |
|
||||||
| Image processing | ✔ | ✕ | ✔ | ✔ |
|
| Image processing | ✔ | ✕ | ✔ | ✔ |
|
||||||
| Sane & powerful template engine | ✔ | ~ | ~ | ✔ |
|
| Sane & powerful template engine | ✔ | ~ | ~ | ✔ |
|
||||||
| Themes | ✔ | ✕ | ✔ | ✔ |
|
| Themes | ✔ | ✕ | ✔ | ✔ |
|
||||||
|
|
|
@ -12,7 +12,7 @@ extern crate syntect;
|
||||||
mod config;
|
mod config;
|
||||||
pub mod highlighting;
|
pub mod highlighting;
|
||||||
mod theme;
|
mod theme;
|
||||||
pub use config::{Config, Taxonomy, Language};
|
pub use config::{Config, Language, Taxonomy};
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,7 @@ impl FileInfo {
|
||||||
|
|
||||||
// Go with the assumption that no one is using `.` in filenames when using i18n
|
// Go with the assumption that no one is using `.` in filenames when using i18n
|
||||||
// We can document that
|
// We can document that
|
||||||
let mut parts: Vec<String> = self.name.splitn(2,'.').map(|s| s.to_string()).collect();
|
let mut parts: Vec<String> = self.name.splitn(2, '.').map(|s| s.to_string()).collect();
|
||||||
|
|
||||||
// The language code is not present in the config: typo or the user forgot to add it to the
|
// The language code is not present in the config: typo or the user forgot to add it to the
|
||||||
// config
|
// config
|
||||||
|
@ -155,7 +155,7 @@ mod tests {
|
||||||
|
|
||||||
use config::{Config, Language};
|
use config::{Config, Language};
|
||||||
|
|
||||||
use super::{FileInfo, find_content_components};
|
use super::{find_content_components, FileInfo};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_content_components() {
|
fn can_find_content_components() {
|
||||||
|
@ -165,17 +165,19 @@ mod tests {
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_components_in_page_with_assets() {
|
fn can_find_components_in_page_with_assets() {
|
||||||
let file =
|
let file = FileInfo::new_page(&Path::new(
|
||||||
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"));
|
"/home/vincent/code/site/content/posts/tutorials/python/index.md",
|
||||||
|
));
|
||||||
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_valid_language_in_page() {
|
fn can_find_valid_language_in_page() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let mut file =
|
let mut file = FileInfo::new_page(&Path::new(
|
||||||
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
|
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
|
||||||
|
));
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert_eq!(res.unwrap(), Some(String::from("fr")));
|
assert_eq!(res.unwrap(), Some(String::from("fr")));
|
||||||
|
@ -184,9 +186,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_valid_language_in_page_with_assets() {
|
fn can_find_valid_language_in_page_with_assets() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let mut file =
|
let mut file = FileInfo::new_page(&Path::new(
|
||||||
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"));
|
"/home/vincent/code/site/content/posts/tutorials/python/index.fr.md",
|
||||||
|
));
|
||||||
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
@ -196,8 +199,9 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn do_nothing_on_unknown_language_in_page_with_i18n_off() {
|
fn do_nothing_on_unknown_language_in_page_with_i18n_off() {
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let mut file =
|
let mut file = FileInfo::new_page(&Path::new(
|
||||||
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
|
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
|
||||||
|
));
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert!(res.unwrap().is_none());
|
assert!(res.unwrap().is_none());
|
||||||
|
@ -206,9 +210,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn errors_on_unknown_language_in_page_with_i18n_on() {
|
fn errors_on_unknown_language_in_page_with_i18n_on() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("it"), rss: false});
|
config.languages.push(Language { code: String::from("it"), rss: false });
|
||||||
let mut file =
|
let mut file = FileInfo::new_page(&Path::new(
|
||||||
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
|
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
|
||||||
|
));
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
}
|
}
|
||||||
|
@ -216,9 +221,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_find_valid_language_in_section() {
|
fn can_find_valid_language_in_section() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let mut file =
|
let mut file = FileInfo::new_section(&Path::new(
|
||||||
FileInfo::new_section(&Path::new("/home/vincent/code/site/content/posts/tutorials/_index.fr.md"));
|
"/home/vincent/code/site/content/posts/tutorials/_index.fr.md",
|
||||||
|
));
|
||||||
let res = file.find_language(&config);
|
let res = file.find_language(&config);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert_eq!(res.unwrap(), Some(String::from("fr")));
|
assert_eq!(res.unwrap(), Some(String::from("fr")));
|
||||||
|
|
|
@ -74,6 +74,8 @@ pub struct Page {
|
||||||
/// The language of that page. `None` if the user doesn't setup `languages` in config.
|
/// The language of that page. `None` if the user doesn't setup `languages` in config.
|
||||||
/// Corresponds to the lang in the {slug}.{lang}.md file scheme
|
/// Corresponds to the lang in the {slug}.{lang}.md file scheme
|
||||||
pub lang: Option<String>,
|
pub lang: Option<String>,
|
||||||
|
/// Contains all the translated version of that page
|
||||||
|
pub translations: Vec<Key>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
|
@ -101,6 +103,7 @@ impl Page {
|
||||||
word_count: None,
|
word_count: None,
|
||||||
reading_time: None,
|
reading_time: None,
|
||||||
lang: None,
|
lang: None,
|
||||||
|
translations: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,6 +303,7 @@ impl Default for Page {
|
||||||
word_count: None,
|
word_count: None,
|
||||||
reading_time: None,
|
reading_time: None,
|
||||||
lang: None,
|
lang: None,
|
||||||
|
translations: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,7 +581,7 @@ Hello world
|
||||||
#[test]
|
#[test]
|
||||||
fn can_specify_language_in_filename() {
|
fn can_specify_language_in_filename() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let content = r#"
|
let content = r#"
|
||||||
+++
|
+++
|
||||||
+++
|
+++
|
||||||
|
@ -594,7 +598,7 @@ Bonjour le monde"#
|
||||||
#[test]
|
#[test]
|
||||||
fn can_specify_language_in_filename_with_date() {
|
fn can_specify_language_in_filename_with_date() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let content = r#"
|
let content = r#"
|
||||||
+++
|
+++
|
||||||
+++
|
+++
|
||||||
|
@ -612,7 +616,7 @@ Bonjour le monde"#
|
||||||
#[test]
|
#[test]
|
||||||
fn i18n_frontmatter_path_overrides_default_permalink() {
|
fn i18n_frontmatter_path_overrides_default_permalink() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let content = r#"
|
let content = r#"
|
||||||
+++
|
+++
|
||||||
path = "bonjour"
|
path = "bonjour"
|
||||||
|
|
|
@ -54,6 +54,8 @@ pub struct Section {
|
||||||
/// The language of that section. `None` if the user doesn't setup `languages` in config.
|
/// The language of that section. `None` if the user doesn't setup `languages` in config.
|
||||||
/// Corresponds to the lang in the _index.{lang}.md file scheme
|
/// Corresponds to the lang in the _index.{lang}.md file scheme
|
||||||
pub lang: Option<String>,
|
pub lang: Option<String>,
|
||||||
|
/// Contains all the translated version of that section
|
||||||
|
pub translations: Vec<Key>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Section {
|
impl Section {
|
||||||
|
@ -78,6 +80,7 @@ impl Section {
|
||||||
word_count: None,
|
word_count: None,
|
||||||
reading_time: None,
|
reading_time: None,
|
||||||
lang: None,
|
lang: None,
|
||||||
|
translations: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +238,7 @@ impl Default for Section {
|
||||||
reading_time: None,
|
reading_time: None,
|
||||||
word_count: None,
|
word_count: None,
|
||||||
lang: None,
|
lang: None,
|
||||||
|
translations: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +306,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn can_specify_language_in_filename() {
|
fn can_specify_language_in_filename() {
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.languages.push(Language {code: String::from("fr"), rss: false});
|
config.languages.push(Language { code: String::from("fr"), rss: false });
|
||||||
let content = r#"
|
let content = r#"
|
||||||
+++
|
+++
|
||||||
+++
|
+++
|
||||||
|
|
|
@ -80,12 +80,8 @@ impl Library {
|
||||||
/// Find out the direct subsections of each subsection if there are some
|
/// Find out the direct subsections of each subsection if there are some
|
||||||
/// as well as the pages for each section
|
/// as well as the pages for each section
|
||||||
pub fn populate_sections(&mut self) {
|
pub fn populate_sections(&mut self) {
|
||||||
let root_path= self
|
let root_path =
|
||||||
.sections
|
self.sections.values().find(|s| s.is_index()).map(|s| s.file.parent.clone()).unwrap();
|
||||||
.values()
|
|
||||||
.find(|s| s.is_index())
|
|
||||||
.map(|s| s.file.parent.clone())
|
|
||||||
.unwrap();
|
|
||||||
// We are going to get both the ancestors and grandparents for each section in one go
|
// We are going to get both the ancestors and grandparents for each section in one go
|
||||||
let mut ancestors: HashMap<PathBuf, Vec<_>> = HashMap::new();
|
let mut ancestors: HashMap<PathBuf, Vec<_>> = HashMap::new();
|
||||||
let mut subsections: HashMap<PathBuf, Vec<_>> = HashMap::new();
|
let mut subsections: HashMap<PathBuf, Vec<_>> = HashMap::new();
|
||||||
|
@ -119,7 +115,9 @@ impl Library {
|
||||||
if path == section.file.parent {
|
if path == section.file.parent {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(section_key) = self.paths_to_sections.get(&path.join(§ion.file.filename)) {
|
if let Some(section_key) =
|
||||||
|
self.paths_to_sections.get(&path.join(§ion.file.filename))
|
||||||
|
{
|
||||||
parents.push(*section_key);
|
parents.push(*section_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,7 +288,7 @@ pub fn after_content_rename(site: &mut Site, old: &Path, new: &Path) -> Result<(
|
||||||
old.to_path_buf()
|
old.to_path_buf()
|
||||||
};
|
};
|
||||||
site.library.remove_page(&old_path);
|
site.library.remove_page(&old_path);
|
||||||
return handle_page_editing(site, &new_path);
|
handle_page_editing(site, &new_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What happens when a section or a page is created/edited
|
/// What happens when a section or a page is created/edited
|
||||||
|
|
|
@ -267,9 +267,5 @@ Edite
|
||||||
let res = after_content_change(&mut site, &file_path);
|
let res = after_content_change(&mut site, &file_path);
|
||||||
println!("{:?}", res);
|
println!("{:?}", res);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(site_path, "public/fr/blog/with-assets/index.html", "Edite"));
|
||||||
site_path,
|
|
||||||
"public/fr/blog/with-assets/index.html",
|
|
||||||
"Edite"
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,10 @@ impl Site {
|
||||||
fn index_section_paths(&self) -> Vec<(PathBuf, Option<String>)> {
|
fn index_section_paths(&self) -> Vec<(PathBuf, Option<String>)> {
|
||||||
let mut res = vec![(self.content_path.join("_index.md"), None)];
|
let mut res = vec![(self.content_path.join("_index.md"), None)];
|
||||||
for language in &self.config.languages {
|
for language in &self.config.languages {
|
||||||
res.push((self.content_path.join(format!("_index.{}.md", language.code)), Some(language.code.clone())));
|
res.push((
|
||||||
|
self.content_path.join(format!("_index.{}.md", language.code)),
|
||||||
|
Some(language.code.clone()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -189,7 +192,9 @@ impl Site {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.filter(|e| !e.as_path().file_name().unwrap().to_str().unwrap().starts_with('.'))
|
.filter(|e| !e.as_path().file_name().unwrap().to_str().unwrap().starts_with('.'))
|
||||||
.partition(|entry| entry.as_path().file_name().unwrap().to_str().unwrap().starts_with("_index."));
|
.partition(|entry| {
|
||||||
|
entry.as_path().file_name().unwrap().to_str().unwrap().starts_with("_index.")
|
||||||
|
});
|
||||||
|
|
||||||
self.library = Library::new(page_entries.len(), section_entries.len());
|
self.library = Library::new(page_entries.len(), section_entries.len());
|
||||||
|
|
||||||
|
@ -241,7 +246,8 @@ impl Site {
|
||||||
let mut index_section = Section::default();
|
let mut index_section = Section::default();
|
||||||
index_section.file.parent = self.content_path.clone();
|
index_section.file.parent = self.content_path.clone();
|
||||||
index_section.file.name = "_index".to_string();
|
index_section.file.name = "_index".to_string();
|
||||||
index_section.file.filename = index_path.file_name().unwrap().to_string_lossy().to_string();
|
index_section.file.filename =
|
||||||
|
index_path.file_name().unwrap().to_string_lossy().to_string();
|
||||||
if let Some(ref l) = lang {
|
if let Some(ref l) = lang {
|
||||||
index_section.permalink = self.config.make_permalink(l);
|
index_section.permalink = self.config.make_permalink(l);
|
||||||
let filename = format!("_index.{}.md", l);
|
let filename = format!("_index.{}.md", l);
|
||||||
|
@ -353,7 +359,8 @@ impl Site {
|
||||||
pub fn add_page(&mut self, mut page: Page, render: bool) -> Result<Option<Page>> {
|
pub fn add_page(&mut self, mut page: Page, render: bool) -> Result<Option<Page>> {
|
||||||
self.permalinks.insert(page.file.relative.clone(), page.permalink.clone());
|
self.permalinks.insert(page.file.relative.clone(), page.permalink.clone());
|
||||||
if render {
|
if render {
|
||||||
let insert_anchor = self.find_parent_section_insert_anchor(&page.file.parent, &page.lang);
|
let insert_anchor =
|
||||||
|
self.find_parent_section_insert_anchor(&page.file.parent, &page.lang);
|
||||||
page.render_markdown(&self.permalinks, &self.tera, &self.config, insert_anchor)?;
|
page.render_markdown(&self.permalinks, &self.tera, &self.config, insert_anchor)?;
|
||||||
}
|
}
|
||||||
let prev = self.library.remove_page(&page.file.path);
|
let prev = self.library.remove_page(&page.file.path);
|
||||||
|
@ -379,7 +386,11 @@ impl Site {
|
||||||
|
|
||||||
/// Finds the insert_anchor for the parent section of the directory at `path`.
|
/// Finds the insert_anchor for the parent section of the directory at `path`.
|
||||||
/// Defaults to `AnchorInsert::None` if no parent section found
|
/// Defaults to `AnchorInsert::None` if no parent section found
|
||||||
pub fn find_parent_section_insert_anchor(&self, parent_path: &PathBuf, lang: &Option<String>) -> InsertAnchor {
|
pub fn find_parent_section_insert_anchor(
|
||||||
|
&self,
|
||||||
|
parent_path: &PathBuf,
|
||||||
|
lang: &Option<String>,
|
||||||
|
) -> InsertAnchor {
|
||||||
let parent = if let Some(ref l) = lang {
|
let parent = if let Some(ref l) = lang {
|
||||||
parent_path.join(format!("_index.{}.md", l))
|
parent_path.join(format!("_index.{}.md", l))
|
||||||
} else {
|
} else {
|
||||||
|
@ -746,7 +757,7 @@ impl Site {
|
||||||
let number_pagers = (section.pages.len() as f64
|
let number_pagers = (section.pages.len() as f64
|
||||||
/ section.meta.paginate_by.unwrap() as f64)
|
/ section.meta.paginate_by.unwrap() as f64)
|
||||||
.ceil() as isize;
|
.ceil() as isize;
|
||||||
for i in 1..number_pagers + 1 {
|
for i in 1..=number_pagers {
|
||||||
let permalink =
|
let permalink =
|
||||||
format!("{}{}/{}/", section.permalink, section.meta.paginate_path, i);
|
format!("{}{}/{}/", section.permalink, section.meta.paginate_path, i);
|
||||||
sections.push(SitemapEntry::new(permalink, None))
|
sections.push(SitemapEntry::new(permalink, None))
|
||||||
|
@ -770,7 +781,7 @@ impl Site {
|
||||||
let number_pagers = (item.pages.len() as f64
|
let number_pagers = (item.pages.len() as f64
|
||||||
/ taxonomy.kind.paginate_by.unwrap() as f64)
|
/ taxonomy.kind.paginate_by.unwrap() as f64)
|
||||||
.ceil() as isize;
|
.ceil() as isize;
|
||||||
for i in 1..number_pagers + 1 {
|
for i in 1..=number_pagers {
|
||||||
let permalink = self.config.make_permalink(&format!(
|
let permalink = self.config.make_permalink(&format!(
|
||||||
"{}/{}/{}/{}",
|
"{}/{}/{}/{}",
|
||||||
name,
|
name,
|
||||||
|
@ -822,7 +833,7 @@ impl Site {
|
||||||
|
|
||||||
context.insert("last_build_date", &pages[0].meta.date.clone());
|
context.insert("last_build_date", &pages[0].meta.date.clone());
|
||||||
// limit to the last n elements if the limit is set; otherwise use all.
|
// limit to the last n elements if the limit is set; otherwise use all.
|
||||||
let num_entries = self.config.rss_limit.unwrap_or(pages.len());
|
let num_entries = self.config.rss_limit.unwrap_or_else(|| pages.len());
|
||||||
let p = pages
|
let p = pages
|
||||||
.iter()
|
.iter()
|
||||||
.take(num_entries)
|
.take(num_entries)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
extern crate tempfile;
|
|
||||||
extern crate site;
|
extern crate site;
|
||||||
|
extern crate tempfile;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -50,7 +50,10 @@ pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `build_site` but has a hook to setup some config options
|
/// Same as `build_site` but has a hook to setup some config options
|
||||||
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf) where F: FnMut(Site) -> (Site, bool) {
|
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf)
|
||||||
|
where
|
||||||
|
F: FnMut(Site) -> (Site, bool),
|
||||||
|
{
|
||||||
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
|
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
|
||||||
path.push(name);
|
path.push(name);
|
||||||
let site = Site::new(&path, "config.toml").unwrap();
|
let site = Site::new(&path, "config.toml").unwrap();
|
||||||
|
|
|
@ -6,9 +6,9 @@ use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use common::{build_site, build_site_with_setup};
|
||||||
use config::Taxonomy;
|
use config::Taxonomy;
|
||||||
use site::Site;
|
use site::Site;
|
||||||
use common::{build_site, build_site_with_setup};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_parse_site() {
|
fn can_parse_site() {
|
||||||
|
@ -425,7 +425,10 @@ fn can_build_site_with_pagination_for_index() {
|
||||||
let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
|
let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
|
||||||
site.load().unwrap();
|
site.load().unwrap();
|
||||||
{
|
{
|
||||||
let index = site.library.get_section_mut(&site.base_path.join("content").join("_index.md")).unwrap();
|
let index = site
|
||||||
|
.library
|
||||||
|
.get_section_mut(&site.base_path.join("content").join("_index.md"))
|
||||||
|
.unwrap();
|
||||||
index.meta.paginate_by = Some(2);
|
index.meta.paginate_by = Some(2);
|
||||||
index.meta.template = Some("index_paginated.html".to_string());
|
index.meta.template = Some("index_paginated.html".to_string());
|
||||||
}
|
}
|
||||||
|
@ -482,8 +485,10 @@ fn can_build_site_with_pagination_for_taxonomy() {
|
||||||
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() {
|
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() {
|
||||||
page.meta.taxonomies = {
|
page.meta.taxonomies = {
|
||||||
let mut taxonomies = HashMap::new();
|
let mut taxonomies = HashMap::new();
|
||||||
taxonomies
|
taxonomies.insert(
|
||||||
.insert("tags".to_string(), vec![if i % 2 == 0 { "A" } else { "B" }.to_string()]);
|
"tags".to_string(),
|
||||||
|
vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
|
||||||
|
);
|
||||||
taxonomies
|
taxonomies
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ mod common;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use site::Site;
|
|
||||||
use common::build_site;
|
use common::build_site;
|
||||||
|
use site::Site;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_parse_multilingual_site() {
|
fn can_parse_multilingual_site() {
|
||||||
|
@ -17,11 +17,13 @@ fn can_parse_multilingual_site() {
|
||||||
assert_eq!(site.library.sections().len(), 4);
|
assert_eq!(site.library.sections().len(), 4);
|
||||||
|
|
||||||
// default index sections
|
// default index sections
|
||||||
let default_index_section = site.library.get_section(&path.join("content").join("_index.md")).unwrap();
|
let default_index_section =
|
||||||
|
site.library.get_section(&path.join("content").join("_index.md")).unwrap();
|
||||||
assert_eq!(default_index_section.pages.len(), 1);
|
assert_eq!(default_index_section.pages.len(), 1);
|
||||||
assert!(default_index_section.ancestors.is_empty());
|
assert!(default_index_section.ancestors.is_empty());
|
||||||
|
|
||||||
let fr_index_section = site.library.get_section(&path.join("content").join("_index.fr.md")).unwrap();
|
let fr_index_section =
|
||||||
|
site.library.get_section(&path.join("content").join("_index.fr.md")).unwrap();
|
||||||
assert_eq!(fr_index_section.pages.len(), 1);
|
assert_eq!(fr_index_section.pages.len(), 1);
|
||||||
assert!(fr_index_section.ancestors.is_empty());
|
assert!(fr_index_section.ancestors.is_empty());
|
||||||
|
|
||||||
|
@ -31,7 +33,10 @@ fn can_parse_multilingual_site() {
|
||||||
let default_blog = site.library.get_section(&blog_path.join("_index.md")).unwrap();
|
let default_blog = site.library.get_section(&blog_path.join("_index.md")).unwrap();
|
||||||
assert_eq!(default_blog.subsections.len(), 0);
|
assert_eq!(default_blog.subsections.len(), 0);
|
||||||
assert_eq!(default_blog.pages.len(), 4);
|
assert_eq!(default_blog.pages.len(), 4);
|
||||||
assert_eq!(default_blog.ancestors, vec![*site.library.get_section_key(&default_index_section.file.path).unwrap()]);
|
assert_eq!(
|
||||||
|
default_blog.ancestors,
|
||||||
|
vec![*site.library.get_section_key(&default_index_section.file.path).unwrap()]
|
||||||
|
);
|
||||||
for key in &default_blog.pages {
|
for key in &default_blog.pages {
|
||||||
let page = site.library.get_page_by_key(*key);
|
let page = site.library.get_page_by_key(*key);
|
||||||
assert_eq!(page.lang, None);
|
assert_eq!(page.lang, None);
|
||||||
|
@ -40,7 +45,10 @@ fn can_parse_multilingual_site() {
|
||||||
let fr_blog = site.library.get_section(&blog_path.join("_index.fr.md")).unwrap();
|
let fr_blog = site.library.get_section(&blog_path.join("_index.fr.md")).unwrap();
|
||||||
assert_eq!(fr_blog.subsections.len(), 0);
|
assert_eq!(fr_blog.subsections.len(), 0);
|
||||||
assert_eq!(fr_blog.pages.len(), 3);
|
assert_eq!(fr_blog.pages.len(), 3);
|
||||||
assert_eq!(fr_blog.ancestors, vec![*site.library.get_section_key(&fr_index_section.file.path).unwrap()]);
|
assert_eq!(
|
||||||
|
fr_blog.ancestors,
|
||||||
|
vec![*site.library.get_section_key(&fr_index_section.file.path).unwrap()]
|
||||||
|
);
|
||||||
for key in &fr_blog.pages {
|
for key in &fr_blog.pages {
|
||||||
let page = site.library.get_page_by_key(*key);
|
let page = site.library.get_page_by_key(*key);
|
||||||
assert_eq!(page.lang, Some("fr".to_string()));
|
assert_eq!(page.lang, Some("fr".to_string()));
|
||||||
|
|
|
@ -50,24 +50,24 @@ impl FromStr for OutputFormat {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(output_format: &str) -> Result<Self> {
|
fn from_str(output_format: &str) -> Result<Self> {
|
||||||
return match output_format {
|
match output_format {
|
||||||
"toml" => Ok(OutputFormat::Toml),
|
"toml" => Ok(OutputFormat::Toml),
|
||||||
"csv" => Ok(OutputFormat::Csv),
|
"csv" => Ok(OutputFormat::Csv),
|
||||||
"json" => Ok(OutputFormat::Json),
|
"json" => Ok(OutputFormat::Json),
|
||||||
"plain" => Ok(OutputFormat::Plain),
|
"plain" => Ok(OutputFormat::Plain),
|
||||||
format => Err(format!("Unknown output format {}", format).into()),
|
format => Err(format!("Unknown output format {}", format).into()),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputFormat {
|
impl OutputFormat {
|
||||||
fn as_accept_header(&self) -> header::HeaderValue {
|
fn as_accept_header(&self) -> header::HeaderValue {
|
||||||
return header::HeaderValue::from_static(match self {
|
header::HeaderValue::from_static(match self {
|
||||||
OutputFormat::Json => "application/json",
|
OutputFormat::Json => "application/json",
|
||||||
OutputFormat::Csv => "text/csv",
|
OutputFormat::Csv => "text/csv",
|
||||||
OutputFormat::Toml => "application/toml",
|
OutputFormat::Toml => "application/toml",
|
||||||
OutputFormat::Plain => "text/plain",
|
OutputFormat::Plain => "text/plain",
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,18 +91,18 @@ impl DataSource {
|
||||||
|
|
||||||
if let Some(url) = url_arg {
|
if let Some(url) = url_arg {
|
||||||
return Url::parse(&url)
|
return Url::parse(&url)
|
||||||
.map(|parsed_url| DataSource::Url(parsed_url))
|
.map(DataSource::Url)
|
||||||
.map_err(|e| format!("Failed to parse {} as url: {}", url, e).into());
|
.map_err(|e| format!("Failed to parse {} as url: {}", url, e).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(GET_DATA_ARGUMENT_ERROR_MESSAGE.into());
|
Err(GET_DATA_ARGUMENT_ERROR_MESSAGE.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_cache_key(&self, format: &OutputFormat) -> u64 {
|
fn get_cache_key(&self, format: &OutputFormat) -> u64 {
|
||||||
let mut hasher = DefaultHasher::new();
|
let mut hasher = DefaultHasher::new();
|
||||||
format.hash(&mut hasher);
|
format.hash(&mut hasher);
|
||||||
self.hash(&mut hasher);
|
self.hash(&mut hasher);
|
||||||
return hasher.finish();
|
hasher.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +123,9 @@ fn get_data_source_from_args(
|
||||||
args: &HashMap<String, Value>,
|
args: &HashMap<String, Value>,
|
||||||
) -> Result<DataSource> {
|
) -> Result<DataSource> {
|
||||||
let path_arg = optional_arg!(String, args.get("path"), GET_DATA_ARGUMENT_ERROR_MESSAGE);
|
let path_arg = optional_arg!(String, args.get("path"), GET_DATA_ARGUMENT_ERROR_MESSAGE);
|
||||||
|
|
||||||
let url_arg = optional_arg!(String, args.get("url"), GET_DATA_ARGUMENT_ERROR_MESSAGE);
|
let url_arg = optional_arg!(String, args.get("url"), GET_DATA_ARGUMENT_ERROR_MESSAGE);
|
||||||
|
|
||||||
return DataSource::from_args(path_arg, url_arg, content_path);
|
DataSource::from_args(path_arg, url_arg, content_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> {
|
fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> {
|
||||||
|
@ -140,9 +139,9 @@ fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> {
|
||||||
)
|
)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
return read_file(&full_path).map_err(|e| {
|
read_file(&full_path).map_err(|e| {
|
||||||
format!("`load_data`: error {} loading file {}", full_path.to_str().unwrap(), e).into()
|
format!("`load_data`: error {} loading file {}", full_path.to_str().unwrap(), e).into()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_output_format_from_args(
|
fn get_output_format_from_args(
|
||||||
|
@ -161,14 +160,14 @@ fn get_output_format_from_args(
|
||||||
|
|
||||||
let from_extension = if let DataSource::Path(path) = data_source {
|
let from_extension = if let DataSource::Path(path) = data_source {
|
||||||
let extension_result: Result<&str> =
|
let extension_result: Result<&str> =
|
||||||
path.extension().map(|extension| extension.to_str().unwrap()).ok_or(
|
path.extension().map(|extension| extension.to_str().unwrap()).ok_or_else(|| {
|
||||||
format!("Could not determine format for {} from extension", path.display()).into(),
|
format!("Could not determine format for {} from extension", path.display()).into()
|
||||||
);
|
});
|
||||||
extension_result?
|
extension_result?
|
||||||
} else {
|
} else {
|
||||||
"plain"
|
"plain"
|
||||||
};
|
};
|
||||||
return OutputFormat::from_str(from_extension);
|
OutputFormat::from_str(from_extension)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A global function to load data from a file or from a URL
|
/// A global function to load data from a file or from a URL
|
||||||
|
@ -231,7 +230,7 @@ pub fn make_load_data(content_path: PathBuf, base_path: PathBuf) -> GlobalFn {
|
||||||
fn load_json(json_data: String) -> Result<Value> {
|
fn load_json(json_data: String) -> Result<Value> {
|
||||||
let json_content: Value =
|
let json_content: Value =
|
||||||
serde_json::from_str(json_data.as_str()).map_err(|e| format!("{:?}", e))?;
|
serde_json::from_str(json_data.as_str()).map_err(|e| format!("{:?}", e))?;
|
||||||
return Ok(json_content);
|
Ok(json_content)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a TOML string and convert it to a Tera Value
|
/// Parse a TOML string and convert it to a Tera Value
|
||||||
|
|
|
@ -142,9 +142,11 @@ pub fn make_get_taxonomy(all_taxonomies: &[Taxonomy], library: &Library) -> Glob
|
||||||
let container = match taxonomies.get(&kind) {
|
let container = match taxonomies.get(&kind) {
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
None => {
|
None => {
|
||||||
return Err(
|
return Err(format!(
|
||||||
format!("`get_taxonomy` received an unknown taxonomy as kind: {}", kind).into()
|
"`get_taxonomy` received an unknown taxonomy as kind: {}",
|
||||||
);
|
kind
|
||||||
|
)
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -502,12 +502,9 @@ fn detect_change_kind(pwd: &Path, path: &Path) -> (ChangeKind, PathBuf) {
|
||||||
/// Check if the directory at path contains any file
|
/// Check if the directory at path contains any file
|
||||||
fn is_folder_empty(dir: &Path) -> bool {
|
fn is_folder_empty(dir: &Path) -> bool {
|
||||||
// Can panic if we don't have the rights I guess?
|
// Can panic if we don't have the rights I guess?
|
||||||
for _ in read_dir(dir).expect("Failed to read a directory to see if it was empty") {
|
let files: Vec<_> =
|
||||||
// If we get there, that means we have a file
|
read_dir(dir).expect("Failed to read a directory to see if it was empty").collect();
|
||||||
return false;
|
files.is_empty()
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue