Adding a config yaml file

This commit is contained in:
Ethan Frei 2015-12-04 19:37:25 +00:00
parent c1d162c201
commit 55aec9df49
11 changed files with 183 additions and 6 deletions

View file

@ -10,6 +10,7 @@ markdown = "0.1"
liquid = "0.2"
walkdir = "0.1"
crossbeam = "0.1.5"
yaml-rust = "0.2.2"
[dev-dependencies]
difference = "0.4"

View file

@ -2,10 +2,16 @@
extern crate cobalt;
extern crate getopts;
extern crate yaml_rust;
use getopts::Options;
use getopts::{ Matches, Options };
use std::env;
use std::path::PathBuf;
use std::fs::File;
use std::io::Result as IoResult;
use std::io::prelude::*;
use std::path::{ Path, PathBuf };
use yaml_rust::Yaml;
use yaml_rust::scanner::ScanError;
fn print_version() {
// TODO parse this from Cargo.toml
@ -48,11 +54,29 @@ fn main() {
return;
}
// Fetch config information if available
let config_contents_result = get_config_contents("./config.yml");
let yaml = if let Ok(config_contents) = config_contents_result {
match parse_yaml(config_contents) {
Ok(y) => {
y
}
Err(e) => {
// Trouble parsing yaml file
panic!(e.to_string())
}
}
} else {
// No config file or error reading it.
Yaml::from_str("")
};
// join("") makes sure path has a trailing slash
let source = PathBuf::from(&matches.opt_str("s").unwrap_or("./".to_string())).join("");
let dest = PathBuf::from(&matches.opt_str("d").unwrap_or("./".to_string())).join("");
let layouts = matches.opt_str("layouts").unwrap_or("_layouts".to_string());
let posts = matches.opt_str("posts").unwrap_or("_posts".to_string());
let source = PathBuf::from(&get_setting("s", "source", "./", &matches, &yaml)).join("");
let dest = PathBuf::from(&get_setting("d", "dest", "./", &matches, &yaml)).join("");
let layouts = get_setting("layouts", "layouts", "_layouts", &matches, &yaml);
let posts = get_setting("posts", "posts", "_posts", &matches, &yaml);
let command = if !matches.free.is_empty() {
matches.free[0].clone()
@ -76,3 +100,72 @@ fn main() {
}
}
}
fn get_setting(arg_str: &str, config_str: &str, default: &str, matches: &Matches, yaml: &Yaml) -> String {
if let Some(arg_val) = matches.opt_str(arg_str) {
arg_val
} else if let Some(config_val) = yaml[config_str].as_str() {
config_val.to_string()
} else {
default.to_string()
}
}
fn get_config_contents<P: AsRef<Path>>(config_file: P) -> IoResult<String> {
let mut buffer = String::new();
let mut f = try!(File::open(config_file));
try!(f.read_to_string(&mut buffer));
Ok(buffer)
}
fn parse_yaml(file_contents: String) -> Result<Yaml, ScanError> {
use yaml_rust::YamlLoader;
let doc_list = try!(YamlLoader::load_from_str(&file_contents));
// Cannot return parsed document directly as list goes out of scope
// Cloning as of now
Ok(doc_list[0].clone())
}
// Private method tests
#[test]
fn get_config_contents_ok() {
let result = get_config_contents("tests/fixtures/config_example/config.yml");
assert!(result.is_ok());
assert!(result.unwrap().len() != 0);
}
#[test]
fn get_config_contents_err() {
let result = get_config_contents("tests/fixtures/config_example/config_does_not_exist.yml");
assert!(result.is_err());
}
#[test]
fn parse_yaml_ok() {
let source = "test_source";
let dest = "test_dest";
let posts = "test_posts";
let layouts = "test_layouts";
let file_contents = format!("source: {}\r\ndest: {}\r\nposts: {}\r\nlayouts: {}\r",
source,
dest,
posts,
layouts);
let result = parse_yaml(file_contents);
assert!(result.is_ok());
let doc = result.unwrap();
assert_eq!(doc["source"].as_str(), Some(source));
}
#[test]
fn parse_yaml_err() {
let file_contents = "!@%!\\@#%!\r\n#ASDF@#%".to_string();
let result = parse_yaml(file_contents);
assert!(result.is_err());
}

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<h1>{{ name }}</h1>
{{ content }}
</body>
</html>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>My blog - {{ title }}</title>
</head>
<body>
{{ content }}
</body>
</html>

View file

@ -0,0 +1,10 @@
@extends: posts.tpl
title: My first Blogpost
date: 24/08/2014 at 15:36
---
# {{ title }}
Hey there this is my first blogpost and this is super awesome.
My Blog is lorem ipsum like, yes it is..

View file

@ -0,0 +1,5 @@
dest: ../../target/config_example
layouts: _my_layouts
posts: _my_posts

View file

@ -0,0 +1,7 @@
@extends: default.tpl
---
This is my Index page!
{% for post in posts %}
<a href="_posts/{{post.name}}.html">{{ post.title }}</a>
{% endfor %}

View file

@ -64,3 +64,4 @@ pub fn no_extends_error() {
assert!(err.is_err());
assert_eq!(err.unwrap_err().description(), "No @extends line creating _posts/2014-08-24-my-first-blogpost.md");
}

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>My blog - My first Blogpost</title>
</head>
<body>
<h1 id='my_first_blogpost'>My first Blogpost</h1>
<p>Hey there this is my first blogpost and this is super awesome.</p>
<p>My Blog is lorem ipsum like, yes it is..</p>
</body>
</html>

View file

@ -0,0 +1,5 @@
dest: ../../target/config_example
layouts: _my_layouts
posts: _my_posts

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<h1>index</h1>
This is my Index page!
<a href="_posts/2014-08-24-my-first-blogpost.html">My first Blogpost</a>
</body>
</html>