Federated blogging application, thanks to ActivityPub https://joinplu.me
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

149 lines
4.3 KiB

  1. use ructe::Ructe;
  2. use std::process::{Command, Stdio};
  3. use std::{ffi::OsStr, fs::*, io::Write, path::*};
  4. fn compute_static_hash() -> String {
  5. //"find static/ -type f ! -path 'static/media/*' | sort | xargs stat -c'%n %Y' | openssl dgst -r"
  6. let find = Command::new("find")
  7. .args(&["static/", "-type", "f", "!", "-path", "static/media/*"])
  8. .stdout(Stdio::piped())
  9. .spawn()
  10. .expect("failed find command");
  11. let sort = Command::new("sort")
  12. .stdin(find.stdout.unwrap())
  13. .stdout(Stdio::piped())
  14. .spawn()
  15. .expect("failed sort command");
  16. let xargs = Command::new("xargs")
  17. .args(&["stat", "-c'%n %Y'"])
  18. .stdin(sort.stdout.unwrap())
  19. .stdout(Stdio::piped())
  20. .spawn()
  21. .expect("failed xargs command");
  22. let mut sha = Command::new("openssl")
  23. .args(&["dgst", "-r"])
  24. .stdin(xargs.stdout.unwrap())
  25. .output()
  26. .expect("failed openssl command");
  27. sha.stdout.resize(64, 0);
  28. String::from_utf8(sha.stdout).unwrap()
  29. }
  30. fn main() {
  31. Ructe::from_env()
  32. .expect("This must be run with cargo")
  33. .compile_templates("templates")
  34. .expect("compile templates");
  35. compile_themes().expect("Theme compilation error");
  36. recursive_copy(&Path::new("assets").join("icons"), &Path::new("static"))
  37. .expect("Couldn't copy icons");
  38. recursive_copy(&Path::new("assets").join("images"), &Path::new("static"))
  39. .expect("Couldn't copy images");
  40. create_dir_all(&Path::new("static").join("media")).expect("Couldn't init media directory");
  41. let cache_id = &compute_static_hash()[..8];
  42. println!("cargo:rerun-if-changed=plume-front/pkg/plume_front_bg.wasm");
  43. copy(
  44. "plume-front/pkg/plume_front_bg.wasm",
  45. "static/plume_front_bg.wasm",
  46. )
  47. .and_then(|_| copy("plume-front/pkg/plume_front.js", "static/plume_front.js"))
  48. .ok();
  49. println!("cargo:rustc-env=CACHE_ID={}", cache_id)
  50. }
  51. fn compile_themes() -> std::io::Result<()> {
  52. let input_dir = Path::new("assets").join("themes");
  53. let output_dir = Path::new("static").join("css");
  54. let themes = find_themes(input_dir)?;
  55. for theme in themes {
  56. compile_theme(&theme, &output_dir)?;
  57. }
  58. Ok(())
  59. }
  60. fn find_themes(path: PathBuf) -> std::io::Result<Vec<PathBuf>> {
  61. let ext = path.extension().and_then(OsStr::to_str);
  62. if metadata(&path)?.is_dir() {
  63. Ok(read_dir(&path)?.fold(vec![], |mut themes, ch| {
  64. if let Ok(ch) = ch {
  65. if let Ok(mut new) = find_themes(ch.path()) {
  66. themes.append(&mut new);
  67. }
  68. }
  69. themes
  70. }))
  71. } else if (ext == Some("scss") || ext == Some("sass"))
  72. && !path.file_name().unwrap().to_str().unwrap().starts_with('_')
  73. {
  74. Ok(vec![path.clone()])
  75. } else {
  76. Ok(vec![])
  77. }
  78. }
  79. fn compile_theme(path: &Path, out_dir: &Path) -> std::io::Result<()> {
  80. let name = path
  81. .components()
  82. .skip_while(|c| *c != Component::Normal(OsStr::new("themes")))
  83. .skip(1)
  84. .filter_map(|c| {
  85. c.as_os_str()
  86. .to_str()
  87. .unwrap_or_default()
  88. .splitn(2, '.')
  89. .next()
  90. })
  91. .collect::<Vec<_>>()
  92. .join("-");
  93. let dir = path.parent().unwrap();
  94. let out = out_dir.join(name);
  95. create_dir_all(&out)?;
  96. // copy files of the theme that are not scss
  97. for ch in read_dir(&dir)? {
  98. recursive_copy(&ch?.path(), &out)?;
  99. }
  100. // compile the .scss/.sass file
  101. let mut out = File::create(out.join("theme.css"))?;
  102. out.write_all(
  103. &rsass::compile_scss_file(path, rsass::OutputStyle::Compressed)
  104. .expect("SCSS compilation error"),
  105. )?;
  106. Ok(())
  107. }
  108. fn recursive_copy(path: &Path, out_dir: &Path) -> std::io::Result<()> {
  109. if metadata(path)?.is_dir() {
  110. let out = out_dir.join(path.file_name().unwrap());
  111. create_dir_all(out.clone())?;
  112. for ch in read_dir(path)? {
  113. recursive_copy(&ch?.path(), &out)?;
  114. }
  115. } else {
  116. println!("cargo:rerun-if-changed={}", path.display());
  117. let ext = path.extension().and_then(OsStr::to_str);
  118. if ext != Some("scss") && ext != Some("sass") {
  119. copy(path, out_dir.join(path.file_name().unwrap()))?;
  120. }
  121. }
  122. Ok(())
  123. }