Skip to content

Commit

Permalink
Merge pull request #315 from epage/cleanup
Browse files Browse the repository at this point in the history
Misc cleanup towards #312
  • Loading branch information
epage authored Oct 31, 2017
2 parents 0585df0 + 2a61f0c commit bb12174
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 270 deletions.
109 changes: 13 additions & 96 deletions src/cobalt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fs::{self, File};
use std::fs::File;
use std::collections::HashMap;
use std::io::Write;
use std::path::Path;
Expand All @@ -8,16 +8,12 @@ use rss;
use jsonfeed::Feed;
use jsonfeed;

#[cfg(feature = "sass")]
use sass_rs;

use config::{Config, SortOrder};
use datetime;
use document::Document;
use error::*;
use config::{Config, SortOrder};
#[cfg(feature = "sass")]
use config::SassOutputStyle;
use files::FilesBuilder;
use files;
use sass;

/// The primary build function that transforms a directory into a site
pub fn build(config: &Config) -> Result<()> {
Expand All @@ -39,7 +35,7 @@ pub fn build(config: &Config) -> Result<()> {

let mut documents = vec![];

let mut page_files = FilesBuilder::new(source)?;
let mut page_files = files::FilesBuilder::new(source)?;
page_files
.add_ignore(&format!("!{}", config.posts.dir))?
.add_ignore(&format!("!{}/**", config.posts.dir))?
Expand Down Expand Up @@ -75,7 +71,7 @@ pub fn build(config: &Config) -> Result<()> {
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 = FilesBuilder::new(drafts_root.as_path())?;
let mut draft_files = files::FilesBuilder::new(drafts_root.as_path())?;
for line in &config.ignore {
draft_files.add_ignore(line.as_str())?;
}
Expand Down Expand Up @@ -151,7 +147,7 @@ pub fn build(config: &Config) -> Result<()> {
let file_name = format!("_{}.{}.{}", file_name, dump, ext);
file_path.set_file_name(file_name);
trace!("Generating {:?}", file_path);
create_document_file(content, dest.join(file_path))?;
files::create_document_file(content, dest.join(file_path))?;
}

let mut context = post.get_render_context(&simple_posts_data);
Expand All @@ -166,7 +162,7 @@ pub fn build(config: &Config) -> Result<()> {
&mut layouts_cache,
&config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render for {:?}", post.file_path))?;
create_document_file(post_html, dest.join(&post.file_path))?;
files::create_document_file(post_html, dest.join(&post.file_path))?;
}

// check if we should create an RSS file and create it!
Expand Down Expand Up @@ -201,7 +197,7 @@ pub fn build(config: &Config) -> Result<()> {
let file_name = format!("_{}.{}.{}", file_name, dump, ext);
file_path.set_file_name(file_name);
trace!("Generating {:?}", file_path);
create_document_file(content, dest.join(file_path))?;
files::create_document_file(content, dest.join(file_path))?;
}

let mut context = doc.get_render_context(&posts_data);
Expand All @@ -214,15 +210,15 @@ pub fn build(config: &Config) -> Result<()> {
&mut layouts_cache,
&config.syntax_highlight.theme)
.chain_err(|| format!("Failed to render for {:?}", doc.file_path))?;
create_document_file(doc_html, dest.join(doc.file_path))?;
files::create_document_file(doc_html, dest.join(doc.file_path))?;
}

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

let mut asset_files = FilesBuilder::new(source)?;
let mut asset_files = files::FilesBuilder::new(source)?;
for line in &config.ignore {
asset_files.add_ignore(line.as_str())?;
}
Expand All @@ -231,12 +227,12 @@ pub fn build(config: &Config) -> Result<()> {
!template_extensions.contains(&p.extension().unwrap_or_else(|| OsStr::new("")))
}) {
if file_path.extension() == Some(OsStr::new("scss")) {
compile_sass(config, source, dest, file_path)?;
sass::compile_sass(&config.sass, source, dest, file_path)?;
} else {
let rel_src = file_path
.strip_prefix(source)
.expect("file was found under the root");
copy_file(&file_path, dest.join(rel_src).as_path())?;
files::copy_file(&file_path, dest.join(rel_src).as_path())?;
}
}
}
Expand Down Expand Up @@ -326,82 +322,3 @@ fn create_jsonfeed(path: &str, dest: &Path, config: &Config, posts: &[Document])
info!("Created jsonfeed file at {}", jsonfeed_path.display());
Ok(())
}

