generate.rs (3400B)
1 use std::path::Path; 2 3 use crate::build_control::Mode; 4 use crate::sdk_generation::{ 5 output::package_outputs, package_matrix::validate_package_matrix, package_metadata, 6 }; 7 8 pub fn generate_all(source_root: &Path, consumer_root: &Path, mode: Mode) -> Result<(), String> { 9 generate_ts(consumer_root, mode)?; 10 generate_package_metadata(source_root, consumer_root, mode) 11 } 12 13 pub fn generate_ts(consumer_root: &Path, mode: Mode) -> Result<(), String> { 14 validate_package_matrix()?; 15 for output in package_outputs()? { 16 for generated_file in output.files() { 17 let path = consumer_root 18 .join(output.spec.package_dir) 19 .join(generated_file.relative_path); 20 crate::sdk_generation::fs::write_or_check(&path, &generated_file.contents, mode)?; 21 } 22 let provenance_file = output.provenance_file(); 23 crate::sdk_generation::fs::write_or_check( 24 &consumer_root.join(&provenance_file.relative_path), 25 &provenance_file.contents, 26 mode, 27 )?; 28 println!("generated TypeScript package {}", output.spec.package_name); 29 } 30 Ok(()) 31 } 32 33 pub fn generate_package_metadata( 34 source_root: &Path, 35 consumer_root: &Path, 36 mode: Mode, 37 ) -> Result<(), String> { 38 validate_package_matrix()?; 39 package_metadata::generate_package_metadata(source_root, consumer_root, mode) 40 } 41 42 #[cfg(test)] 43 mod tests { 44 use std::fs; 45 46 use crate::{ 47 build_control::Mode, 48 sdk_generation::package_matrix::{package_specs, wasm_package_specs}, 49 }; 50 51 use super::generate_all; 52 53 #[test] 54 fn explicit_consumer_generation_round_trips_and_detects_drift() { 55 let source = tempfile::TempDir::new().expect("source fixture"); 56 let consumer = tempfile::TempDir::new().expect("consumer fixture"); 57 fs::write(source.path().join("LICENSE-MIT"), "MIT fixture\n").expect("MIT license"); 58 fs::write(source.path().join("LICENSE-APACHE"), "Apache fixture\n") 59 .expect("Apache license"); 60 for (package_name, package_dir) in package_specs() 61 .iter() 62 .map(|spec| (spec.package_name, spec.package_dir)) 63 .chain( 64 wasm_package_specs() 65 .iter() 66 .map(|spec| (spec.package_name, spec.package_dir)), 67 ) 68 { 69 let directory = consumer.path().join(package_dir); 70 fs::create_dir_all(&directory).expect("package directory"); 71 fs::write( 72 directory.join("package.json"), 73 format!( 74 "{{\n \"name\": \"{package_name}\",\n \"description\": \"Fixture package\"\n}}\n" 75 ), 76 ) 77 .expect("package manifest"); 78 } 79 80 generate_all(source.path(), consumer.path(), Mode::Write).expect("write generation"); 81 generate_all(source.path(), consumer.path(), Mode::Check).expect("fresh generation"); 82 83 let generated = consumer 84 .path() 85 .join(package_specs()[0].package_dir) 86 .join("src/generated/types.ts"); 87 fs::write(&generated, "drift\n").expect("drift generated output"); 88 let error = generate_all(source.path(), consumer.path(), Mode::Check) 89 .expect_err("drift must fail check mode"); 90 assert!(error.contains("stale generated SDK output")); 91 } 92 }