diff --git a/wasm-rpc-stubgen/src/commands/app.rs b/wasm-rpc-stubgen/src/commands/app.rs index e7c5215bf..3d423413b 100644 --- a/wasm-rpc-stubgen/src/commands/app.rs +++ b/wasm-rpc-stubgen/src/commands/app.rs @@ -130,10 +130,17 @@ impl ApplicationContext { .common_wit_deps .get_or_init(|| { let sources = self.application.wit_deps(); - if sources.is_empty() { + if sources.value.is_empty() { bail!("No common witDeps were defined in the application manifest") } - WitDepsResolver::new(sources) + WitDepsResolver::new( + sources + .value + .iter() + .cloned() + .map(|path| sources.source.join(path)) + .collect(), + ) }) .as_ref() { @@ -233,7 +240,11 @@ fn componentize( let _indent = LogIndent::new(); for build_step in &component_properties.build { - execute_external_command(ctx, component_name, build_step)?; + execute_external_command( + ctx, + ctx.application.component_source_dir(component_name), + build_step, + )?; } } @@ -433,11 +444,21 @@ pub fn clean(config: Config) -> anyhow: } } + { + log_action("Cleaning", "common clean targets"); + let _indent = LogIndent::new(); + + let common_clean = app.common_clean(); + for path in &common_clean.value { + delete_path("common clean target", &common_clean.source.join(path))?; + } + } + { log_action("Cleaning", "application build dir"); let _indent = LogIndent::new(); - delete_path("temp dir", app.temp_dir())?; + delete_path("temp dir", &app.temp_dir())?; } Ok(()) @@ -511,6 +532,19 @@ pub fn custom_command( ); let _indent = LogIndent::new(); + let common_custom_commands = ctx.application.common_custom_commands(); + if let Some(custom_command) = common_custom_commands.value.get(command) { + log_action( + "Executing", + format!("common custom command {}", command.log_color_highlight(),), + ); + let _indent = LogIndent::new(); + + for step in custom_command { + execute_external_command(&ctx, &common_custom_commands.source, step)?; + } + } + for component_name in ctx.application.component_names() { let properties = &ctx .application @@ -527,7 +561,11 @@ pub fn custom_command( let _indent = LogIndent::new(); for step in custom_command { - execute_external_command(&ctx, component_name, step)?; + execute_external_command( + &ctx, + ctx.application.component_source_dir(component_name), + step, + )?; } } } @@ -1449,22 +1487,14 @@ fn copy_wit_sources(source: &Path, target: &Path) -> anyhow::Result<()> { fn execute_external_command( ctx: &ApplicationContext, - component_name: &ComponentName, + base_build_dir: &Path, command: &app_raw::ExternalCommand, ) -> anyhow::Result<()> { let build_dir = command .dir .as_ref() - .map(|dir| { - ctx.application - .component_source_dir(component_name) - .join(dir) - }) - .unwrap_or_else(|| { - ctx.application - .component_source_dir(component_name) - .to_path_buf() - }); + .map(|dir| base_build_dir.join(dir)) + .unwrap_or_else(|| base_build_dir.to_path_buf()); let task_result_marker = TaskResultMarker::new( &ctx.application.task_result_marker_dir(), diff --git a/wasm-rpc-stubgen/src/model/app.rs b/wasm-rpc-stubgen/src/model/app.rs index d3c226b9f..3dc45ccad 100644 --- a/wasm-rpc-stubgen/src/model/app.rs +++ b/wasm-rpc-stubgen/src/model/app.rs @@ -139,13 +139,36 @@ pub struct ComponentEffectivePropertySource<'a> { pub any_template_overrides: bool, } +#[derive(Clone, Debug)] +pub struct WithSource { + pub source: PathBuf, + pub value: T, +} + +impl WithSource { + pub fn new(source: PathBuf, value: T) -> Self { + Self { source, value } + } +} + +impl Default for WithSource { + fn default() -> Self { + Self { + source: Default::default(), + value: T::default(), + } + } +} + #[derive(Clone, Debug)] pub struct Application { - temp_dir: Option, - wit_deps: Vec, + temp_dir: Option>, + wit_deps: WithSource>, components: BTreeMap>, dependencies: BTreeMap>, no_dependencies: BTreeSet, + custom_commands: WithSource>>, + clean: WithSource>, } impl Application { @@ -161,8 +184,18 @@ impl Application { self.components.contains_key(component_name) } - pub fn wit_deps(&self) -> Vec { - self.wit_deps.iter().map(PathBuf::from).collect() + pub fn common_custom_commands( + &self, + ) -> &WithSource>> { + &self.custom_commands + } + + pub fn common_clean(&self) -> &WithSource> { + &self.clean + } + + pub fn wit_deps(&self) -> &WithSource> { + &self.wit_deps } pub fn all_wasm_rpc_dependencies(&self) -> BTreeSet { @@ -186,20 +219,21 @@ impl Application { } pub fn all_custom_commands(&self, profile: Option<&ProfileName>) -> BTreeSet { - self.component_names() - .flat_map(|component_name| { - self.component_properties(component_name, profile) - .custom_commands - .keys() - .cloned() - }) - .collect() + let mut custom_commands = BTreeSet::new(); + custom_commands.extend(self.component_names().flat_map(|component_name| { + self.component_properties(component_name, profile) + .custom_commands + .keys() + .cloned() + })); + custom_commands.extend(self.custom_commands.value.keys().cloned()); + custom_commands } - pub fn temp_dir(&self) -> &Path { + pub fn temp_dir(&self) -> PathBuf { match self.temp_dir.as_ref() { - Some(temp_dir) => Path::new(temp_dir), - None => Path::new("golem-temp"), + Some(temp_dir) => temp_dir.source.as_path().join(&temp_dir.value), + None => Path::new("golem-temp").to_path_buf(), } } @@ -637,10 +671,11 @@ impl ComponentPropertiesExtensions for ComponentPropertiesExtensionsAny { } mod app_builder { + use crate::fs::PathExtra; use crate::log::LogColorize; use crate::model::app::{ Application, Component, ComponentName, ComponentProperties, ComponentPropertiesExtensions, - ProfileName, ResolvedComponentProperties, TemplateName, + ProfileName, ResolvedComponentProperties, TemplateName, WithSource, }; use crate::model::app_raw; use crate::validation::{ValidatedResult, ValidationBuilder}; @@ -664,6 +699,8 @@ mod app_builder { Include, TempDir, WitDeps, + CustomCommands, + Clean, Template(TemplateName), WasmRpcDependency((ComponentName, ComponentName)), Component(ComponentName), @@ -676,6 +713,8 @@ mod app_builder { UniqueSourceCheckedEntityKey::Include => property, UniqueSourceCheckedEntityKey::TempDir => property, UniqueSourceCheckedEntityKey::WitDeps => property, + UniqueSourceCheckedEntityKey::CustomCommands => property, + UniqueSourceCheckedEntityKey::Clean => property, UniqueSourceCheckedEntityKey::Template(_) => "Template", UniqueSourceCheckedEntityKey::WasmRpcDependency(_) => "WASM RPC dependency", UniqueSourceCheckedEntityKey::Component(_) => "Component", @@ -693,6 +732,10 @@ mod app_builder { UniqueSourceCheckedEntityKey::WitDeps => { "witDeps".log_color_highlight().to_string() } + UniqueSourceCheckedEntityKey::CustomCommands => { + "customCommands".log_color_highlight().to_string() + } + UniqueSourceCheckedEntityKey::Clean => "clean".log_color_highlight().to_string(), UniqueSourceCheckedEntityKey::Template(template_name) => { template_name.as_str().log_color_highlight().to_string() } @@ -716,17 +759,16 @@ mod app_builder { #[derive(Default)] struct AppBuilder { include: Vec, - temp_dir: Option, - wit_deps: Vec, - + temp_dir: Option>, + wit_deps: WithSource>, templates: HashMap, dependencies: BTreeMap>, - + custom_commands: WithSource>>, + clean: WithSource>, raw_components: HashMap, + resolved_components: BTreeMap>, entity_sources: HashMap>, - - resolved_components: BTreeMap>, } impl AppBuilder { @@ -744,6 +786,8 @@ mod app_builder { components: builder.resolved_components, dependencies: builder.dependencies, no_dependencies: BTreeSet::new(), + custom_commands: builder.custom_commands, + clean: builder.clean, }) } @@ -772,25 +816,31 @@ mod app_builder { validation.with_context( vec![("source", app.source.to_string_lossy().to_string())], |validation| { + let app_source = PathExtra::new(&app.source); + let app_source_dir = app_source.parent().unwrap(); + if let Some(dir) = app.application.temp_dir { - self.add_entity_source(UniqueSourceCheckedEntityKey::TempDir, &app.source); - if self.temp_dir.is_none() { - self.temp_dir = Some(dir); + if self + .add_entity_source(UniqueSourceCheckedEntityKey::TempDir, &app.source) + { + self.temp_dir = + Some(WithSource::new(app_source_dir.to_path_buf(), dir)); } } - if !app.application.includes.is_empty() { - self.add_entity_source(UniqueSourceCheckedEntityKey::Include, &app.source); - if self.include.is_empty() { - self.include = app.application.includes; - } + if !app.application.includes.is_empty() + && self + .add_entity_source(UniqueSourceCheckedEntityKey::Include, &app.source) + { + self.include = app.application.includes; } - if !app.application.wit_deps.is_empty() { - self.add_entity_source(UniqueSourceCheckedEntityKey::WitDeps, &app.source); - if self.wit_deps.is_empty() { - self.wit_deps = app.application.wit_deps; // TODO: resolve from source? - } + if !app.application.wit_deps.is_empty() + && self + .add_entity_source(UniqueSourceCheckedEntityKey::WitDeps, &app.source) + { + self.wit_deps = + WithSource::new(app_source_dir.to_path_buf(), app.application.wit_deps); } for (template_name, template) in app.application.templates { @@ -815,6 +865,25 @@ mod app_builder { component_dependencies, ); } + + if !app.application.custom_commands.is_empty() + && self.add_entity_source( + UniqueSourceCheckedEntityKey::CustomCommands, + &app.source, + ) + { + self.custom_commands = WithSource::new( + app_source_dir.to_path_buf(), + app.application.custom_commands, + ) + } + + if !app.application.clean.is_empty() + && self.add_entity_source(UniqueSourceCheckedEntityKey::Clean, &app.source) + { + self.clean = + WithSource::new(app_source_dir.to_path_buf(), app.application.clean); + } }, ); } diff --git a/wasm-rpc-stubgen/src/model/app_raw.rs b/wasm-rpc-stubgen/src/model/app_raw.rs index 569bbfabc..ef0c7e476 100644 --- a/wasm-rpc-stubgen/src/model/app_raw.rs +++ b/wasm-rpc-stubgen/src/model/app_raw.rs @@ -44,6 +44,10 @@ pub struct Application { pub components: HashMap, #[serde(default, skip_serializing_if = "HashMap::is_empty")] pub dependencies: HashMap>, + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + pub custom_commands: HashMap>, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub clean: Vec, } impl Application { diff --git a/wasm-rpc-stubgen/src/wit_resolve.rs b/wasm-rpc-stubgen/src/wit_resolve.rs index a5285061a..df4dabc79 100644 --- a/wasm-rpc-stubgen/src/wit_resolve.rs +++ b/wasm-rpc-stubgen/src/wit_resolve.rs @@ -697,7 +697,7 @@ impl WitDepsResolver { for source in &sources { packages.insert( - source.clone(), + source.to_path_buf().clone(), parse_wit_deps_dir(source)? .into_iter() .map(|package| (package.main.name.clone(), package))