A static site generator written in Rust
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

main.rs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. extern crate clap;
  2. extern crate comrak;
  3. extern crate fs_extra;
  4. #[macro_use]
  5. extern crate lazy_static;
  6. extern crate regex;
  7. extern crate uuid;
  8. use std::{env, fs};
  9. use clap::{App, Arg};
  10. use fs_extra::dir;
  11. use post::{parse_post, read_posts_dir};
  12. use write::{write_post, write_post_listing};
  13. mod post;
  14. mod render;
  15. mod write;
  16. fn build() {
  17. let cwd = env::current_dir().expect("Couldn't read current directory");
  18. match fs::read_dir(cwd.join("public")) {
  19. Ok(_) => {
  20. fs::remove_dir_all(cwd.join("public")).unwrap();
  21. }
  22. Err(_) => {}
  23. }
  24. fs::create_dir(cwd.join("public")).expect("Couldn't create public directory");
  25. let layout_template = fs::read_to_string(&cwd.join("templates").join("layout.html"))
  26. .expect("Couldn't find layout template");
  27. let post_template = fs::read_to_string(cwd.join("templates").join("post.html"))
  28. .expect("Couldn't find post template");
  29. let post_listing_template = fs::read_to_string(cwd.join("templates").join("post_listing.html"))
  30. .expect("Couldn't find post listing item template");
  31. let post_item_template =
  32. fs::read_to_string(cwd.join("templates").join("post_listing_item.html"))
  33. .expect("Couldn't find post listing item template");
  34. let post_paths = read_posts_dir(&cwd.join("posts"));
  35. let posts = post_paths
  36. .into_iter()
  37. .map(|path| match path {
  38. Ok(p) => {
  39. let post = parse_post(p.path());
  40. write_post(&cwd, &layout_template, &post_template, &post);
  41. post
  42. }
  43. Err(err) => panic!(err),
  44. }).collect();
  45. write_post_listing(
  46. &cwd,
  47. &layout_template,
  48. &post_listing_template,
  49. &post_item_template,
  50. &posts,
  51. );
  52. fs_extra::copy_items(
  53. &vec![cwd.join("css"), cwd.join("js")],
  54. cwd.join("public"),
  55. &dir::CopyOptions::new(),
  56. ).expect("Couldn't copy css/js directories");
  57. }
  58. fn new(name: &str) {
  59. let cwd = env::current_dir().expect("Couldn't read current directory");
  60. let project_path = cwd.join(name);
  61. fs::create_dir(&project_path).expect(&format!("Couldn't create directory '{}'", &name));
  62. for dir in &["posts", "public", "templates", "css", "js"] {
  63. fs::create_dir(&project_path.join(&dir))
  64. .expect(&format!("Couldn't create {} directory", &dir));
  65. }
  66. fs::write(project_path.join("css").join("style.css"), "")
  67. .expect("Couldn't create css/style.css");
  68. fs::write(project_path.join("js").join("index.js"), "").expect("Couldn't create js/index.js");
  69. for file in &["layout", "post_listing", "post", "post_listing_item"] {
  70. fs::write(
  71. &project_path
  72. .join("templates")
  73. .join(format!("{}.html", file)),
  74. "",
  75. ).expect(&format!("Couldn't write templates/{}.html", file));
  76. }
  77. }
  78. fn main() {
  79. let matches = App::new("tlon")
  80. .version("0.1.0")
  81. .author("Dylan Baker")
  82. .about("Highly opinionated static site generator")
  83. .arg(
  84. Arg::with_name("command")
  85. .required(true)
  86. .possible_values(&["build", "new"])
  87. .index(1),
  88. ).arg(
  89. Arg::with_name("name")
  90. .required_if("command", "new")
  91. .index(2),
  92. ).get_matches();
  93. let command = matches.value_of("command").unwrap();
  94. if command == "build" {
  95. build();
  96. } else if command == "new" {
  97. new(&matches.value_of("name").unwrap());
  98. }
  99. }
  100. #[cfg(test)]
  101. mod tests {
  102. #[allow(unused_imports)]
  103. use super::*;
  104. #[allow(unused_imports)]
  105. use uuid::Uuid;
  106. #[test]
  107. fn test_new() {
  108. let temp_dir = env::temp_dir();
  109. env::set_current_dir(&temp_dir).unwrap();
  110. let uuid = Uuid::new_v4().to_string();
  111. let project_dir = temp_dir.join(&uuid);
  112. new(&uuid);
  113. for dir in &["public", "posts", "templates"] {
  114. fs::read_dir(&project_dir.join(dir)).unwrap();
  115. }
  116. assert_eq!(
  117. "",
  118. fs::read_to_string(&project_dir.join("templates").join("post_listing.html")).unwrap()
  119. );
  120. assert_eq!(
  121. "",
  122. fs::read_to_string(&project_dir.join("templates").join("layout.html")).unwrap()
  123. );
  124. assert_eq!(
  125. "",
  126. fs::read_to_string(&project_dir.join("templates").join("post_listing_item.html"))
  127. .unwrap()
  128. );
  129. assert_eq!(
  130. "",
  131. fs::read_to_string(&project_dir.join("templates").join("post.html")).unwrap()
  132. );
  133. assert_eq!(
  134. "",
  135. fs::read_to_string(&project_dir.join("css").join("style.css")).unwrap()
  136. );
  137. assert_eq!(
  138. "",
  139. fs::read_to_string(&project_dir.join("js").join("index.js")).unwrap()
  140. );
  141. fs::remove_dir_all(project_dir).unwrap();
  142. }
  143. }