In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/b907e848c200047115c6d9ded5c73601208ea87b?hp=eb9d0228c41a1528b2864e335094c0c25258789a>

- Log -----------------------------------------------------------------
commit b907e848c200047115c6d9ded5c73601208ea87b
Author: Chris 'BinGOs' Williams <[email protected]>
Date:   Thu Nov 20 15:55:11 2014 +0000

    Update CPAN-Meta to CPAN version 2.143240
    
      [DELTA]
    
    2.143240  2014-11-20 10:26:30-05:00 America/New_York
    
      [FIXED]
    
      - Give correct path in nested merges such as resources
    
      - Removed strings test that should have been removed when
        CPAN::Meta::Requirements was removed to a separate dist

M       MANIFEST
M       META.json
M       META.yml
M       Porting/Maintainers.pl
M       cpan/CPAN-Meta/lib/CPAN/Meta.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/History.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm
M       cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm
M       cpan/CPAN-Meta/t/merge.t
A       cpan/CPAN-Meta/t/optional_feature-merge.t
D       cpan/CPAN-Meta/t/strings.t

commit 1a85ea9547a3c97e1b3d2ca5790981ec60962564
Author: Chris 'BinGOs' Williams <[email protected]>
Date:   Thu Nov 20 15:54:02 2014 +0000

    Update CPAN-Meta-Requirements to CPAN version 2.130
    
      [DELTA]
    
    2.130     2014-11-19 23:25:46-05:00 America/New_York
    
        [ADDED]
    
        - from_string_hash can take optional constructor arguments
    
        [CHANGED]
    
        - bad_version_hook callback gets module name as well as version string
    
        - undefined/empty versions given to from_string_hash or
          add_string_requirement now carp and are coerced to "0" instead of
          being fatal.  This is more consistent with how the other requirement
          functions work.

M       Porting/Maintainers.pl
M       cpan/CPAN-Meta-Requirements/lib/CPAN/Meta/Requirements.pm
M       cpan/CPAN-Meta-Requirements/t/bad_version_hook.t
M       cpan/CPAN-Meta-Requirements/t/from-hash.t
-----------------------------------------------------------------------

Summary of changes:
 MANIFEST                                           |   2 +-
 META.json                                          |   2 +-
 META.yml                                           |   2 +-
 Porting/Maintainers.pl                             |   4 +-
 .../lib/CPAN/Meta/Requirements.pm                  |  60 +++++----
 cpan/CPAN-Meta-Requirements/t/bad_version_hook.t   |  20 ++-
 cpan/CPAN-Meta-Requirements/t/from-hash.t          |  35 +++--
 cpan/CPAN-Meta/lib/CPAN/Meta.pm                    |  16 ++-
 cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm          |   4 +-
 cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm            |   4 +-
 cpan/CPAN-Meta/lib/CPAN/Meta/History.pm            |   4 +-
 cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm              |  40 +++++-
 cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm            |   4 +-
 cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm               |   4 +-
 cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm          |   4 +-
 cpan/CPAN-Meta/t/merge.t                           |   2 +-
 cpan/CPAN-Meta/t/optional_feature-merge.t          | 142 +++++++++++++++++++++
 cpan/CPAN-Meta/t/strings.t                         |  63 ---------
 18 files changed, 278 insertions(+), 134 deletions(-)
 create mode 100644 cpan/CPAN-Meta/t/optional_feature-merge.t
 delete mode 100644 cpan/CPAN-Meta/t/strings.t

diff --git a/MANIFEST b/MANIFEST
index 0cb04cf..5faa395 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -311,12 +311,12 @@ cpan/CPAN-Meta/t/load-bad.t
 cpan/CPAN-Meta/t/merge.t
 cpan/CPAN-Meta/t/meta-obj.t
 cpan/CPAN-Meta/t/no-index.t