fn compile_sass<S: AsRef<Path>, D: AsRef<Path>, F: AsRef<Path>>(config: &Config,
source: S,
dest: D,
file_path: F)
-> Result<()> {
compile_sass_internal(config, source.as_ref(), dest.as_ref(), file_path.as_ref())
}

#[cfg(feature = "sass")]
fn compile_sass_internal(config: &Config,
source: &Path,
dest: &Path,
file_path: &Path)
-> Result<()> {
let mut sass_opts = sass_rs::Options::default();
sass_opts.include_paths = vec![source
.join(&config.sass.import_dir)
.into_os_string()
.into_string()
.unwrap()];
sass_opts.output_style = match config.sass.style {
SassOutputStyle::Nested => sass_rs::OutputStyle::Nested,
SassOutputStyle::Expanded => sass_rs::OutputStyle::Expanded,
SassOutputStyle::Compact => sass_rs::OutputStyle::Compact,
SassOutputStyle::Compressed => sass_rs::OutputStyle::Compressed,
};
let content = sass_rs::compile_file(file_path, sass_opts)?;

let rel_src = file_path
.strip_prefix(source)
.expect("file was found under the root");
let mut dest_file = dest.join(rel_src);
dest_file.set_extension("css");

create_document_file(content, dest_file)
}

#[cfg(not(feature = "sass"))]
fn compile_sass_internal(_config: &Config,
source: &Path,
dest: &Path,
file_path: &Path)
-> Result<()> {
let src_file = source.join(file_path);
copy_file(src_file.as_path(), dest.join(file_path).as_path())
}

fn copy_file(src_file: &Path, dest_file: &Path) -> Result<()> {
// create target directories if any exist
if let Some(parent) = dest_file.parent() {
fs::create_dir_all(parent)
.map_err(|e| format!("Could not create {:?}: {}", parent, e))?;
}

debug!("Copying {:?} to {:?}", src_file, dest_file);
fs::copy(src_file, dest_file)
.map_err(|e| format!("Could not copy {:?} into {:?}: {}", src_file, dest_file, e))?;
Ok(())
}

fn create_document_file<S: AsRef<str>, P: AsRef<Path>>(content: S, dest_file: P) -> Result<()> {
create_document_file_internal(content.as_ref(), dest_file.as_ref())
}

fn create_document_file_internal(content: &str, dest_file: &Path) -> Result<()> {
// create target directories if any exist
if let Some(parent) = dest_file.parent() {
fs::create_dir_all(parent)
.map_err(|e| format!("Could not create {:?}: {}", parent, e))?;
}

let mut file = File::create(dest_file)
.map_err(|e| format!("Could not create {:?}: {}", dest_file, e))?;

file.write_all(content.as_bytes())?;
info!("Created {}", dest_file.display());
Ok(())
}
130 changes: 11 additions & 119 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::default::Default;
use std::path;
use std::fs::File;
use std::io::Read;
use error::*;

use serde_yaml;

use error::*;
use files;
use frontmatter;
use legacy::wildwest;
use sass;
use site;
use syntax_highlight::has_syntax_theme;

Expand Down Expand Up @@ -41,36 +42,6 @@ impl Default for SortOrder {
}
}

#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub enum SassOutputStyle {
Nested,
Expanded,
Compact,
Compressed,
}

const SASS_IMPORT_DIR: &'static str = "_sass";

#[derive(Debug, PartialEq)]
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct SassOptions {
#[serde(skip)]
pub import_dir: &'static str,
pub style: SassOutputStyle,
}

impl Default for SassOptions {
fn default() -> SassOptions {
SassOptions {
import_dir: SASS_IMPORT_DIR,
style: SassOutputStyle::Nested,
}
}
}

#[derive(Debug, PartialEq)]
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
Expand Down Expand Up @@ -142,7 +113,7 @@ pub struct ConfigBuilder {
pub ignore: Vec<String>,
pub syntax_highlight: SyntaxHighlight,
pub layouts_dir: &'static str,
pub sass: SassOptions,
pub sass: sass::SassOptions,
// This is a debug-only field and should be transient rather than persistently set.
#[serde(skip)]
pub dump: Vec<Dump>,
Expand All @@ -167,7 +138,7 @@ impl Default for ConfigBuilder {
ignore: vec![],
syntax_highlight: SyntaxHighlight::default(),
layouts_dir: LAYOUTS_DIR,
sass: SassOptions::default(),
sass: sass::SassOptions::default(),
dump: vec![],
}
}
Expand All @@ -179,12 +150,7 @@ impl ConfigBuilder {
}

