diff --git a/lib/CPAN/Meta/Merge.pm b/lib/CPAN/Meta/Merge.pm index b484e8c..66e7a1a 100644 --- a/lib/CPAN/Meta/Merge.pm +++ b/lib/CPAN/Meta/Merge.pm @@ -81,8 +81,16 @@ sub _optional_features { $left->{$key} = $right->{$key}; } else { - Carp::croak "Cannot merge two optional_features named '$key' with different descriptions" - if do { no warnings 'uninitialized'; $left->{$key}{description} ne $right->{$key}{description} }; + for my $subkey (keys %{ $right->{$key} }) { + next if $subkey eq 'prereqs'; + if (not exists $left->{$key}{$subkey}) { + $left->{$key}{$subkey} = $right->{$key}{$subkey}; + } + else { + Carp::croak "Cannot merge two optional_features named '$key' with different '$subkey' values" + if do { no warnings 'uninitialized'; $left->{$key}{$subkey} ne $right->{$key}{$subkey} }; + } + } require CPAN::Meta::Prereqs; $left->{$key}{prereqs} = diff --git a/t/optional_feature-merge.t b/t/optional_feature-merge.t index c11bc5f..15aa621 100644 --- a/t/optional_feature-merge.t +++ b/t/optional_feature-merge.t @@ -37,6 +37,7 @@ my $fragment1 = { 'optional_features' => { 'FeatureName' => { 'description' => 'desc', + 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } } } } @@ -71,6 +72,7 @@ is_deeply( 'optional_features' => { 'FeatureName' => { 'description' => 'desc', + 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } }, 'test' => { 'requires' => { 'B' => '0' } }, @@ -90,11 +92,25 @@ my $fragment3 = { } }; -my $failure = eval { $merger->merge($meta1, $fragment3) }; -is($failure, undef, 'Trying to merge optional_features with same feature name and different descriptions gives an exception'); -like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different descriptions/, 'Exception looks right'; +my $result = eval { $merger->merge($meta1, $fragment3) }; +is($result, undef, 'Trying to merge optional_features with same feature name and different descriptions gives an exception'); +like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'description' values/, 'Exception looks right'; my $fragment4 = { + 'optional_features' => { + 'FeatureName' => { + 'description' => 'desc', + 'x_default' => 0, + 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } + } + } +}; + +$result = eval { $merger->merge($meta1, $fragment4) }; +is($result, undef, 'Trying to merge optional_features with same feature name and differences in other keys gives an exception'); +like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'x_default' values/, 'Exception looks right'; + +my $fragment5 = { 'optional_features' => { 'Another FeatureName' => { 'description' => 'desc', @@ -103,14 +119,15 @@ my $fragment4 = { } }; -my $meta4 = $merger->merge($meta1, $fragment4); +my $meta5 = $merger->merge($meta1, $fragment5); is_deeply( - $meta4, + $meta5, { %base, 'optional_features' => { 'FeatureName' => { 'description' => 'desc', + 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } }, }, 'Another FeatureName' => {