@@ -298,12 +298,21 @@ impl<'p> Environment<'p> {
298298 /// The environment variables of all features are combined in the order they
299299 /// are defined for the environment.
300300 pub ( crate ) fn activation_env ( & self , platform : Option < Platform > ) -> IndexMap < String , String > {
301- self . features ( )
302- . map ( |f| f. activation_env ( platform) )
303- . fold ( IndexMap :: new ( ) , |mut acc, env| {
301+ // As self.features() would put "default" envs in the last item, but the "default" env priority should be the lowest.
302+ // Here, we use rfold (reverse fold) to ensure later features override earlier features
303+ // for environment variables. Processing features in reverse order means that
304+ // features appearing later in the list will have higher precedence.
305+ //
306+ // Example: If features: [override_feature, user_feature, default]
307+ // - rfold processes as: [default, user_feature, override_feature]
308+ // - Result: override_feature env vars take precedence over all others
309+ self . features ( ) . map ( |f| f. activation_env ( platform) ) . rfold (
310+ IndexMap :: new ( ) ,
311+ |mut acc, env| {
304312 acc. extend ( env. iter ( ) . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) ) ) ;
305313 acc
306- } )
314+ } ,
315+ )
307316 }
308317
309318 /// Validates that the given platform is supported by this environment.
@@ -652,6 +661,58 @@ mod tests {
652661 ) ;
653662 }
654663
664+ #[ test]
665+ fn test_activation_env_priority ( ) {
666+ let manifest = Workspace :: from_str (
667+ Path :: new ( "pixi.toml" ) ,
668+ r#"
669+ [project]
670+ name = "foobar"
671+ channels = []
672+ platforms = ["linux-64", "osx-64"]
673+
674+ [activation.env]
675+ FOO_VAR = "default"
676+
677+ [feature.foo.activation.env]
678+ FOO_VAR = "foo"
679+
680+ [feature.cuda1.activation.env]
681+ FOO_VAR = "cuda1"
682+
683+ [feature.cuda2.activation.env]
684+ FOO_VAR = "cuda2"
685+
686+ [environments]
687+ foo = ["foo"]
688+ cuda = ["cuda1", "cuda2"]
689+ "# ,
690+ )
691+ . unwrap ( ) ;
692+
693+ let default_env = manifest. default_environment ( ) ;
694+ let foo_env = manifest. environment ( "foo" ) . unwrap ( ) ;
695+ let cuda_env = manifest. environment ( "cuda" ) . unwrap ( ) ;
696+ assert_eq ! (
697+ default_env. activation_env( None ) ,
698+ indexmap! {
699+ "FOO_VAR" . to_string( ) => "default" ,
700+ }
701+ ) ;
702+ assert_eq ! (
703+ foo_env. activation_env( None ) ,
704+ indexmap! {
705+ "FOO_VAR" . to_string( ) => "foo" ,
706+ }
707+ ) ;
708+ assert_eq ! (
709+ cuda_env. activation_env( None ) ,
710+ indexmap! {
711+ "FOO_VAR" . to_string( ) => "cuda1" ,
712+ }
713+ ) ;
714+ }
715+
655716 #[ test]
656717 fn test_channel_feature_priority ( ) {
657718 let manifest = Workspace :: from_str (
0 commit comments