+cpan/CPAN-Meta/t/optional_feature-merge.t
 cpan/CPAN-Meta/t/prereqs-finalize.t
 cpan/CPAN-Meta/t/prereqs-merge.t
 cpan/CPAN-Meta/t/prereqs.t
 cpan/CPAN-Meta/t/repository.t
 cpan/CPAN-Meta/t/save-load.t
-cpan/CPAN-Meta/t/strings.t
 cpan/CPAN-Meta/t/validator.t
 cpan/CPAN-Meta-YAML/lib/CPAN/Meta/YAML.pm              CPAN-Meta-YAML files
 cpan/CPAN-Meta-YAML/t/01_api.t
diff --git a/META.json b/META.json
index 221f378..b08ccc8 100644
--- a/META.json
+++ b/META.json
@@ -4,7 +4,7 @@
       "[email protected]"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "CPAN::Meta version 2.142690",
+   "generated_by" : "CPAN::Meta version 2.143240",
    "license" : [
       "perl_5"
    ],
diff --git a/META.yml b/META.yml
index 4346c93..4e4bed5 100644
--- a/META.yml
+++ b/META.yml
@@ -4,7 +4,7 @@ author:
   - [email protected]
 build_requires: {}
 dynamic_config: 1
-generated_by: 'CPAN::Meta version 2.142690, CPAN::Meta::Converter version 
2.142690'
+generated_by: 'CPAN::Meta version 2.143240, CPAN::Meta::Converter version 
2.143240'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl
index 33e03c1..b27f363 100755
--- a/Porting/Maintainers.pl
+++ b/Porting/Maintainers.pl
@@ -288,7 +288,7 @@ use File::Glob qw(:case);
     # Note: When updating CPAN-Meta the META.* files will need to be 
