extern crate clap; extern crate comrak; extern crate fs_extra; #[macro_use] extern crate lazy_static; extern crate regex; extern crate uuid; use std::{env, fs}; use clap::{App, Arg}; use fs_extra::dir; use post::{parse_post, read_posts_dir}; use write::{write_post, write_post_listing}; mod post; mod render; mod write; fn build() { let cwd = env::current_dir().expect("Couldn't read current directory"); match fs::read_dir(cwd.join("public")) { Ok(_) => { fs::remove_dir_all(cwd.join("public")).unwrap(); } Err(_) => {} } fs::create_dir(cwd.join("public")).expect("Couldn't create public directory"); let layout_template = fs::read_to_string(&cwd.join("templates").join("layout.html")) .expect("Couldn't find layout template"); let post_template = fs::read_to_string(cwd.join("templates").join("post.html")) .expect("Couldn't find post template"); let post_listing_template = fs::read_to_string(cwd.join("templates").join("post_listing.html")) .expect("Couldn't find post listing item template"); let post_item_template = fs::read_to_string(cwd.join("templates").join("post_listing_item.html")) .expect("Couldn't find post listing item template"); let post_paths = read_posts_dir(&cwd.join("posts")); let posts = post_paths .into_iter() .map(|path| match path { Ok(p) => { let post = parse_post(p.path()); write_post(&cwd, &layout_template, &post_template, &post); post } Err(err) => panic!(err), }).collect(); write_post_listing( &cwd, &layout_template, &post_listing_template, &post_item_template, &posts, ); fs_extra::copy_items( &vec![cwd.join("css"), cwd.join("js")], cwd.join("public"), &dir::CopyOptions::new(), ).expect("Couldn't copy css/js directories"); } fn new(name: &str) { let cwd = env::current_dir().expect("Couldn't read current directory"); let project_path = cwd.join(name); fs::create_dir(&project_path).expect(&format!("Couldn't create directory '{}'", &name)); for dir in &["posts", "public", "templates", "css", "js"] { fs::create_dir(&project_path.join(&dir)) .expect(&format!("Couldn't create {} directory", &dir)); } fs::write(project_path.join("css").join("style.css"), "") .expect("Couldn't create css/style.css"); fs::write(project_path.join("js").join("index.js"), "").expect("Couldn't create js/index.js"); for file in &["layout", "post_listing", "post", "post_listing_item"] { fs::write( &project_path .join("templates") .join(format!("{}.html", file)), "", ).expect(&format!("Couldn't write templates/{}.html", file)); } } fn main() { let matches = App::new("tlon") .version("0.1.0") .author("Dylan Baker") .about("Highly opinionated static site generator") .arg( Arg::with_name("command") .required(true) .possible_values(&["build", "new"]) .index(1), ).arg( Arg::with_name("name") .required_if("command", "new") .index(2), ).get_matches(); let command = matches.value_of("command").unwrap(); if command == "build" { build(); } else if command == "new" { new(&matches.value_of("name").unwrap()); } } #[cfg(test)] mod tests { #[allow(unused_imports)] use super::*; #[allow(unused_imports)] use uuid::Uuid; #[test] fn test_new() { let temp_dir = env::temp_dir(); env::set_current_dir(&temp_dir).unwrap(); let uuid = Uuid::new_v4().to_string(); let project_dir = temp_dir.join(&uuid); new(&uuid); for dir in &["public", "posts", "templates"] { fs::read_dir(&project_dir.join(dir)).unwrap(); } assert_eq!( "", fs::read_to_string(&project_dir.join("templates").join("post_listing.html")).unwrap() ); assert_eq!( "", fs::read_to_string(&project_dir.join("templates").join("layout.html")).unwrap() ); assert_eq!( "", fs::read_to_string(&project_dir.join("templates").join("post_listing_item.html")) .unwrap() ); assert_eq!( "", fs::read_to_string(&project_dir.join("templates").join("post.html")).unwrap() ); assert_eq!( "", fs::read_to_string(&project_dir.join("css").join("style.css")).unwrap() ); assert_eq!( "", fs::read_to_string(&project_dir.join("js").join("index.js")).unwrap() ); fs::remove_dir_all(project_dir).unwrap(); } }