@@ -317,7 +317,7 @@ pub struct Component {
317
317
///
318
318
/// `environment = { DB_URL = "mysql://spin:spin@localhost/dev" }`
319
319
#[ serde( default , skip_serializing_if = "Map::is_empty" ) ]
320
- pub environment : Map < String , String > ,
320
+ pub ( crate ) environment : Map < String , String > ,
321
321
/// The files the component is allowed to read. Each list entry is either:
322
322
///
323
323
/// - a glob pattern (e.g. "assets/**/*.jpg"); or
@@ -413,7 +413,7 @@ pub struct Component {
413
413
///
414
414
/// Learn more: https://spinframework.dev/writing-apps#using-component-dependencies
415
415
#[ serde( default , skip_serializing_if = "ComponentDependencies::is_empty" ) ]
416
- pub dependencies : ComponentDependencies ,
416
+ pub ( crate ) dependencies : ComponentDependencies ,
417
417
/// Override values to use when building or running a named build profile.
418
418
///
419
419
/// Example: `profile.debug.build.command = "npm run build-debug"`
@@ -433,6 +433,22 @@ pub struct ComponentProfileOverride {
433
433
#[ serde( default , skip_serializing_if = "Option::is_none" ) ]
434
434
source : Option < ComponentSource > ,
435
435
436
+ /// Environment variables for the Wasm module to be overridden in this profile.
437
+ /// Environment variables specified in the default profile will still be set
438
+ /// if not overridden here.
439
+ ///
440
+ /// `environment = { DB_URL = "mysql://spin:spin@localhost/dev" }`
441
+ #[ serde( default , skip_serializing_if = "Map::is_empty" ) ]
442
+ environment : Map < String , String > ,
443
+
444
+ /// Wasm Component Model imports to be overridden in this profile.
445
+ /// Dependencies specified in the default profile will still be composed
446
+ /// if not overridden here.
447
+ ///
448
+ /// Learn more: https://spinframework.dev/writing-apps#using-component-dependencies
449
+ #[ serde( default , skip_serializing_if = "ComponentDependencies::is_empty" ) ]
450
+ dependencies : ComponentDependencies ,
451
+
436
452
/// The command or commands for building the component in non-default profiles.
437
453
/// If a component has no special build instructions for a profile, the
438
454
/// default build command is used.
@@ -502,6 +518,36 @@ impl Component {
502
518
None => & self . source ,
503
519
}
504
520
}
521
+
522
+ /// The component's environment variables
523
+ pub fn environment ( & self , profile : Option < & str > ) -> Map < String , String > {
524
+ let mut environment = self . environment . clone ( ) ;
525
+
526
+ let Some ( overrides) = self . profile ( profile) . map ( |o| o. environment . clone ( ) ) else {
527
+ return environment;
528
+ } ;
529
+
530
+ for ( name, value) in overrides {
531
+ environment. insert ( name, value) ;
532
+ }
533
+
534
+ environment
535
+ }
536
+
537
+ /// The component's dependencies
538
+ pub fn dependencies ( & self , profile : Option < & str > ) -> ComponentDependencies {
539
+ let mut dependencies = self . dependencies . clone ( ) ;
540
+
541
+ let Some ( overrides) = self . profile ( profile) . map ( |o| o. dependencies . clone ( ) ) else {
542
+ return dependencies;
543
+ } ;
544
+
545
+ for ( itf, dep) in overrides. inner {
546
+ dependencies. inner . insert ( itf, dep) ;
547
+ }
548
+
549
+ dependencies
550
+ }
505
551
}
506
552
507
553
/// Component dependencies
@@ -1225,4 +1271,53 @@ mod tests {
1225
1271
. commands( ) [ 1 ]
1226
1272
) ;
1227
1273
}
1274
+
1275
+ #[ test]
1276
+ fn profiles_override_env_vars ( ) {
1277
+ let manifest = AppManifest :: deserialize ( toml ! {
1278
+ spin_manifest_version = 2
1279
+ [ application]
1280
+ name = "trigger-configs"
1281
+ [ [ trigger. fake] ]
1282
+ component = "profile-test"
1283
+ [ component. profile-test]
1284
+ source = "original"
1285
+ environment = { DB_URL = "pg://production" }
1286
+ [ component. profile-test. profile. fancy]
1287
+ environment = { DB_URL = "pg://fancy" , FANCINESS = "1" }
1288
+ } )
1289
+ . expect ( "manifest should be valid" ) ;
1290
+
1291
+ let id = KebabId :: try_from ( "profile-test" . to_owned ( ) )
1292
+ . expect ( "profile-test should have been kebab" ) ;
1293
+ let component = manifest
1294
+ . components
1295
+ . get ( & id)
1296
+ . expect ( "should have compopnent with id profile-test" ) ;
1297
+
1298
+ assert_eq ! ( 1 , component. environment( None ) . len( ) ) ;
1299
+ assert_eq ! (
1300
+ "pg://production" ,
1301
+ component
1302
+ . environment( None )
1303
+ . get( "DB_URL" )
1304
+ . expect( "DB_URL should have been set" )
1305
+ ) ;
1306
+
1307
+ assert_eq ! ( 2 , component. environment( Some ( "fancy" ) ) . len( ) ) ;
1308
+ assert_eq ! (
1309
+ "pg://fancy" ,
1310
+ component
1311
+ . environment( Some ( "fancy" ) )
1312
+ . get( "DB_URL" )
1313
+ . expect( "DB_URL should have been set" )
1314
+ ) ;
1315
+ assert_eq ! (
1316
+ "1" ,
1317
+ component
1318
+ . environment( Some ( "fancy" ) )
1319
+ . get( "FANCINESS" )
1320
+ . expect( "FANCINESS should have been set" )
1321
+ ) ;
1322
+ }
1228
1323
}
0 commit comments