regenerated
     # perl -Icpan/CPAN-Meta/lib Porting/makemeta
     'CPAN::Meta' => {
-        'DISTRIBUTION' => 'DAGOLDEN/CPAN-Meta-2.142690.tar.gz',
+        'DISTRIBUTION' => 'DAGOLDEN/CPAN-Meta-2.143240.tar.gz',
         'FILES'        => q[cpan/CPAN-Meta],
         'EXCLUDED'     => [
             qw[t/00-report-prereqs.t],
@@ -300,7 +300,7 @@ use File::Glob qw(:case);
     },
 
     'CPAN::Meta::Requirements' => {
-        'DISTRIBUTION' => 'DAGOLDEN/CPAN-Meta-Requirements-2.129.tar.gz',
+        'DISTRIBUTION' => 'DAGOLDEN/CPAN-Meta-Requirements-2.130.tar.gz',
         'FILES'        => q[cpan/CPAN-Meta-Requirements],
         'EXCLUDED'     => [
             qw(CONTRIBUTING.mkdn),
diff --git a/cpan/CPAN-Meta-Requirements/lib/CPAN/Meta/Requirements.pm 
b/cpan/CPAN-Meta-Requirements/lib/CPAN/Meta/Requirements.pm
index f313415..05df504 100644
--- a/cpan/CPAN-Meta-Requirements/lib/CPAN/Meta/Requirements.pm
+++ b/cpan/CPAN-Meta-Requirements/lib/CPAN/Meta/Requirements.pm
@@ -3,7 +3,7 @@ use warnings;
 package CPAN::Meta::Requirements;
 # ABSTRACT: a set of version requirements for a CPAN dist
 
-our $VERSION = '2.129';
+our $VERSION = '2.130';
 
 #pod =head1 SYNOPSIS
 #pod
@@ -60,8 +60,9 @@ BEGIN {
 #pod
 #pod =for :list
 #pod * C<bad_version_hook> -- if provided, when a version cannot be parsed into
-#pod   a version object, this code reference will be called with the invalid 
version
-#pod   string as an argument.  It must return a valid version object.
+#pod   a version object, this code reference will be called with the invalid
+#pod   version string as first argument, and the module name as second
+#pod   argument.  It must return a valid version object.
 #pod
 #pod All other keys are ignored.
 #pod
@@ -100,7 +101,7 @@ sub _find_magic_vstring {
 }
 
 sub _version_object {
-  my ($self, $version) = @_;
+  my ($self, $module, $version) = @_;
 
   my $vobj;
 
@@ -119,7 +120,7 @@ sub _version_object {
 
   if ( my $err = $@ ) {
     my $hook = $self->{bad_version_hook};
-    $vobj = eval { $hook->($version) }
+    $vobj = eval { $hook->($version, $module) }
       if ref $hook eq 'CODE';
     unless (Scalar::Util::blessed($vobj) && $vobj->isa("version")) {
       $err =~ s{ at .* line \d+.*$}{};
@@ -200,7 +201,7 @@ BEGIN {
     my $code = sub {
       my ($self, $name, $version) = @_;
 
-      $version = $self->_version_object( $version );
+      $version = $self->_version_object( $name, $version );
 
       $self->__modify_entry_for($name, $method, $version);
 
@@ -258,7 +259,7 @@ sub add_requirements {
 sub accepts_module {
   my ($self, $module, $version) = @_;
 
-  $version = $self->_version_object( $version );
+  $version = $self->_version_object( $module, $version );
 
   return 1 unless my $range = $self->__entry_for($module);
   return $range->_accepts($version);
@@ -480,8 +481,10 @@ my %methods_for_op = (
 sub add_string_requirement {
   my ($self, $module, $req) = @_;
 
-  Carp::confess("No requirement string provided for $module")
-    unless defined $req && length $req;
+  unless ( defined $req && length $req ) {
+    $req = 0;
+    $self->_blank_carp($module);
+  }
 
   my $magic = _find_magic_vstring( $req );
   if (length $magic) {
@@ -508,24 +511,32 @@ sub add_string_requirement {
 #pod =method from_string_hash
 #pod
 #pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
+#pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
 #pod
-#pod This is an alternate constructor for a CPAN::Meta::Requirements object.  
It takes
-#pod a hash of module names and version requirement strings and returns a new
-#pod CPAN::Meta::Requirements object. As with add_string_requirement, a
-#pod version can be a Perl "v-string".
+#pod This is an alternate constructor for a CPAN::Meta::Requirements
+#pod object. It takes a hash of module names and version requirement
+#pod strings and returns a new CPAN::Meta::Requirements object. As with
+#pod add_string_requirement, a version can be a Perl "v-string". Optionally,
+#pod you can supply a hash-reference of options, exactly as with the L</new>
+#pod method.
 #pod
 #pod =cut
 
+sub _blank_carp {
+  my ($self, $module) = @_;
+  Carp::carp("Undefined requirement for $module treated as '0'");
+}
+
 sub from_string_hash {
-  my ($class, $hash) = @_;
+  my ($class, $hash, $options) = @_;
 
-  my $self = $class->new;
+  my $self = $class->new($options);
 
   for my $module (keys %$hash) {
     my $req = $hash->{$module};
     unless ( defined $req && length $req ) {
       $req = 0;
-      Carp::carp("Undefined requirement for $module treated as '0'");
+      $class->_blank_carp($module);
     }
     $self->add_string_requirement($module, $req);
   }
@@ -744,7 +755,7 @@ CPAN::Meta::Requirements - a set of version requirements 
for a CPAN dist
 
 =head1 VERSION
 
-version 2.129
+version 2.130
 
 =head1 SYNOPSIS
 
@@ -784,7 +795,7 @@ hash reference argument.  Currently, only one key is 
supported:
 
 =item *
 
-C<bad_version_hook> -- if provided, when a version cannot be parsed into a 
version object, this code reference will be called with the invalid version 
string as an argument.  It must return a valid v ... [14 chars truncated]
+C<bad_version_hook> -- if provided, when a version cannot be parsed into a 
version object, this code reference will be called with the invalid version 
string as first argument, and the module name as ... [57 chars truncated]
 
 =back
 
@@ -982,11 +993,14 @@ A version number without an operator is equivalent to 
specifying a minimum
 =head2 from_string_hash
 
   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
-
-This is an alternate constructor for a CPAN::Meta::Requirements object.  It 
takes
-a hash of module names and version requirement strings and returns a new
-CPAN::Meta::Requirements object. As with add_string_requirement, a
-version can be a Perl "v-string".
+  my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
+
+This is an alternate constructor for a CPAN::Meta::Requirements
+object. It takes a hash of module names and version requirement
+strings and returns a new CPAN::Meta::Requirements object. As with
+add_string_requirement, a version can be a Perl "v-string". Optionally,
+you can supply a hash-reference of options, exactly as with the L</new>
+method.
 
 =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants 
kwalitee diff irc mailto metadata placeholders metacpan
 
diff --git a/cpan/CPAN-Meta-Requirements/t/bad_version_hook.t 
b/cpan/CPAN-Meta-Requirements/t/bad_version_hook.t
index 4b7c8c0..5eef7fb 100644
--- a/cpan/CPAN-Meta-Requirements/t/bad_version_hook.t
+++ b/cpan/CPAN-Meta-Requirements/t/bad_version_hook.t
@@ -6,6 +6,13 @@ use version;
 
 use Test::More 0.88;
 
+my %DATA = (
+  'Foo::Bar' => [ 10, 10 ],
+  'Foo::Baz' => [ 'invalid_version', 42 ],
+);
+my %input = map { ($_ => $DATA{$_}->[0]) } keys %DATA;
+my %expected = map { ($_ => $DATA{$_}->[1]) } keys %DATA;
+
 sub dies_ok (&@) {
   my ($code, $qr, $comment) = @_;
 
@@ -18,20 +25,19 @@ sub dies_ok (&@) {
   }
 }
 
-sub _fixit { return version->new(42) }
+my $hook_text;
+sub _fixit { my ($v, $m) = @_; $hook_text = $m; return version->new(42) }
 
 {
   my $req = CPAN::Meta::Requirements->new( {bad_version_hook => \&_fixit} );
 
-  $req->add_minimum('Foo::Bar' => 10);
-  $req->add_minimum('Foo::Baz' => 'invalid_version');
+  my ($k, $v);
+  $req->add_minimum($k => $v) while ($k, $v) = each %input;
+  is $hook_text, 'Foo::Baz', 'hook stored module name';
 
   is_deeply(
     $req->as_string_hash,
-    {
-      'Foo::Bar'   => 10,
-      'Foo::Baz'   => 42,
-    },
+    \%expected,
     "hook fixes invalid version",
   );
 }
diff --git a/cpan/CPAN-Meta-Requirements/t/from-hash.t 
b/cpan/CPAN-Meta-Requirements/t/from-hash.t
index 451c374..73ec214 100644
--- a/cpan/CPAN-Meta-Requirements/t/from-hash.t
+++ b/cpan/CPAN-Meta-Requirements/t/from-hash.t
@@ -46,24 +46,22 @@ sub dies_ok (&@) {
 }
 
 {
-  my $string_hash = {
-    Left   => 10,
-    Shared => undef,
-    Right  => 18,
-  };
+  my $undef_hash = { Undef => undef };
+  my $z_hash = { ZeroLength => '' };
 
   my $warning;
   local $SIG{__WARN__} = sub { $warning = join("\n",@_) };
 
-  my $req = CPAN::Meta::Requirements->from_string_hash($string_hash);
-
-  is(
-    $req->as_string_hash->{Shared}, 0,
-    "undef requirement treated as '0'",
-  );
-
+  my $req = CPAN::Meta::Requirements->from_string_hash($undef_hash);
   like ($warning, qr/Undefined requirement.*treated as '0'/, "undef 
requirement warns");
+  $req->add_string_requirement(%$z_hash);
+  like ($warning, qr/Undefined requirement.*treated as '0'/, "'' requirement 
warns");
 
+  is_deeply(
+    $req->as_string_hash,
+    { map { ($_ => 0) } keys(%$undef_hash), keys(%$z_hash) },
+    "undef/'' requirements treated as '0'",
+  );
 }
 
 {
@@ -84,4 +82,17 @@ sub dies_ok (&@) {
   );
 }
 
+
+{
+  my $req = CPAN::Meta::Requirements->from_string_hash(
+    { Bad => 'invalid', },
+    { bad_version_hook => sub { version->new(42) } },
+  );
+
+  ok(
+    $req->accepts_module(Bad => 42),
+    "options work 2nd arg to f_s_h",
+  );
+}
+
 done_testing;
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta.pm b/cpan/CPAN-Meta/lib/CPAN/Meta.pm
index f2a8936..83e4ced 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta.pm
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta;
 # VERSION
-$CPAN::Meta::VERSION = '2.142690';
+$CPAN::Meta::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod     use v5.10;
@@ -465,7 +465,8 @@ sub effective_prereqs {
 #pod
 #pod This method returns true if the given file should be indexed.  It decides 
this
 #pod by checking the C<file> and C<directory> keys in the C<no_index> property 
of
-#pod the distmeta structure.
+#pod the distmeta structure. Note that neither the version format nor
+#pod C<release_status> are considered.
 #pod
 #pod C<$filename> should be given in unix format.
 #pod
@@ -492,7 +493,8 @@ sub should_index_file {
 #pod
 #pod This method returns true if the given package should be indexed.  It 
decides
 #pod this by checking the C<package> and C<namespace> keys in the C<no_index>
-#pod property of the distmeta structure.
+#pod property of the distmeta structure. Note that neither the version format 
nor
+#pod C<release_status> are considered.
 #pod
 #pod =cut
 
@@ -641,7 +643,7 @@ CPAN::Meta - the distribution metadata for a CPAN dist
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
@@ -799,7 +801,8 @@ distribution's core prereqs before the CPAN::Meta::Prereqs 
object is returned.
 
 This method returns true if the given file should be indexed.  It decides this
 by checking the C<file> and C<directory> keys in the C<no_index> property of
-the distmeta structure.
+the distmeta structure. Note that neither the version format nor
+C<release_status> are considered.
 
 C<$filename> should be given in unix format.
 
@@ -809,7 +812,8 @@ C<$filename> should be given in unix format.
 
 This method returns true if the given package should be indexed.  It decides
 this by checking the C<package> and C<namespace> keys in the C<no_index>
-property of the distmeta structure.
+property of the distmeta structure. Note that neither the version format nor
+C<release_status> are considered.
 
 =head2 features
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm
index 1a92af4..fe89c36 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Converter;
 # VERSION
-$CPAN::Meta::Converter::VERSION = '2.142690';
+$CPAN::Meta::Converter::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod   my $struct = decode_json_file('META.json');
@@ -1494,7 +1494,7 @@ CPAN::Meta::Converter - Convert CPAN distribution 
metadata structures
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm
index 35476cf..45ab897 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Feature;
 # VERSION
-$CPAN::Meta::Feature::VERSION = '2.142690';
+$CPAN::Meta::Feature::VERSION = '2.143240';
 use CPAN::Meta::Prereqs;
 
 #pod =head1 DESCRIPTION
@@ -78,7 +78,7 @@ CPAN::Meta::Feature - an optional feature provided by a CPAN 
distribution
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm
index abf14f1..b5339d1 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 package CPAN::Meta::History;
 # VERSION
-$CPAN::Meta::History::VERSION = '2.142690';
+$CPAN::Meta::History::VERSION = '2.143240';
 1;
 
 # ABSTRACT: history of CPAN Meta Spec changes
@@ -21,7 +21,7 @@ CPAN::Meta::History - history of CPAN Meta Spec changes
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm
index 490985a..5571c51 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Merge.pm
@@ -3,14 +3,14 @@ use warnings;
 
 package CPAN::Meta::Merge;
 # VERSION
-$CPAN::Meta::Merge::VERSION = '2.142690';
+$CPAN::Meta::Merge::VERSION = '2.143240';
 use Carp qw/croak/;
 use Scalar::Util qw/blessed/;
 use CPAN::Meta::Converter;
 
 sub _identical {
   my ($left, $right, $path) = @_;
-  croak "Can't merge attribute " . join '.', @{$path} unless $left eq $right;
+  croak sprintf "Can't merge attribute %s: '%s' does not equal '%s'", 
join('.', @{$path}), $left, $right unless $left eq $right;
   return $left;
 }
 
@@ -73,6 +73,36 @@ sub _improvize {
   croak sprintf "Can't merge '%s'", join '.', @{$path};
 }
 
+sub _optional_features {
+  my ($left, $right, $path) = @_;
+
+  for my $key (keys %{$right}) {
+    if (not exists $left->{$key}) {
+      $left->{$key} = $right->{$key};
+    }
+    else {
+      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} =
+        CPAN::Meta::Prereqs->new($left->{$key}{prereqs})
+          
->with_merged_prereqs(CPAN::Meta::Prereqs->new($right->{$key}{prereqs}))
+          ->as_string_hash;
+    }
+  }
+  return $left;
+}
+
+
 my %default = (
   abstract       => \&_identical,
   author         => \&_set_addition,
@@ -95,7 +125,7 @@ my %default = (
   description       => \&_identical,
   keywords          => \&_set_addition,
   no_index          => { map { ($_ => \&_set_addition) } qw/file directory 
package namespace/ },
-  optional_features => \&_uniq_map,
+  optional_features => \&_optional_features,
   prereqs           => sub {
     require CPAN::Meta::Prereqs;
     my ($left, $right) = map { CPAN::Meta::Prereqs->new($_) } @_[0,1];
@@ -150,7 +180,7 @@ sub _coerce_mapping {
       my $mapping = _coerce_mapping($value, [ @{$map_path}, $key ]);
       $ret{$key} = sub {
         my ($left, $right, $path) = @_;
-        return _merge($left, $right, $mapping, [ @{$path}, $key ]);
+        return _merge($left, $right, $mapping, [ @{$path} ]);
       };
     }
     elsif ($coderef_for{$value}) {
@@ -200,7 +230,7 @@ CPAN::Meta::Merge - Merging CPAN Meta fragments
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm
index 3332f6b..748a237 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Prereqs;
 # VERSION
-$CPAN::Meta::Prereqs::VERSION = '2.142690';
+$CPAN::Meta::Prereqs::VERSION = '2.143240';
 #pod =head1 DESCRIPTION
 #pod
 #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
@@ -286,7 +286,7 @@ CPAN::Meta::Prereqs - a set of distribution prerequisites 
by phase and type
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 DESCRIPTION
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm
index 4a72b72..a4e330b 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm
@@ -8,7 +8,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Spec;
 # VERSION
-$CPAN::Meta::Spec::VERSION = '2.142690';
+$CPAN::Meta::Spec::VERSION = '2.143240';
 1;
 
 # ABSTRACT: specification for CPAN distribution metadata
@@ -28,7 +28,7 @@ CPAN::Meta::Spec - specification for CPAN distribution 
metadata
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm 
b/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm
index 67fb931..8799f52 100644
--- a/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm
+++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 package CPAN::Meta::Validator;
 # VERSION
-$CPAN::Meta::Validator::VERSION = '2.142690';
+$CPAN::Meta::Validator::VERSION = '2.143240';
 #pod =head1 SYNOPSIS
 #pod
 #pod   my $struct = decode_json_file('META.json');
@@ -997,7 +997,7 @@ CPAN::Meta::Validator - validate CPAN distribution metadata 
structures
 
 =head1 VERSION
 
-version 2.142690
+version 2.143240
 
 =head1 SYNOPSIS
 
diff --git a/cpan/CPAN-Meta/t/merge.t b/cpan/CPAN-Meta/t/merge.t
index c7396d4..f58e8c6 100644
--- a/cpan/CPAN-Meta/t/merge.t
+++ b/cpan/CPAN-Meta/t/merge.t
@@ -110,7 +110,7 @@ is_deeply($first_result, \%first_expected, 'First result is 
as expected');
 is_deeply($merger->merge(\%base, { abstract => 'This is a test' }), \%base, 
'Can merge in identical abstract');
 my $failure = eval { $merger->merge(\%base, { abstract => 'And now for 
something else' }) };
 is($failure, undef, 'Trying to merge different author gives an exception');
-like $@, qr/^Can't merge attribute abstract /, 'Exception looks right';
+like $@, qr/^Can't merge attribute abstract/, 'Exception looks right';
 
 my $failure2 = eval { $merger->merge(\%base, { provides => { Baz => { file => 
'Baz.pm' } } }) };
 is($failure2, undef, 'Trying to merge different author gives an exception');
diff --git a/cpan/CPAN-Meta/t/optional_feature-merge.t 
b/cpan/CPAN-Meta/t/optional_feature-merge.t
new file mode 100644
index 0000000..15aa621
--- /dev/null
+++ b/cpan/CPAN-Meta/t/optional_feature-merge.t
@@ -0,0 +1,142 @@
+use strict;
+use warnings;
+# vim: set ts=4 sw=4 noet nolist :
+
+use Test::More;
+use CPAN::Meta;
+use CPAN::Meta::Merge;
+
+my %base = (
+       abstract => 'This is a test',
+       author => ['A.U. Thor'],
+       generated_by => 'Myself',
+       license => [ 'perl_5' ],
+       resources => {
+               license => [ 'http://dev.perl.org/licenses/' ],
+       },
+       prereqs => {
+               runtime => {
+                       requires => {
+                               Foo => '0',
+                       },
+               },
+       },
+       dynamic_config => 0,
+       provides => {
+               Baz => {
+                       file => 'lib/Baz.pm',
+               },
+       },
+       'meta-spec' => {
+               url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec";,
+               version => 2,
+       },
+);
+
+my $fragment1 = {
+       'optional_features' => {
+               'FeatureName' => {
+                       'description' => 'desc',
+                       'x_default' => 1,
+                       'prereqs' => { 'runtime' => { 'requires' => { 'A' => 
'0' } } }
+               }
+       }
+};
+my $fragment2 = {
+       'optional_features' => {
+               'FeatureName' => {
+                       'description' => 'desc',
+                       'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } 
} }
+               }
+       }
+};
+
+my $merger = CPAN::Meta::Merge->new(default_version => "2");
+my $meta1 = $merger->merge(\%base, $fragment1);
+
+is_deeply(
+       $meta1,
+       {
+               %base,
+               %$fragment1,
+       },
+       'merged first optional_feature fragment into base',
+);
+
+my $meta2 = $merger->merge($meta1, $fragment2);
+
+is_deeply(
+       $meta2,
+       {
+               %base,
+               'optional_features' => {
+                       'FeatureName' => {
+                               'description' => 'desc',
+                               'x_default' => 1,
+                               'prereqs' => {
+                                       'runtime' => { 'requires' => { 'A' => 
'0' } },
+                                       'test' => { 'requires' => { 'B' => '0' 
} },
+                               }
+                       }
+               }
+       },
+       'merged second optional_feature fragment into the first',
+);
+
+my $fragment3 = {
+       'optional_features' => {
+               'FeatureName' => {
+                       'description' => 'other desc',
+                       'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } 
} }
+               }
+       }
+};
+
+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',
+                       'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } 
} }
+               }
+       }
+};
+
+my $meta5 = $merger->merge($meta1, $fragment5);
+is_deeply(
+       $meta5,
+       {
+               %base,
+               'optional_features' => {
+                       'FeatureName' => {
+                               'description' => 'desc',
+                               'x_default' => 1,
+                               'prereqs' => { 'runtime' => { 'requires' => { 
'A' => '0' } } },
+                       },
+                       'Another FeatureName' => {
+                               'description' => 'desc',
+                               'prereqs' => { 'test' => { 'requires' => { 'B' 
=> '0' } } },
+                       }
+               }
+       },
+       'can merge optional_features with different names without collisions',
+);
+
+done_testing;
diff --git a/cpan/CPAN-Meta/t/strings.t b/cpan/CPAN-Meta/t/strings.t
deleted file mode 100644
index bb87c68..0000000
--- a/cpan/CPAN-Meta/t/strings.t
+++ /dev/null
@@ -1,63 +0,0 @@
-use strict;
-use warnings;
-use Test::More 0.88;
-
-sub dies_ok (&@) {
-  my ($code, $qr, $comment) = @_;
-
-  my $lived = eval { $code->(); 1 };
-
-  if ($lived) {
-    fail("$comment: did not die");
-  } else {
-    like($@, $qr, $comment);
-  }
-}
-
-use CPAN::Meta::Requirements;
-
-my $req = CPAN::Meta::Requirements->new;
-
-# Test ==
-$req->add_string_requirement('Foo::Bar', '== 1.3');
-ok($req->accepts_module('Foo::Bar' => '1.3'), 'exact version (==)');
-ok(!$req->accepts_module('Foo::Bar' => '1.2'), 'lower version (==)');
-ok(!$req->accepts_module('Foo::Bar' => '1.4'), 'higher version (==)');
-
-# Test !=
-$req->add_string_requirement('Foo::Baz', '!= 1.3');
-ok(!$req->accepts_module('Foo::Baz' => '1.3'), 'exact version (!=)');
-ok($req->accepts_module('Foo::Baz' => '1.2'), 'lower version (!=)');
-ok($req->accepts_module('Foo::Baz' => '1.4'), 'higher version (!=)');
-
-# Test >=
-$req->add_string_requirement('Foo::Gorch', '>= 1.3');
-ok($req->accepts_module('Foo::Gorch' => '1.3'), 'exact version (>=)');
-ok(!$req->accepts_module('Foo::Gorch' => '1.2'), 'lower version (>=)');
-ok($req->accepts_module('Foo::Gorch' => '1.4'), 'higher version (>=)');
-
-# Test <=
-$req->add_string_requirement('Foo::Graz', '<= 1.3');
-ok($req->accepts_module('Foo::Graz' => '1.3'), 'exact version (<=)');
-ok($req->accepts_module('Foo::Graz' => '1.2'), 'lower version (<=)');
-ok(!$req->accepts_module('Foo::Graz' => '1.4'), 'higher version (<=)');
-
-# Test ""
-$req->add_string_requirement('Foo::Blurb', '>= 1.3');
-ok($req->accepts_module('Foo::Blurb' => '1.3'), 'exact version (>=)');
-ok(!$req->accepts_module('Foo::Blurb' => '1.2'), 'lower version (>=)');
-ok($req->accepts_module('Foo::Blurb' => '1.4'), 'higher version (>=)');
-
-# Test multiple requirements
-$req->add_string_requirement('A::Tribe::Called', '>= 1.3, <= 2.0, != 1.6');
-ok($req->accepts_module('A::Tribe::Called' => '1.5'), 'middle version (>=, <=, 
!)');
-ok(!$req->accepts_module('A::Tribe::Called' => '1.2'), 'lower version (>=, <=, 
!)');
-ok(!$req->accepts_module('A::Tribe::Called' => '2.1'), 'higher version (>=, 
<=, !)');
-ok(!$req->accepts_module('A::Tribe::Called' => '1.6'), 'excluded version (>=, 
<=, !)');
-
-# Test fatal errors
-dies_ok { $req->add_string_requirement('Foo::Bar', undef) }
-  qr/No requirement string provided/,
-  "die without a requirement string";
-
-done_testing;

--
Perl5 Master Repository

Reply via email to