Skip to content

Commit

Permalink
Merge pull request cobalt-org#373 from Geobert/rename_some_refactored…
Browse files Browse the repository at this point in the history
…_fct

Rename some refactored fct
  • Loading branch information
epage committed Jan 27, 2018
2 parents 0aedcba + bc97e4e commit de7b6d0
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 131 deletions.
254 changes: 129 additions & 125 deletions src/cobalt.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fs;
use std::collections::HashMap;
use std::io::Write;
use std::path::Path;
use std::path::{PathBuf, Path};
use std::ffi::OsStr;
use liquid;
use rss;
Expand Down Expand Up @@ -34,16 +34,16 @@ pub fn build(config: &Config) -> Result<()> {
debug!("Posts directory: {:?}", posts_path);
debug!("Draft mode enabled: {}", config.include_drafts);

let page_files = construct_page_files(source, config)?;
let mut documents = parse_files(&page_files, source, config, &template_extensions)?;
let page_files = find_pages(source, config)?;
let mut documents = parse_pages(&page_files, source, config, &template_extensions)?;
process_included_drafts(config, source, &template_extensions, &mut documents)?;

let (mut posts, documents): (Vec<Document>, Vec<Document>) =
documents
.into_iter()
.partition(|x| x.front.collection == "posts");

sort_documents_by_date(&mut posts, config)?;
sort_pages(&mut posts, config)?;
generate_posts(&mut posts,
config,
&parser,
Expand All @@ -60,33 +60,86 @@ pub fn build(config: &Config) -> Result<()> {
create_jsonfeed(path, dest, config, &posts)?;
}

generate_other_docs(posts,
documents,
config,
&parser,
dest,
&layouts,
&mut layouts_cache)?;
generate_pages(posts,
documents,
config,
&parser,
dest,
&layouts,
&mut layouts_cache)?;

// copy all remaining files in the source to the destination
// compile SASS along the way
{
debug!("Copying remaining assets");

config.assets.populate(dest)?;
}

Ok(())
}

fn generate_other_docs(posts: Vec<Document>,
documents: Vec<Document>,
config: &Config,
parser: &template::LiquidParser,
dest: &Path,
layouts: &Path,
mut layouts_cache: &mut HashMap<String, String>)
-> Result<()> {
fn generate_doc(dest: &Path,
layouts: &Path,
mut layouts_cache: &mut HashMap<String, String>,
parser: &template::LiquidParser,
posts_data: &[liquid::Value],
doc: &mut Document,
config: &Config)
-> Result<()> {
for dump in config.dump.iter().filter(|d| d.is_doc()) {
trace!("Dumping {:?}", dump);
let (content, ext) = doc.render_dump(*dump)?;
let mut file_path = doc.file_path.clone();
let file_name = file_path
.file_stem()
.and_then(|p| p.to_str())
.expect("page must have file name")
.to_owned();
let file_name = format!("_{}.{}.{}", file_name, dump, ext);
file_path.set_file_name(file_name);
trace!("Generating {:?}", file_path);
files::write_document_file(content, dest.join(file_path))?;
}

// Everything done with `globals` is terrible for performance. liquid#95 allows us to
// improve this.
let mut posts_variable = config.posts.attributes.clone();
posts_variable.insert("pages".to_owned(),
liquid::Value::Array(posts_data.to_vec()));
let global_collection: liquid::Object = vec![(config.posts.slug.clone(),
liquid::Value::Object(posts_variable))]
.into_iter()
.collect();
let mut globals: liquid::Object =
vec![("site".to_owned(), liquid::Value::Object(config.site.attributes.clone())),
("collections".to_owned(), liquid::Value::Object(global_collection))]
.into_iter()
.collect();
globals.insert("page".to_owned(),
liquid::Value::Object(doc.attributes.clone()));

doc.render_excerpt(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render excerpt for {:?}", doc.file_path))?;
doc.render_content(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render content for {:?}", doc.file_path))?;

// Refresh `page` with the `excerpt` / `content` attribute
globals.insert("page".to_owned(),
liquid::Value::Object(doc.attributes.clone()));
let doc_html = doc.render(&globals, parser, layouts, &mut layouts_cache)
.chain_err(|| format!("Failed to render for {:?}", doc.file_path))?;
files::write_document_file(doc_html, dest.join(&doc.file_path))?;
Ok(())
}

fn generate_pages(posts: Vec<Document>,
documents: Vec<Document>,
config: &Config,
parser: &template::LiquidParser,
dest: &Path,
layouts: &Path,
mut layouts_cache: &mut HashMap<String, String>)
-> Result<()> {
// during post rendering additional attributes such as content were
// added to posts. collect them so that non-post documents can access them
let posts_data: Vec<liquid::Value> = posts
Expand All @@ -97,46 +150,13 @@ fn generate_other_docs(posts: Vec<Document>,
trace!("Generating other documents");
for mut doc in documents {
trace!("Generating {}", doc.url_path);

for dump in config.dump.iter().filter(|d| d.is_doc()) {
trace!("Dumping {:?}", dump);
let (content, ext) = doc.render_dump(*dump)?;
let mut file_path = doc.file_path.clone();
let file_name = file_path
.file_stem()
.and_then(|p| p.to_str())
.expect("page must have file name")
.to_owned();
let file_name = format!("_{}.{}.{}", file_name, dump, ext);
file_path.set_file_name(file_name);
trace!("Generating {:?}", file_path);
files::write_document_file(content, dest.join(file_path))?;
}

let mut posts_variable = config.posts.attributes.clone();
posts_variable.insert("pages".to_owned(), liquid::Value::Array(posts_data.clone()));
let global_collection: liquid::Object = vec![(config.posts.slug.clone(),
liquid::Value::Object(posts_variable))]
.into_iter()
.collect();
let mut globals: liquid::Object =
vec![("site".to_owned(), liquid::Value::Object(config.site.attributes.clone())),
("collections".to_owned(), liquid::Value::Object(global_collection))]
.into_iter()
.collect();
globals.insert("page".to_owned(),
liquid::Value::Object(doc.attributes.clone()));
doc.render_excerpt(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render excerpt for {:?}", doc.file_path))?;
doc.render_content(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render content for {:?}", doc.file_path))?;

// Refresh `page` with the `excerpt` / `content` attribute
globals.insert("page".to_owned(),
liquid::Value::Object(doc.attributes.clone()));
let doc_html = doc.render(&globals, parser, layouts, &mut layouts_cache)
.chain_err(|| format!("Failed to render for {:?}", doc.file_path))?;
files::write_document_file(doc_html, dest.join(doc.file_path))?;
generate_doc(dest,
layouts,
&mut layouts_cache,
parser,
&posts_data,
&mut doc,
config)?;
}

Ok(())
Expand Down Expand Up @@ -174,54 +194,19 @@ fn generate_posts(posts: &mut Vec<Document>,
.unwrap_or(liquid::Value::Nil);
post.attributes.insert("next".to_owned(), next);

for dump in config.dump.iter().filter(|d| d.is_doc()) {
trace!("Dumping {:?}", dump);
let (content, ext) = post.render_dump(*dump)?;
let mut file_path = post.file_path.clone();
let file_name = file_path
.file_stem()
.and_then(|p| p.to_str())
.expect("page must have file name")
.to_owned();
let file_name = format!("_{}.{}.{}", file_name, dump, ext);
file_path.set_file_name(file_name);
trace!("Generating {:?}", file_path);
files::write_document_file(content, dest.join(file_path))?;
}

// Everything done with `globals` is terrible for performance. liquid#95 allows us to
// improve this.
let mut posts_variable = config.posts.attributes.clone();
posts_variable.insert("pages".to_owned(),
liquid::Value::Array(simple_posts_data.clone()));
let global_collection: liquid::Object = vec![(config.posts.slug.clone(),
liquid::Value::Object(posts_variable))]
.into_iter()
.collect();
let mut globals: liquid::Object =
vec![("site".to_owned(), liquid::Value::Object(config.site.attributes.clone())),
("collections".to_owned(), liquid::Value::Object(global_collection))]
.into_iter()
.collect();
globals.insert("page".to_owned(),
liquid::Value::Object(post.attributes.clone()));
post.render_excerpt(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render excerpt for {:?}", post.file_path))?;
post.render_content(&globals, parser, &config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render content for {:?}", post.file_path))?;

// Refresh `page` with the `excerpt` / `content` attribute
globals.insert("page".to_owned(),
liquid::Value::Object(post.attributes.clone()));
let post_html = post.render(&globals, parser, layouts, &mut layouts_cache)
.chain_err(|| format!("Failed to render for {:?}", post.file_path))?;
files::write_document_file(post_html, dest.join(&post.file_path))?;
generate_doc(dest,
layouts,
&mut layouts_cache,
parser,
&simple_posts_data,
post,
config)?;
}

Ok(())
}

fn sort_documents_by_date(posts: &mut Vec<Document>, config: &Config) -> Result<()> {
fn sort_pages(posts: &mut Vec<Document>, config: &Config) -> Result<()> {
// January 1, 1970 0:00:00 UTC, the beginning of time
let default_date = cobalt_model::DateTime::default();

Expand All @@ -242,6 +227,38 @@ fn sort_documents_by_date(posts: &mut Vec<Document>, config: &Config) -> Result<
Ok(())
}

fn find_drafts_files(drafts_root: &Path, config: &Config) -> Result<files::Files> {
let mut draft_files = files::FilesBuilder::new(drafts_root)?;
for line in &config.ignore {
draft_files.add_ignore(line.as_str())?;
}
Ok(draft_files.build()?)
}

fn parse_drafts(drafts_root: &PathBuf,
draft_files: &files::Files,
template_extensions: &[&OsStr],
documents: &mut Vec<Document>,
config: &Config)
-> Result<()> {
for file_path in draft_files.files().filter(|p| {
template_extensions.contains(&p.extension().unwrap_or_else(|| OsStr::new("")))
}) {
// Provide a fake path as if it was not a draft
let rel_src = file_path
.strip_prefix(&drafts_root)
.expect("file was found under the root");
let new_path = Path::new(&config.posts.dir).join(rel_src);

let default_front = config.posts.default.clone().set_draft(true);

let doc = Document::parse(&file_path, &new_path, default_front)
.chain_err(|| format!("Failed to parse {:?}", rel_src))?;
documents.push(doc);
}
Ok(())
}

fn process_included_drafts(config: &Config,
source: &Path,
template_extensions: &[&OsStr],
Expand All @@ -251,32 +268,19 @@ fn process_included_drafts(config: &Config,
if let Some(ref drafts_dir) = config.posts.drafts_dir {
debug!("Draft directory: {:?}", drafts_dir);
let drafts_root = source.join(&drafts_dir);
let mut draft_files = files::FilesBuilder::new(drafts_root.as_path())?;
for line in &config.ignore {
draft_files.add_ignore(line.as_str())?;
}
let draft_files = draft_files.build()?;
for file_path in draft_files.files().filter(|p| {
template_extensions.contains(&p.extension().unwrap_or_else(|| OsStr::new("")))
}) {
// Provide a fake path as if it was not a draft
let rel_src = file_path
.strip_prefix(&drafts_root)
.expect("file was found under the root");
let new_path = Path::new(&config.posts.dir).join(rel_src);

let default_front = config.posts.default.clone().set_draft(true);

let doc = Document::parse(&file_path, &new_path, default_front)
.chain_err(|| format!("Failed to parse {:?}", rel_src))?;
documents.push(doc);
}
let draft_files = find_drafts_files(drafts_root.as_path(), config)?;

parse_drafts(&drafts_root,
&draft_files,
template_extensions,
documents,
config)?;
}
}
Ok(())
}

fn construct_page_files(source: &Path, config: &Config) -> Result<files::Files> {
fn find_pages(source: &Path, config: &Config) -> Result<files::Files> {
let mut page_files = files::FilesBuilder::new(source)?;
page_files
.add_ignore(&format!("!{}", config.posts.dir))?
Expand All @@ -289,7 +293,7 @@ fn construct_page_files(source: &Path, config: &Config) -> Result<files::Files>
page_files.build()
}

fn parse_files(page_files: &files::Files,
fn parse_pages(page_files: &files::Files,
source: &Path,
config: &Config,
template_extensions: &[&OsStr])
Expand Down
3 changes: 2 additions & 1 deletion src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::default::Default;
use std::path::{Path, PathBuf};
use std::clone::Clone;

use chrono::{Datelike, Timelike};
use itertools;
Expand Down Expand Up @@ -163,7 +164,7 @@ fn document_attributes(front: &cobalt_model::Frontmatter,
attributes
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Document {
pub url_path: String,
pub file_path: PathBuf,
Expand Down
8 changes: 3 additions & 5 deletions tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,9 @@ pub fn liquid_raw() {
pub fn no_extends_error() {
let err = run_test("no_extends_error");
assert!(err.is_err());
assert_contains!(
format!("{}", err.unwrap_err().display_chain()),
"Layout default_nonexistent.liquid can not be read (defined in \
\"index.html\")"
);
assert_contains!(format!("{}", err.unwrap_err().display_chain()),
"Layout default_nonexistent.liquid can not be read (defined in \
\"index.html\")");
}

#[test]
Expand Down

0 comments on commit de7b6d0

Please sign in to comment.