Author: dagolden
Date: Thu Nov 12 15:30:49 2009
New Revision: 13493

Modified:
   Module-Build/trunk/Changes
   Module-Build/trunk/lib/Module/Build/Compat.pm
   Module-Build/trunk/t/compat.t

Log:
fix merging requires and build_requires in M::B::Compat

Modified: Module-Build/trunk/Changes
==============================================================================
--- Module-Build/trunk/Changes  (original)
+++ Module-Build/trunk/Changes  Thu Nov 12 15:30:49 2009
@@ -13,6 +13,14 @@
 
  Bug fixes:
 
+ - Merging 'requires' and 'build_requires' in Module::Build::Compat could
+   lead to duplicate PREREQ_PM entries; now the highest version is used
+   for PREREQ_PM. (RT#50948) [David Golden]
+
+ - Module::Build::Compat will now die with an error if advanced,
+   non-numeric prerequisites are given, as these are not supported by
+   ExtUtils::MakeMaker in PREREQ_PM [David Golden]
+   
  - Made MYMETA generation non-fatal if fields required for META.yml 
    are missing [David Golden]
 

Modified: Module-Build/trunk/lib/Module/Build/Compat.pm
==============================================================================
--- Module-Build/trunk/lib/Module/Build/Compat.pm       (original)
+++ Module-Build/trunk/lib/Module/Build/Compat.pm       Thu Nov 12 15:30:49 2009
@@ -64,7 +64,33 @@
 # "LIB=foo make" is not the same as "perl Makefile.PL LIB=foo"
 delete $macro_to_build{LIB};
 
+sub _simple_prereq {
+  return $_[0] =~ /^[0-9_]+\.?[0-9_]*$/; # crudly, a decimal literal
+}
 
+sub _merge_prereq {
+  my ($req, $breq) = @_;
+  $req ||= {};
+  $breq ||= {};
+
+  # validate formats
+  for my $p ( $req, $breq ) {
+    for my $k (keys %$p) {
+      die "Prereq '$p->{$k}' for '$k' is not supported by 
Module::Build::Compat\n"
+        unless _simple_prereq($p->{$k});
+    }
+  }
+  # merge
+  my $merge = { %$req };
+  for my $k ( keys %$breq ) {
+    my $v1 = $merge->{$k} || 0;
+    my $v2 = $breq->{$k};
+    $merge->{$k} = $v1 > $v2 ? $v1 : $v2;
+  }
+  return %$merge;
+}
+    
+    
 sub create_makefile_pl {
   my ($package, $type, $build, %args) = @_;
   
@@ -187,7 +213,7 @@
                  );
     %MM_Args = (%name, %version);
     
-    %prereq = ( %{$build->requires}, %{$build->build_requires} );
+    %prereq = _merge_prereq( $build->requires, $build->build_requires );
     %prereq = map {$_, $prereq{$_}} sort keys %prereq;
     
      delete $prereq{perl};

Modified: Module-Build/trunk/t/compat.t
==============================================================================
--- Module-Build/trunk/t/compat.t       (original)
+++ Module-Build/trunk/t/compat.t       Thu Nov 12 15:30:49 2009
@@ -26,6 +26,7 @@
 my $is_vms_mms = ($^O eq 'VMS') && ($Config{make} =~ /MM[SK]/i);
 
 blib_load('Module::Build');
+blib_load('Module::Build::Version');
 
 
 #########################
@@ -71,10 +72,11 @@
   license             => 'perl',
   requires            => {
     'perl'        => $],
-    'File::Spec'  => 0,
+    'File::Spec'  => 0.2,
   },
-  build_requires      => {
-    'Test::More'  => 0,
+  build_requires => {
+      'Test::More' => 0,
+      'File::Spec' => 0,
   },
   PL_files            => { 'foo.PL' => 'foo' },
 });
@@ -89,8 +91,11 @@
 test_makefile_types(
     requires => {
         'perl' => $],
-        'File::Spec' => 0,
+        'File::Spec' => 0.2,
+    },
+    build_requires => {
         'Test::More' => 0,
+        'File::Spec' => 0,
     },
     PL_files => {
         'foo.PL' => 'foo',
@@ -314,9 +319,25 @@
 
 #########################################################
 
+sub _merge_prereqs {
+  my ($first, $second) = @_;
+  my $new = { %$first };
+  for my $k (keys %$second) {
+    if ( exists $new->{$k} ) {
+      my ($v1,$v2) = ($new->{$k},$second->{$k});
+      $new->{$k} = ($v1 > $v2 ? $v1 : $v2);
+    }
+    else {
+      $new->{$k} = $second->{$k};
+    }
+  }
+  return $new;
+}
+
 sub test_makefile_types {
   my %opts = @_;
   $opts{requires} ||= {};
+  $opts{build_requires} ||= {};
   $opts{PL_files} ||= {};
 
   foreach my $type (@makefile_types) {
@@ -332,7 +353,7 @@
 
     test_makefile_pl_requires_perl( $opts{requires}{perl} );
     test_makefile_creation($mb);
-    test_makefile_prereq_pm( $opts{requires} );
+    test_makefile_prereq_pm( _merge_prereqs($opts{requires}, 
$opts{build_requires}) );
     test_makefile_pl_files( $opts{PL_files} ) if $type eq 'traditional';
       
     my ($output,$success);

Reply via email to