fn from_file_internal(path: path::PathBuf) -> Result<ConfigBuilder> {
let content = {
let mut buffer = String::new();
let mut f = File::open(&path)?;
f.read_to_string(&mut buffer)?;
buffer
};
let content = files::read_file(&path)?;

if content.trim().is_empty() {
return Ok(ConfigBuilder::default());
Expand All @@ -205,7 +171,7 @@ impl ConfigBuilder {
}

fn from_cwd_internal(cwd: path::PathBuf) -> Result<ConfigBuilder> {
let file_path = find_project_file(&cwd, ".cobalt.yml");
let file_path = files::find_project_file(&cwd, ".cobalt.yml");
let mut config = file_path
.map(|p| {
info!("Using config file {:?}", &p);
Expand Down Expand Up @@ -257,8 +223,8 @@ impl ConfigBuilder {
let mut posts = posts;
posts.default = posts.default.merge(default);

let source = cleanup_path(source);
let destination = cleanup_path(destination);
let source = files::cleanup_path(source);
let destination = files::cleanup_path(destination);

let mut ignore = ignore;
if let Ok(rel_dest) = path::Path::new(&destination).strip_prefix(&source) {
Expand Down Expand Up @@ -308,7 +274,7 @@ pub struct Config {
pub ignore: Vec<String>,
pub syntax_highlight: SyntaxHighlight,
pub layouts_dir: &'static str,
pub sass: SassOptions,
pub sass: sass::SassOptions,
pub dump: Vec<Dump>,
}

Expand All @@ -319,80 +285,6 @@ impl Default for Config {
.expect("default config should not fail")
}
}
fn find_project_file<P: Into<path::PathBuf>>(dir: P, name: &str) -> Option<path::PathBuf> {
find_project_file_internal(dir.into(), name)
}

fn find_project_file_internal(dir: path::PathBuf, name: &str) -> Option<path::PathBuf> {
let mut file_path = dir;
file_path.push(name);
while !file_path.exists() {
file_path.pop(); // filename
let hit_bottom = !file_path.pop();
if hit_bottom {
return None;
}
file_path.push(name);
}
Some(file_path)
}

fn cleanup_path(path: String) -> String {
let stripped = path.trim_left_matches("./");
if stripped == "." {
String::new()
} else {
stripped.to_owned()
}
}

#[test]
fn find_project_file_same_dir() {
let actual = find_project_file("tests/fixtures/config", ".cobalt.yml").unwrap();
let expected = path::Path::new("tests/fixtures/config/.cobalt.yml");
assert_eq!(actual, expected);
}

#[test]
fn find_project_file_parent_dir() {
let actual = find_project_file("tests/fixtures/config/child", ".cobalt.yml").unwrap();
let expected = path::Path::new("tests/fixtures/config/.cobalt.yml");
assert_eq!(actual, expected);
}

#[test]
fn find_project_file_doesnt_exist() {
let expected = path::Path::new("<NOT FOUND>");
let actual = find_project_file("tests/fixtures/", ".cobalt.yml")
.unwrap_or_else(|| expected.into());
assert_eq!(actual, expected);
}

#[test]
fn cleanup_path_empty() {
assert_eq!(cleanup_path("".to_owned()), "".to_owned());
}

#[test]
fn cleanup_path_dot() {
assert_eq!(cleanup_path(".".to_owned()), "".to_owned());
}

#[test]
fn cleanup_path_current_dir() {
assert_eq!(cleanup_path("./".to_owned()), "".to_owned());
}

#[test]
fn cleanup_path_current_dir_extreme() {
assert_eq!(cleanup_path("././././.".to_owned()), "".to_owned());
}

#[test]
fn cleanup_path_current_dir_child() {
assert_eq!(cleanup_path("./build/file.txt".to_owned()),
"build/file.txt".to_owned());
}

#[test]
fn test_from_file_ok() {
Expand Down
Loading

0 comments on commit bb12174

Please sign in to comment.