Skip to content

Commit 411f876

Browse files
updaet avocado build to support multiple runtimes sharing extensions
1 parent 45b6e16 commit 411f876

1 file changed

Lines changed: 52 additions & 2 deletions

File tree

src/commands/build.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ echo "Successfully created image for versioned extension '$EXT_NAME-$EXT_VERSION
10711071
"Step 1/4: Analyzing runtime dependencies",
10721072
OutputLevel::Normal,
10731073
);
1074-
let required_extensions = self.find_extensions_for_runtime(config, &runtime_config)?;
1074+
let required_extensions = self.find_extensions_for_runtime(config, parsed, &runtime_config, target)?;
10751075

10761076
// Note: SDK compile sections are now compiled on-demand when extensions are built
10771077
// This prevents duplicate compilation when sdk.compile sections are also extension dependencies
@@ -1252,12 +1252,62 @@ echo "Successfully created image for versioned extension '$EXT_NAME-$EXT_VERSION
12521252
fn find_extensions_for_runtime(
12531253
&self,
12541254
config: &Config,
1255+
parsed: &serde_yaml::Value,
12551256
runtime_config: &serde_yaml::Value,
1257+
target: &str,
12561258
) -> Result<Vec<ExtensionDependency>> {
1259+
use crate::utils::interpolation::interpolate_name;
1260+
12571261
let mut required_extensions = HashSet::new();
12581262
let mut visited = HashSet::new();
12591263

1260-
// Check runtime dependencies for extensions
1264+
// Build a map of interpolated ext names to their source config
1265+
// This is needed because ext section keys may contain templates like {{ avocado.target }}
1266+
let mut ext_sources: std::collections::HashMap<String, Option<ExtensionSource>> =
1267+
std::collections::HashMap::new();
1268+
if let Some(ext_section) = parsed.get("extensions").and_then(|e| e.as_mapping()) {
1269+
for (ext_key, ext_config) in ext_section {
1270+
if let Some(raw_name) = ext_key.as_str() {
1271+
// Interpolate the extension name with the target
1272+
let interpolated_name = interpolate_name(raw_name, target);
1273+
// Use parse_extension_source which properly deserializes the source field
1274+
let source = Config::parse_extension_source(&interpolated_name, ext_config)
1275+
.ok()
1276+
.flatten();
1277+
ext_sources.insert(interpolated_name, source);
1278+
}
1279+
}
1280+
}
1281+
1282+
// Check extensions from the new `extensions` array format
1283+
if let Some(extensions) = runtime_config.get("extensions").and_then(|e| e.as_sequence()) {
1284+
for ext in extensions {
1285+
if let Some(ext_name) = ext.as_str() {
1286+
// Check if this extension has a source: field (remote extension)
1287+
if let Some(Some(source)) = ext_sources.get(ext_name) {
1288+
// Remote extension with source field
1289+
required_extensions.insert(ExtensionDependency::Remote {
1290+
name: ext_name.to_string(),
1291+
source: source.clone(),
1292+
});
1293+
} else {
1294+
// Local extension (defined in ext section without source, or not in ext section)
1295+
required_extensions.insert(ExtensionDependency::Local(ext_name.to_string()));
1296+
1297+
// Also check local extension dependencies
1298+
self.find_local_extension_dependencies(
1299+
config,
1300+
parsed,
1301+
ext_name,
1302+
&mut required_extensions,
1303+
&mut visited,
1304+
)?;
1305+
}
1306+
}
1307+
}
1308+
}
1309+
1310+
// Check runtime dependencies for extensions (old packages format for backwards compatibility)
12611311
if let Some(dependencies) = runtime_config.get("packages").and_then(|d| d.as_mapping()) {
12621312
for (_dep_name, dep_spec) in dependencies {
12631313
// Check for extension dependency

0 commit comments

Comments
 (0)