This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-lexicons / build.rs
3.1 kB 86 lines
1use std::path::{Path, PathBuf}; 2 3use anyhow::{Context, Result}; 4use jacquard_lexicon::codegen::{CodeGenerator, CodegenMode}; 5use jacquard_lexicon::corpus::LexiconCorpus; 6use walkdir::WalkDir; 7 8const LEXICONS_SUBDIR: &str = "lexicons"; 9const STAGED_SUBDIR: &str = "lexicons-staged"; 10const GENERATED_SUBDIR: &str = "src/_lex"; 11const TEMP_SEGMENT: &str = "temp"; 12 13fn main() -> Result<()> { 14 let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?); 15 let knot_root = manifest_dir 16 .parent() 17 .and_then(Path::parent) 18 .context("resolve knot root from manifest dir")? 19 .to_path_buf(); 20 let workspace_root = knot_root 21 .parent() 22 .context("resolve workspace root from knot root")? 23 .to_path_buf(); 24 25 let lexicons_dir = std::env::var("KNOT_LEXICONS_DIR") 26 .map(PathBuf::from) 27 .unwrap_or_else(|_| workspace_root.join(LEXICONS_SUBDIR)); 28 let vendored_dir = knot_root.join(LEXICONS_SUBDIR); 29 30 println!("cargo:rerun-if-env-changed=KNOT_LEXICONS_DIR"); 31 println!("cargo:rerun-if-changed={}", lexicons_dir.display()); 32 println!("cargo:rerun-if-changed={}", vendored_dir.display()); 33 println!("cargo:rerun-if-changed=build.rs"); 34 35 let out_dir = PathBuf::from(std::env::var("OUT_DIR")?); 36 let staged = out_dir.join(STAGED_SUBDIR); 37 if staged.exists() { 38 std::fs::remove_dir_all(&staged).context("clean staged lexicons")?; 39 } 40 stage_lexicons(&lexicons_dir, &staged)?; 41 stage_lexicons(&vendored_dir, &staged)?; 42 43 let corpus = LexiconCorpus::load_from_dir(&staged) 44 .map_err(|e| anyhow::anyhow!("load lexicon corpus: {e:?}"))?; 45 46 let generated = manifest_dir.join(GENERATED_SUBDIR); 47 if generated.exists() { 48 std::fs::remove_dir_all(&generated).context("clean generated dir")?; 49 } 50 std::fs::create_dir_all(&generated).context("create generated dir")?; 51 52 let codegen = CodeGenerator::with_mode(&corpus, "crate", CodegenMode::Pretty); 53 codegen 54 .write_to_disk(&generated) 55 .map_err(|e| anyhow::anyhow!("write generated code: {e:?}"))?; 56 57 Ok(()) 58} 59 60fn stage_lexicons(src: &Path, dst: &Path) -> Result<()> { 61 WalkDir::new(src) 62 .into_iter() 63 .filter_map(std::result::Result::ok) 64 .filter(|entry| entry.file_type().is_file()) 65 .filter(|entry| { 66 entry 67 .path() 68 .extension() 69 .is_some_and(|ext| ext.eq_ignore_ascii_case("json")) 70 }) 71 .filter(|entry| { 72 !entry 73 .path() 74 .components() 75 .any(|component| component.as_os_str() == TEMP_SEGMENT) 76 }) 77 .try_for_each(|entry| -> Result<()> { 78 let rel = entry.path().strip_prefix(src).context("strip src prefix")?; 79 let target = dst.join(rel); 80 if let Some(parent) = target.parent() { 81 std::fs::create_dir_all(parent).context("create staged parent")?; 82 } 83 std::fs::copy(entry.path(), &target).context("copy lexicon file")?; 84 Ok(()) 85 }) 86}