[libcpan-meta-perl] 01/04: Imported Upstream version 2.141170

gregor herrmann gregoa at debian.org
Sat May 3 12:58:01 UTC 2014


This is an automated email from the git hooks/post-receive script.

gregoa pushed a commit to branch master
in repository libcpan-meta-perl.

commit 61aec5a25e2aeb14da019b7458cf40e345115c5d
Author: gregor herrmann <gregoa at debian.org>
Date:   Sat May 3 14:51:16 2014 +0200

    Imported Upstream version 2.141170
---
 Changes                    |  19 ++
 LICENSE                    |   2 +-
 MANIFEST                   |   3 +-
 META.json                  |  28 +--
 META.yml                   |  22 +-
 Makefile.PL                |   8 +-
 README                     |   6 +-
 cpanfile                   |   4 +-
 dist.ini                   |   1 +
 lib/CPAN/Meta.pm           | 572 +++++++++++++++++++++++----------------------
 lib/CPAN/Meta/Converter.pm | 316 ++++++++++++++++---------
 lib/CPAN/Meta/Feature.pm   |  72 +++---
 lib/CPAN/Meta/History.pm   |   4 +-
 lib/CPAN/Meta/Prereqs.pm   | 212 ++++++++---------
 lib/CPAN/Meta/Spec.pm      |  40 +++-
 lib/CPAN/Meta/Validator.pm | 354 ++++++++++++++--------------
 t/00-report-prereqs.t      |   4 +-
 t/converter-fragments.t    | 158 +++++++++++++
 xt/author/00-compile.t     |   2 +-
 xt/author/pod-spell.t      |  13 +-
 20 files changed, 1089 insertions(+), 751 deletions(-)

diff --git a/Changes b/Changes
index 106b9c0..ff50812 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,24 @@
 Revision history for CPAN-Meta
 
+2.141170  2014-04-27 13:03:37-04:00 America/New_York
+
+  [ADDED]
+
+  - Added ability for CPAN::Meta::Converter to convert metadata fragments
+    (incomplete portions of a metadata structure)
+
+  [CHANGED]
+
+  - Optimized internal use of JSON for datastructure cloning
+
+  [FIXED]
+
+  - Removed dependency on List::Util 1.33
+
+  [DOCUMENTED]
+
+  - Clarified language around 'dynamic_config' in the Spec
+
 2.140640  2014-03-05 09:07:05-05:00 America/New_York
 
   [FIXED]
diff --git a/LICENSE b/LICENSE
index 905f9a2..2e750f8 100644
--- a/LICENSE
+++ b/LICENSE
@@ -22,7 +22,7 @@ This is free software, licensed under:
                      Version 1, February 1989
 
  Copyright (C) 1989 Free Software Foundation, Inc.
- 51 Franklin St, Suite 500, Boston, MA  02110-1335  USA
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
diff --git a/MANIFEST b/MANIFEST
index 45fa528..5ebe558 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,4 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.013.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.015.
 CONTRIBUTING
 Changes
 LICENSE
@@ -27,6 +27,7 @@ t/00-report-prereqs.t
 t/README-data.txt
 t/converter-bad.t
 t/converter-fail.t
+t/converter-fragments.t
 t/converter.t
 t/data-fail/META-1_0.yml
 t/data-fail/META-1_1.yml
diff --git a/META.json b/META.json
index 000b677..4f73a72 100644
--- a/META.json
+++ b/META.json
@@ -5,12 +5,12 @@
       "Ricardo Signes <rjbs at cpan.org>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 5.013, CPAN::Meta::Converter version 2.140630",
+   "generated_by" : "Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.140640",
    "license" : [
       "perl_5"
    ],
    "meta-spec" : {
-      "url" : "https://metacpan.org/pod/CPAN::Meta::Spec",
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
       "version" : "2"
    },
    "name" : "CPAN-Meta",
@@ -34,7 +34,7 @@
       },
       "develop" : {
          "requires" : {
-            "Dist::Zilla" : "5.013",
+            "Dist::Zilla" : "5.015",
             "Dist::Zilla::Plugin::AutoVersion" : "0",
             "Dist::Zilla::Plugin::MakeMaker" : "0",
             "Dist::Zilla::Plugin::MakeMaker::Highlander" : "0.003",
@@ -58,7 +58,6 @@
             "CPAN::Meta::YAML" : "0.008",
             "Carp" : "0",
             "JSON::PP" : "2.27200",
-            "List::Util" : "1.33",
             "Parse::CPAN::Meta" : "1.4414",
             "Scalar::Util" : "0",
             "perl" : "5.008",
@@ -80,6 +79,7 @@
             "File::Spec::Functions" : "0",
             "File::Temp" : "0.20",
             "IO::Dir" : "0",
+            "List::Util" : "0",
             "Test::More" : "0.88",
             "overload" : "0",
             "utf8" : "0"
@@ -89,31 +89,31 @@
    "provides" : {
       "CPAN::Meta" : {
          "file" : "lib/CPAN/Meta.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::Converter" : {
          "file" : "lib/CPAN/Meta/Converter.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::Feature" : {
          "file" : "lib/CPAN/Meta/Feature.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::History" : {
          "file" : "lib/CPAN/Meta/History.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::Prereqs" : {
          "file" : "lib/CPAN/Meta/Prereqs.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::Spec" : {
          "file" : "lib/CPAN/Meta/Spec.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       },
       "CPAN::Meta::Validator" : {
          "file" : "lib/CPAN/Meta/Validator.pm",
-         "version" : "2.140640"
+         "version" : "2.141170"
       }
    },
    "release_status" : "stable",
@@ -128,7 +128,7 @@
          "web" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta"
       }
    },
-   "version" : "2.140640",
+   "version" : "2.141170",
    "x_authority" : "cpan:DAGOLDEN",
    "x_contributors" : [
       "Ansgar Burchardt <ansgar at cpan.org>",
@@ -145,10 +145,12 @@
       "Lars Dieckow <daxim at cpan.org>",
       "Leon Timmermans <leont at cpan.org>",
       "Mark Fowler <markf at cpan.org>",
+      "Matt S Trout <mst at shadowcat.co.uk>",
       "Michael G. Schwern <mschwern at cpan.org>",
       "Olaf Alders <olaf at wundersolutions.com>",
       "Olivier Mengue <dolmen at cpan.org>",
-      "Randy Sims <randys at thepierianspring.org>"
+      "Randy Sims <randys at thepierianspring.org>",
+      "moznion <moznion at gmail.com>"
    ]
 }
 
diff --git a/META.yml b/META.yml
index 5c1f97d..0eb9f48 100644
--- a/META.yml
+++ b/META.yml
@@ -11,13 +11,14 @@ build_requires:
   File::Spec::Functions: '0'
   File::Temp: '0.20'
   IO::Dir: '0'
+  List::Util: '0'
   Test::More: '0.88'
   overload: '0'
   utf8: '0'
 configure_requires:
   ExtUtils::MakeMaker: '6.17'
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.013, CPAN::Meta::Converter version 2.140630'
+generated_by: 'Dist::Zilla version 5.015, CPAN::Meta::Converter version 2.140640'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -35,31 +36,30 @@ no_index:
 provides:
   CPAN::Meta:
     file: lib/CPAN/Meta.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::Converter:
     file: lib/CPAN/Meta/Converter.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::Feature:
     file: lib/CPAN/Meta/Feature.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::History:
     file: lib/CPAN/Meta/History.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::Prereqs:
     file: lib/CPAN/Meta/Prereqs.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::Spec:
     file: lib/CPAN/Meta/Spec.pm
-    version: '2.140640'
+    version: '2.141170'
   CPAN::Meta::Validator:
     file: lib/CPAN/Meta/Validator.pm
-    version: '2.140640'
+    version: '2.141170'
 requires:
   CPAN::Meta::Requirements: '2.121'
   CPAN::Meta::YAML: '0.008'
   Carp: '0'
   JSON::PP: '2.27200'
-  List::Util: '1.33'
   Parse::CPAN::Meta: '1.4414'
   Scalar::Util: '0'
   perl: '5.008'
@@ -70,7 +70,7 @@ resources:
   bugtracker: https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues
   homepage: https://github.com/Perl-Toolchain-Gang/CPAN-Meta
   repository: https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git
-version: '2.140640'
+version: '2.141170'
 x_authority: cpan:DAGOLDEN
 x_contributors:
   - 'Ansgar Burchardt <ansgar at cpan.org>'
@@ -87,7 +87,9 @@ x_contributors:
   - 'Lars Dieckow <daxim at cpan.org>'
   - 'Leon Timmermans <leont at cpan.org>'
   - 'Mark Fowler <markf at cpan.org>'
+  - 'Matt S Trout <mst at shadowcat.co.uk>'
   - 'Michael G. Schwern <mschwern at cpan.org>'
   - 'Olaf Alders <olaf at wundersolutions.com>'
   - 'Olivier Mengue <dolmen at cpan.org>'
   - 'Randy Sims <randys at thepierianspring.org>'
+  - 'moznion <moznion at gmail.com>'
diff --git a/Makefile.PL b/Makefile.PL
index ac9f558..a08a6e4 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,5 +1,5 @@
 
-# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.013.
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.015.
 use strict;
 use warnings;
 
@@ -25,7 +25,6 @@ my %WriteMakefileArgs = (
     "CPAN::Meta::YAML" => "0.008",
     "Carp" => 0,
     "JSON::PP" => "2.27200",
-    "List::Util" => "1.33",
     "Parse::CPAN::Meta" => "1.4414",
     "Scalar::Util" => 0,
     "strict" => 0,
@@ -40,11 +39,12 @@ my %WriteMakefileArgs = (
     "File::Spec::Functions" => 0,
     "File::Temp" => "0.20",
     "IO::Dir" => 0,
+    "List::Util" => 0,
     "Test::More" => "0.88",
     "overload" => 0,
     "utf8" => 0
   },
-  "VERSION" => "2.140640",
+  "VERSION" => "2.141170",
   "test" => {
     "TESTS" => "t/*.t"
   }
@@ -63,7 +63,7 @@ my %FallbackPrereqs = (
   "File::Temp" => "0.20",
   "IO::Dir" => 0,
   "JSON::PP" => "2.27200",
-  "List::Util" => "1.33",
+  "List::Util" => 0,
   "Parse::CPAN::Meta" => "1.4414",
   "Scalar::Util" => 0,
   "Test::More" => "0.88",
diff --git a/README b/README
index 9606cc7..2cacdb0 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ NAME
     CPAN::Meta - the distribution metadata for a CPAN dist
 
 VERSION
-    version 2.140640
+    version 2.141170
 
 SYNOPSIS
         use v5.10;
@@ -314,6 +314,8 @@ CONTRIBUTORS
 
     *   Mark Fowler <markf at cpan.org>
 
+    *   Matt S Trout <mst at shadowcat.co.uk>
+
     *   Michael G. Schwern <mschwern at cpan.org>
 
     *   Olaf Alders <olaf at wundersolutions.com>
@@ -322,6 +324,8 @@ CONTRIBUTORS
 
     *   Randy Sims <randys at thepierianspring.org>
 
+    *   moznion <moznion at gmail.com>
+
 COPYRIGHT AND LICENSE
     This software is copyright (c) 2010 by David Golden and Ricardo Signes.
 
diff --git a/cpanfile b/cpanfile
index b5ace2e..0da4a03 100644
--- a/cpanfile
+++ b/cpanfile
@@ -2,7 +2,6 @@ requires "CPAN::Meta::Requirements" => "2.121";
 requires "CPAN::Meta::YAML" => "0.008";
 requires "Carp" => "0";
 requires "JSON::PP" => "2.27200";
-requires "List::Util" => "1.33";
 requires "Parse::CPAN::Meta" => "1.4414";
 requires "Scalar::Util" => "0";
 requires "perl" => "5.008";
@@ -18,6 +17,7 @@ on 'test' => sub {
   requires "File::Spec::Functions" => "0";
   requires "File::Temp" => "0.20";
   requires "IO::Dir" => "0";
+  requires "List::Util" => "0";
   requires "Test::More" => "0.88";
   requires "overload" => "0";
   requires "utf8" => "0";
@@ -33,7 +33,7 @@ on 'configure' => sub {
 };
 
 on 'develop' => sub {
-  requires "Dist::Zilla" => "5.013";
+  requires "Dist::Zilla" => "5.015";
   requires "Dist::Zilla::Plugin::AutoVersion" => "0";
   requires "Dist::Zilla::Plugin::MakeMaker" => "0";
   requires "Dist::Zilla::Plugin::MakeMaker::Highlander" => "0.003";
diff --git a/dist.ini b/dist.ini
index 544a780..ec12ac1 100644
--- a/dist.ini
+++ b/dist.ini
@@ -22,6 +22,7 @@ stopwords = distmeta
 stopwords = dir
 stopwords = mailto
 stopwords = metacpan
+stopwords = releaser
 stopwords = subkey
 stopwords = subkeys
 
diff --git a/lib/CPAN/Meta.pm b/lib/CPAN/Meta.pm
index 3ab0111..17c74f6 100644
--- a/lib/CPAN/Meta.pm
+++ b/lib/CPAN/Meta.pm
@@ -2,55 +2,55 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta;
-our $VERSION = '2.140640'; # VERSION
-
-# =head1 SYNOPSIS
-#
-#     use v5.10;
-#     use strict;
-#     use warnings;
-#     use CPAN::Meta;
-#     use Module::Load;
-#
-#     my $meta = CPAN::Meta->load_file('META.json');
-#
-#     printf "testing requirements for %s version %s\n",
-#     $meta->name,
-#     $meta->version;
-#
-#     my $prereqs = $meta->effective_prereqs;
-#
-#     for my $phase ( qw/configure runtime build test/ ) {
-#         say "Requirements for $phase:";
-#         my $reqs = $prereqs->requirements_for($phase, "requires");
-#         for my $module ( sort $reqs->required_modules ) {
-#             my $status;
-#             if ( eval { load $module unless $module eq 'perl'; 1 } ) {
-#                 my $version = $module eq 'perl' ? $] : $module->VERSION;
-#                 $status = $reqs->accepts_module($module, $version)
-#                         ? "$version ok" : "$version not ok";
-#             } else {
-#                 $status = "missing"
-#             };
-#             say "  $module ($status)";
-#         }
-#     }
-#
-# =head1 DESCRIPTION
-#
-# Software distributions released to the CPAN include a F<META.json> or, for
-# older distributions, F<META.yml>, which describes the distribution, its
-# contents, and the requirements for building and installing the distribution.
-# The data structure stored in the F<META.json> file is described in
-# L<CPAN::Meta::Spec>.
-#
-# CPAN::Meta provides a simple class to represent this distribution metadata (or
-# I<distmeta>), along with some helpful methods for interrogating that data.
-#
-# The documentation below is only for the methods of the CPAN::Meta object.  For
-# information on the meaning of individual fields, consult the spec.
-#
-# =cut
+our $VERSION = '2.141170'; # VERSION
+
+#pod =head1 SYNOPSIS
+#pod
+#pod     use v5.10;
+#pod     use strict;
+#pod     use warnings;
+#pod     use CPAN::Meta;
+#pod     use Module::Load;
+#pod
+#pod     my $meta = CPAN::Meta->load_file('META.json');
+#pod
+#pod     printf "testing requirements for %s version %s\n",
+#pod     $meta->name,
+#pod     $meta->version;
+#pod
+#pod     my $prereqs = $meta->effective_prereqs;
+#pod
+#pod     for my $phase ( qw/configure runtime build test/ ) {
+#pod         say "Requirements for $phase:";
+#pod         my $reqs = $prereqs->requirements_for($phase, "requires");
+#pod         for my $module ( sort $reqs->required_modules ) {
+#pod             my $status;
+#pod             if ( eval { load $module unless $module eq 'perl'; 1 } ) {
+#pod                 my $version = $module eq 'perl' ? $] : $module->VERSION;
+#pod                 $status = $reqs->accepts_module($module, $version)
+#pod                         ? "$version ok" : "$version not ok";
+#pod             } else {
+#pod                 $status = "missing"
+#pod             };
+#pod             say "  $module ($status)";
+#pod         }
+#pod     }
+#pod
+#pod =head1 DESCRIPTION
+#pod
+#pod Software distributions released to the CPAN include a F<META.json> or, for
+#pod older distributions, F<META.yml>, which describes the distribution, its
+#pod contents, and the requirements for building and installing the distribution.
+#pod The data structure stored in the F<META.json> file is described in
+#pod L<CPAN::Meta::Spec>.
+#pod
+#pod CPAN::Meta provides a simple class to represent this distribution metadata (or
+#pod I<distmeta>), along with some helpful methods for interrogating that data.
+#pod
+#pod The documentation below is only for the methods of the CPAN::Meta object.  For
+#pod information on the meaning of individual fields, consult the spec.
+#pod
+#pod =cut
 
 use Carp qw(carp croak);
 use CPAN::Meta::Feature;
@@ -61,22 +61,22 @@ use Parse::CPAN::Meta 1.4414 ();
 
 BEGIN { *_dclone = \&CPAN::Meta::Converter::_dclone }
 
-# =head1 STRING DATA
-#
-# The following methods return a single value, which is the value for the
-# corresponding entry in the distmeta structure.  Values should be either undef
-# or strings.
-#
-# =for :list
-# * abstract
-# * description
-# * dynamic_config
-# * generated_by
-# * name
-# * release_status
-# * version
-#
-# =cut
+#pod =head1 STRING DATA
+#pod
+#pod The following methods return a single value, which is the value for the
+#pod corresponding entry in the distmeta structure.  Values should be either undef
+#pod or strings.
+#pod
+#pod =for :list
+#pod * abstract
+#pod * description
+#pod * dynamic_config
+#pod * generated_by
+#pod * name
+#pod * release_status
+#pod * version
+#pod
+#pod =cut
 
 BEGIN {
   my @STRING_READERS = qw(
@@ -95,20 +95,20 @@ BEGIN {
   }
 }
 
-# =head1 LIST DATA
-#
-# These methods return lists of string values, which might be represented in the
-# distmeta structure as arrayrefs or scalars:
-#
-# =for :list
-# * authors
-# * keywords
-# * licenses
-#
-# The C<authors> and C<licenses> methods may also be called as C<author> and
-# C<license>, respectively, to match the field name in the distmeta structure.
-#
-# =cut
+#pod =head1 LIST DATA
+#pod
+#pod These methods return lists of string values, which might be represented in the
+#pod distmeta structure as arrayrefs or scalars:
+#pod
+#pod =for :list
+#pod * authors
+#pod * keywords
+#pod * licenses
+#pod
+#pod The C<authors> and C<licenses> methods may also be called as C<author> and
+#pod C<license>, respectively, to match the field name in the distmeta structure.
+#pod
+#pod =cut
 
 BEGIN {
   my @LIST_READERS = qw(
@@ -132,20 +132,20 @@ BEGIN {
 sub authors  { $_[0]->author }
 sub licenses { $_[0]->license }
 
-# =head1 MAP DATA
-#
-# These readers return hashrefs of arbitrary unblessed data structures, each
-# described more fully in the specification:
-#
-# =for :list
-# * meta_spec
-# * resources
-# * provides
-# * no_index
-# * prereqs
-# * optional_features
-#
-# =cut
+#pod =head1 MAP DATA
+#pod
+#pod These readers return hashrefs of arbitrary unblessed data structures, each
+#pod described more fully in the specification:
+#pod
+#pod =for :list
+#pod * meta_spec
+#pod * resources
+#pod * provides
+#pod * no_index
+#pod * prereqs
+#pod * optional_features
+#pod
+#pod =cut
 
 BEGIN {
   my @MAP_READERS = qw(
@@ -169,16 +169,16 @@ BEGIN {
   }
 }
 
-# =head1 CUSTOM DATA
-#
-# A list of custom keys are available from the C<custom_keys> method and
-# particular keys may be retrieved with the C<custom> method.
-#
-#   say $meta->custom($_) for $meta->custom_keys;
-#
-# If a custom key refers to a data structure, a deep clone is returned.
-#
-# =cut
+#pod =head1 CUSTOM DATA
+#pod
+#pod A list of custom keys are available from the C<custom_keys> method and
+#pod particular keys may be retrieved with the C<custom> method.
+#pod
+#pod   say $meta->custom($_) for $meta->custom_keys;
+#pod
+#pod If a custom key refers to a data structure, a deep clone is returned.
+#pod
+#pod =cut
 
 sub custom_keys {
   return grep { /^x_/i } keys %{$_[0]};
@@ -191,29 +191,29 @@ sub custom {
   return $value;
 }
 
-# =method new
-#
-#   my $meta = CPAN::Meta->new($distmeta_struct, \%options);
-#
-# Returns a valid CPAN::Meta object or dies if the supplied metadata hash
-# reference fails to validate.  Older-format metadata will be up-converted to
-# version 2 if they validate against the original stated specification.
-#
-# It takes an optional hashref of options. Valid options include:
-#
-# =over
-#
-# =item *
-#
-# lazy_validation -- if true, new will attempt to convert the given metadata
-# to version 2 before attempting to validate it.  This means than any
-# fixable errors will be handled by CPAN::Meta::Converter before validation.
-# (Note that this might result in invalid optional data being silently
-# dropped.)  The default is false.
-#
-# =back
-#
-# =cut
+#pod =method new
+#pod
+#pod   my $meta = CPAN::Meta->new($distmeta_struct, \%options);
+#pod
+#pod Returns a valid CPAN::Meta object or dies if the supplied metadata hash
+#pod reference fails to validate.  Older-format metadata will be up-converted to
+#pod version 2 if they validate against the original stated specification.
+#pod
+#pod It takes an optional hashref of options. Valid options include:
+#pod
+#pod =over
+#pod
+#pod =item *
+#pod
+#pod lazy_validation -- if true, new will attempt to convert the given metadata
+#pod to version 2 before attempting to validate it.  This means than any
+#pod fixable errors will be handled by CPAN::Meta::Converter before validation.
+#pod (Note that this might result in invalid optional data being silently
+#pod dropped.)  The default is false.
+#pod
+#pod =back
+#pod
+#pod =cut
 
 sub _new {
   my ($class, $struct, $options) = @_;
@@ -254,15 +254,15 @@ sub new {
   return $self;
 }
 
-# =method create
-#
-#   my $meta = CPAN::Meta->create($distmeta_struct, \%options);
-#
-# This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
-# will be generated if not provided.  This means the metadata structure is
-# assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
-#
-# =cut
+#pod =method create
+#pod
+#pod   my $meta = CPAN::Meta->create($distmeta_struct, \%options);
+#pod
+#pod This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
+#pod will be generated if not provided.  This means the metadata structure is
+#pod assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
+#pod
+#pod =cut
 
 sub create {
   my ($class, $struct, $options) = @_;
@@ -274,19 +274,19 @@ sub create {
   return $self;
 }
 
-# =method load_file
-#
-#   my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
-#
-# Given a pathname to a file containing metadata, this deserializes the file
-# according to its file suffix and constructs a new C<CPAN::Meta> object, just
-# like C<new()>.  It will die if the deserialized version fails to validate
-# against its stated specification version.
-#
-# It takes the same options as C<new()> but C<lazy_validation> defaults to
-# true.
-#
-# =cut
+#pod =method load_file
+#pod
+#pod   my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
+#pod
+#pod Given a pathname to a file containing metadata, this deserializes the file
+#pod according to its file suffix and constructs a new C<CPAN::Meta> object, just
+#pod like C<new()>.  It will die if the deserialized version fails to validate
+#pod against its stated specification version.
+#pod
+#pod It takes the same options as C<new()> but C<lazy_validation> defaults to
+#pod true.
+#pod
+#pod =cut
 
 sub load_file {
   my ($class, $file, $options) = @_;
@@ -304,14 +304,14 @@ sub load_file {
   return $self;
 }
 
-# =method load_yaml_string
-#
-#   my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
-#
-# This method returns a new CPAN::Meta object using the first document in the
-# given YAML string.  In other respects it is identical to C<load_file()>.
-#
-# =cut
+#pod =method load_yaml_string
+#pod
+#pod   my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
+#pod
+#pod This method returns a new CPAN::Meta object using the first document in the
+#pod given YAML string.  In other respects it is identical to C<load_file()>.
+#pod
+#pod =cut
 
 sub load_yaml_string {
   my ($class, $yaml, $options) = @_;
@@ -326,14 +326,14 @@ sub load_yaml_string {
   return $self;
 }
 
-# =method load_json_string
-#
-#   my $meta = CPAN::Meta->load_json_string($json, \%options);
-#
-# This method returns a new CPAN::Meta object using the structure represented by
-# the given JSON string.  In other respects it is identical to C<load_file()>.
-#
-# =cut
+#pod =method load_json_string
+#pod
+#pod   my $meta = CPAN::Meta->load_json_string($json, \%options);
+#pod
+#pod This method returns a new CPAN::Meta object using the structure represented by
+#pod the given JSON string.  In other respects it is identical to C<load_file()>.
+#pod
+#pod =cut
 
 sub load_json_string {
   my ($class, $json, $options) = @_;
@@ -348,15 +348,15 @@ sub load_json_string {
   return $self;
 }
 
-# =method load_string
-#
-#   my $meta = CPAN::Meta->load_string($string, \%options);
-#
-# If you don't know if a string contains YAML or JSON, this method will use
-# L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
-# C<load_file()>.
-#
-# =cut
+#pod =method load_string
+#pod
+#pod   my $meta = CPAN::Meta->load_string($string, \%options);
+#pod
+#pod If you don't know if a string contains YAML or JSON, this method will use
+#pod L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
+#pod C<load_file()>.
+#pod
+#pod =cut
 
 sub load_string {
   my ($class, $string, $options) = @_;
@@ -371,27 +371,27 @@ sub load_string {
   return $self;
 }
 
-# =method save
-#
-#   $meta->save($distmeta_file, \%options);
-#
-# Serializes the object as JSON and writes it to the given file.  The only valid
-# option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
-# is saved with UTF-8 encoding.
-#
-# For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
-# is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
-# later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
-# backend like L<JSON::XS>.
-#
-# For C<version> less than 2, the filename should end in '.yml'.
-# L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
-# is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
-# set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
-# this is not recommended due to subtle incompatibilities between YAML parsers on
-# CPAN.
-#
-# =cut
+#pod =method save
+#pod
+#pod   $meta->save($distmeta_file, \%options);
+#pod
+#pod Serializes the object as JSON and writes it to the given file.  The only valid
+#pod option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
+#pod is saved with UTF-8 encoding.
+#pod
+#pod For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
+#pod is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
+#pod later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
+#pod backend like L<JSON::XS>.
+#pod
+#pod For C<version> less than 2, the filename should end in '.yml'.
+#pod L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
+#pod is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
+#pod set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
+#pod this is not recommended due to subtle incompatibilities between YAML parsers on
+#pod CPAN.
+#pod
+#pod =cut
 
 sub save {
   my ($self, $file, $options) = @_;
@@ -419,32 +419,32 @@ sub save {
   return 1;
 }
 
-# =method meta_spec_version
-#
-# This method returns the version part of the C<meta_spec> entry in the distmeta
-# structure.  It is equivalent to:
-#
-#   $meta->meta_spec->{version};
-#
-# =cut
+#pod =method meta_spec_version
+#pod
+#pod This method returns the version part of the C<meta_spec> entry in the distmeta
+#pod structure.  It is equivalent to:
+#pod
+#pod   $meta->meta_spec->{version};
+#pod
+#pod =cut
 
 sub meta_spec_version {
   my ($self) = @_;
   return $self->meta_spec->{version};
 }
 
-# =method effective_prereqs
-#
-#   my $prereqs = $meta->effective_prereqs;
-#
-#   my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
-#
-# This method returns a L<CPAN::Meta::Prereqs> object describing all the
-# prereqs for the distribution.  If an arrayref of feature identifiers is given,
-# the prereqs for the identified features are merged together with the
-# distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
-#
-# =cut
+#pod =method effective_prereqs
+#pod
+#pod   my $prereqs = $meta->effective_prereqs;
+#pod
+#pod   my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
+#pod
+#pod This method returns a L<CPAN::Meta::Prereqs> object describing all the
+#pod prereqs for the distribution.  If an arrayref of feature identifiers is given,
+#pod the prereqs for the identified features are merged together with the
+#pod distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
+#pod
+#pod =cut
 
 sub effective_prereqs {
   my ($self, $features) = @_;
@@ -459,17 +459,17 @@ sub effective_prereqs {
   return $prereq->with_merged_prereqs(\@other);
 }
 
-# =method should_index_file
-#
-#   ... if $meta->should_index_file( $filename );
-#
-# 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.
-#
-# C<$filename> should be given in unix format.
-#
-# =cut
+#pod =method should_index_file
+#pod
+#pod   ... if $meta->should_index_file( $filename );
+#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
+#pod C<$filename> should be given in unix format.
+#pod
+#pod =cut
 
 sub should_index_file {
   my ($self, $filename) = @_;
@@ -486,15 +486,15 @@ sub should_index_file {
   return 1;
 }
 
-# =method should_index_package
-#
-#   ... if $meta->should_index_package( $package );
-#
-# 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.
-#
-# =cut
+#pod =method should_index_package
+#pod
+#pod   ... if $meta->should_index_package( $package );
+#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
+#pod =cut
 
 sub should_index_package {
   my ($self, $package) = @_;
@@ -510,14 +510,14 @@ sub should_index_package {
   return 1;
 }
 
-# =method features
-#
-#   my @feature_objects = $meta->features;
-#
-# This method returns a list of L<CPAN::Meta::Feature> objects, one for each
-# optional feature described by the distribution's metadata.
-#
-# =cut
+#pod =method features
+#pod
+#pod   my @feature_objects = $meta->features;
+#pod
+#pod This method returns a list of L<CPAN::Meta::Feature> objects, one for each
+#pod optional feature described by the distribution's metadata.
+#pod
+#pod =cut
 
 sub features {
   my ($self) = @_;
@@ -529,15 +529,15 @@ sub features {
   return @features;
 }
 
-# =method feature
-#
-#   my $feature_object = $meta->feature( $identifier );
-#
-# This method returns a L<CPAN::Meta::Feature> object for the optional feature
-# with the given identifier.  If no feature with that identifier exists, an
-# exception will be raised.
-#
-# =cut
+#pod =method feature
+#pod
+#pod   my $feature_object = $meta->feature( $identifier );
+#pod
+#pod This method returns a L<CPAN::Meta::Feature> object for the optional feature
+#pod with the given identifier.  If no feature with that identifier exists, an
+#pod exception will be raised.
+#pod
+#pod =cut
 
 sub feature {
   my ($self, $ident) = @_;
@@ -548,18 +548,18 @@ sub feature {
   return CPAN::Meta::Feature->new($ident, $f);
 }
 
-# =method as_struct
-#
-#   my $copy = $meta->as_struct( \%options );
-#
-# This method returns a deep copy of the object's metadata as an unblessed hash
-# reference.  It takes an optional hashref of options.  If the hashref contains
-# a C<version> argument, the copied metadata will be converted to the version
-# of the specification and returned.  For example:
-#
-#   my $old_spec = $meta->as_struct( {version => "1.4"} );
-#
-# =cut
+#pod =method as_struct
+#pod
+#pod   my $copy = $meta->as_struct( \%options );
+#pod
+#pod This method returns a deep copy of the object's metadata as an unblessed hash
+#pod reference.  It takes an optional hashref of options.  If the hashref contains
+#pod a C<version> argument, the copied metadata will be converted to the version
+#pod of the specification and returned.  For example:
+#pod
+#pod   my $old_spec = $meta->as_struct( {version => "1.4"} );
+#pod
+#pod =cut
 
 sub as_struct {
   my ($self, $options) = @_;
@@ -571,24 +571,24 @@ sub as_struct {
   return $struct;
 }
 
-# =method as_string
-#
-#   my $string = $meta->as_string( \%options );
-#
-# This method returns a serialized copy of the object's metadata as a character
-# string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
-# of options.  If the hashref contains a C<version> argument, the copied metadata
-# will be converted to the version of the specification and returned.  For
-# example:
-#
-#   my $string = $meta->as_string( {version => "1.4"} );
-#
-# For C<version> greater than or equal to 2, the string will be serialized as
-# JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
-# both cases, the same rules are followed as in the C<save()> method for choosing
-# a serialization backend.
-#
-# =cut
+#pod =method as_string
+#pod
+#pod   my $string = $meta->as_string( \%options );
+#pod
+#pod This method returns a serialized copy of the object's metadata as a character
+#pod string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
+#pod of options.  If the hashref contains a C<version> argument, the copied metadata
+#pod will be converted to the version of the specification and returned.  For
+#pod example:
+#pod
+#pod   my $string = $meta->as_string( {version => "1.4"} );
+#pod
+#pod For C<version> greater than or equal to 2, the string will be serialized as
+#pod JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
+#pod both cases, the same rules are followed as in the C<save()> method for choosing
+#pod a serialization backend.
+#pod
+#pod =cut
 
 sub as_string {
   my ($self, $options) = @_;
@@ -641,7 +641,7 @@ CPAN::Meta - the distribution metadata for a CPAN dist
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 SYNOPSIS
 
@@ -1080,6 +1080,10 @@ Mark Fowler <markf at cpan.org>
 
 =item *
 
+Matt S Trout <mst at shadowcat.co.uk>
+
+=item *
+
 Michael G. Schwern <mschwern at cpan.org>
 
 =item *
@@ -1094,6 +1098,10 @@ Olivier Mengue <dolmen at cpan.org>
 
 Randy Sims <randys at thepierianspring.org>
 
+=item *
+
+moznion <moznion at gmail.com>
+
 =back
 
 =head1 COPYRIGHT AND LICENSE
diff --git a/lib/CPAN/Meta/Converter.pm b/lib/CPAN/Meta/Converter.pm
index 1bb4431..4917753 100644
--- a/lib/CPAN/Meta/Converter.pm
+++ b/lib/CPAN/Meta/Converter.pm
@@ -2,31 +2,30 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::Converter;
-our $VERSION = '2.140640'; # VERSION
-
-# =head1 SYNOPSIS
-#
-#   my $struct = decode_json_file('META.json');
-#
-#   my $cmc = CPAN::Meta::Converter->new( $struct );
-#
-#   my $new_struct = $cmc->convert( version => "2" );
-#
-# =head1 DESCRIPTION
-#
-# This module converts CPAN Meta structures from one form to another.  The
-# primary use is to convert older structures to the most modern version of
-# the specification, but other transformations may be implemented in the
-# future as needed.  (E.g. stripping all custom fields or stripping all
-# optional fields.)
-#
-# =cut
+our $VERSION = '2.141170'; # VERSION
+
+#pod =head1 SYNOPSIS
+#pod
+#pod   my $struct = decode_json_file('META.json');
+#pod
+#pod   my $cmc = CPAN::Meta::Converter->new( $struct );
+#pod
+#pod   my $new_struct = $cmc->convert( version => "2" );
+#pod
+#pod =head1 DESCRIPTION
+#pod
+#pod This module converts CPAN Meta structures from one form to another.  The
+#pod primary use is to convert older structures to the most modern version of
+#pod the specification, but other transformations may be implemented in the
+#pod future as needed.  (E.g. stripping all custom fields or stripping all
+#pod optional fields.)
+#pod
+#pod =cut
 
 use CPAN::Meta::Validator;
 use CPAN::Meta::Requirements;
 use version 0.88 ();
 use Parse::CPAN::Meta 1.4400 ();
-use List::Util 1.33 qw/all/;
 
 sub _dclone {
   my $ref = shift;
@@ -36,12 +35,14 @@ sub _dclone {
   # right thing for typical things that might be there, like version objects,
   # Path::Class objects, etc.
   no warnings 'once';
-  local *UNIVERSAL::TO_JSON = sub { return "$_[0]" };
-
-  my $backend = Parse::CPAN::Meta->json_backend();
-  return $backend->new->utf8->decode(
-    $backend->new->utf8->allow_blessed->convert_blessed->encode($ref)
-  );
+  no warnings 'redefine';
+  local *UNIVERSAL::TO_JSON = sub { "$_[0]" };
+
+  my $json = Parse::CPAN::Meta->json_backend()->new
+      ->utf8
+      ->allow_blessed
+      ->convert_blessed;
+  $json->decode($json->encode($ref))
 }
 
 my %known_specs = (
@@ -247,11 +248,11 @@ sub _downgrade_license {
   }
   elsif( ref $element eq 'ARRAY' ) {
     if ( @$element > 1) {
-      if ( all { $is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element ) {
-        return 'open_source';
+      if (grep { !$is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element) {
+        return 'unknown';
       }
       else {
-        return 'unknown';
+        return 'open_source';
       }
     }
     elsif ( @$element == 1 ) {
@@ -682,7 +683,7 @@ sub _resources_1_2 {
   my (undef, undef, $meta) = @_;
   my $resources = $meta->{resources} || {};
   if ( $meta->{license_url} && ! $resources->{license} ) {
-    $resources->{license} = $meta->license_url
+    $resources->{license} = $meta->{license_url}
       if _is_urlish($meta->{license_url});
   }
   return unless keys %$resources;
@@ -1230,27 +1231,80 @@ my %cleanup = (
   },
 );
 
+# for a given field in a spec version, what fields will it feed
+# into in the *latest* spec (i.e. v2); meta-spec omitted because
+# we always expect a meta-spec to be generated
+my %fragments_generate = (
+  '2' => {
+    'abstract'            =>   'abstract',
+    'author'              =>   'author',
+    'generated_by'        =>   'generated_by',
+    'license'             =>   'license',
+    'name'                =>   'name',
+    'version'             =>   'version',
+    'dynamic_config'      =>   'dynamic_config',
+    'release_status'      =>   'release_status',
+    'keywords'            =>   'keywords',
+    'no_index'            =>   'no_index',
+    'optional_features'   =>   'optional_features',
+    'provides'            =>   'provides',
+    'resources'           =>   'resources',
+    'description'         =>   'description',
+    'prereqs'             =>   'prereqs',
+  },
+  '1.4' => {
+    'abstract'            => 'abstract',
+    'author'              => 'author',
+    'generated_by'        => 'generated_by',
+    'license'             => 'license',
+    'name'                => 'name',
+    'version'             => 'version',
+    'build_requires'      => 'prereqs',
+    'conflicts'           => 'prereqs',
+    'distribution_type'   => 'distribution_type',
+    'dynamic_config'      => 'dynamic_config',
+    'keywords'            => 'keywords',
+    'no_index'            => 'no_index',
+    'optional_features'   => 'optional_features',
+    'provides'            => 'provides',
+    'recommends'          => 'prereqs',
+    'requires'            => 'prereqs',
+    'resources'           => 'resources',
+    'configure_requires'  => 'prereqs',
+  },
+);
+# this is not quite true but will work well enough
+# as 1.4 is a superset of earlier ones
+$fragments_generate{$_} = $fragments_generate{'1.4'} for qw/1.3 1.2 1.1 1.0/;
+
 #--------------------------------------------------------------------------#
 # Code
 #--------------------------------------------------------------------------#
 
-# =method new
-#
-#   my $cmc = CPAN::Meta::Converter->new( $struct );
-#
-# The constructor should be passed a valid metadata structure but invalid
-# structures are accepted.  If no meta-spec version is provided, version 1.0 will
-# be assumed.
-#
-# =cut
+#pod =method new
+#pod
+#pod   my $cmc = CPAN::Meta::Converter->new( $struct );
+#pod
+#pod The constructor should be passed a valid metadata structure but invalid
+#pod structures are accepted.  If no meta-spec version is provided, version 1.0 will
+#pod be assumed.
+#pod
+#pod Optionally, you can provide a C<default_version> argument after C<$struct>:
+#pod
+#pod   my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
+#pod
+#pod This is only needed when converting a metadata fragment that does not include a
+#pod C<meta-spec> field.
+#pod
+#pod =cut
 
 sub new {
-  my ($class,$data) = @_;
+  my ($class,$data,%args) = @_;
 
   # create an attributes hash
   my $self = {
     'data'    => $data,
-    'spec'    => _extract_spec_version($data),
+    'spec'    => _extract_spec_version($data, $args{default_version}),
   };
 
   # create the object
@@ -1258,11 +1312,11 @@ sub new {
 }
 
 sub _extract_spec_version {
-    my ($data) = @_;
+    my ($data, $default) = @_;
     my $spec = $data->{'meta-spec'};
 
     # is meta-spec there and valid?
-    return "1.0" unless defined $spec && ref $spec eq 'HASH'; # before meta-spec?
+    return( $default || "1.0" ) unless defined $spec && ref $spec eq 'HASH'; # before meta-spec?
 
     # does the version key look like a valid version?
     my $v = $spec->{version};
@@ -1274,56 +1328,56 @@ sub _extract_spec_version {
     # otherwise, use heuristics: look for 1.x vs 2.0 fields
     return "2" if exists $data->{prereqs};
     return "1.4" if exists $data->{configure_requires};
-    return "1.2"; # when meta-spec was first defined
+    return( $default || "1.2" ); # when meta-spec was first defined
 }
 
-# =method convert
-#
-#   my $new_struct = $cmc->convert( version => "2" );
-#
-# Returns a new hash reference with the metadata converted to a different form.
-# C<convert> will die if any conversion/standardization still results in an
-# invalid structure.
-#
-# Valid parameters include:
-#
-# =over
-#
-# =item *
-#
-# C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
-# Defaults to the latest version of the CPAN Meta Spec.
-#
-# =back
-#
-# Conversion proceeds through each version in turn.  For example, a version 1.2
-# structure might be converted to 1.3 then 1.4 then finally to version 2. The
-# conversion process attempts to clean-up simple errors and standardize data.
-# For example, if C<author> is given as a scalar, it will converted to an array
-# reference containing the item. (Converting a structure to its own version will
-# also clean-up and standardize.)
-#
-# When data are cleaned and standardized, missing or invalid fields will be
-# replaced with sensible defaults when possible.  This may be lossy or imprecise.
-# For example, some badly structured META.yml files on CPAN have prerequisite
-# modules listed as both keys and values:
-#
-#   requires => { 'Foo::Bar' => 'Bam::Baz' }
-#
-# These would be split and each converted to a prerequisite with a minimum
-# version of zero.
-#
-# When some mandatory fields are missing or invalid, the conversion will attempt
-# to provide a sensible default or will fill them with a value of 'unknown'.  For
-# example a missing or unrecognized C<license> field will result in a C<license>
-# field of 'unknown'.  Fields that may get an 'unknown' include:
-#
-# =for :list
-# * abstract
-# * author
-# * license
-#
-# =cut
+#pod =method convert
+#pod
+#pod   my $new_struct = $cmc->convert( version => "2" );
+#pod
+#pod Returns a new hash reference with the metadata converted to a different form.
+#pod C<convert> will die if any conversion/standardization still results in an
+#pod invalid structure.
+#pod
+#pod Valid parameters include:
+#pod
+#pod =over
+#pod
+#pod =item *
+#pod
+#pod C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
+#pod Defaults to the latest version of the CPAN Meta Spec.
+#pod
+#pod =back
+#pod
+#pod Conversion proceeds through each version in turn.  For example, a version 1.2
+#pod structure might be converted to 1.3 then 1.4 then finally to version 2. The
+#pod conversion process attempts to clean-up simple errors and standardize data.
+#pod For example, if C<author> is given as a scalar, it will converted to an array
+#pod reference containing the item. (Converting a structure to its own version will
+#pod also clean-up and standardize.)
+#pod
+#pod When data are cleaned and standardized, missing or invalid fields will be
+#pod replaced with sensible defaults when possible.  This may be lossy or imprecise.
+#pod For example, some badly structured META.yml files on CPAN have prerequisite
+#pod modules listed as both keys and values:
+#pod
+#pod   requires => { 'Foo::Bar' => 'Bam::Baz' }
+#pod
+#pod These would be split and each converted to a prerequisite with a minimum
+#pod version of zero.
+#pod
+#pod When some mandatory fields are missing or invalid, the conversion will attempt
+#pod to provide a sensible default or will fill them with a value of 'unknown'.  For
+#pod example a missing or unrecognized C<license> field will result in a C<license>
+#pod field of 'unknown'.  Fields that may get an 'unknown' include:
+#pod
+#pod =for :list
+#pod * abstract
+#pod * author
+#pod * license
+#pod
+#pod =cut
 
 sub convert {
   my ($self, %args) = @_;
@@ -1336,10 +1390,12 @@ sub convert {
 
   if ( $old_version == $new_version ) {
     $converted = _convert( $converted, $cleanup{$old_version}, $old_version );
-    my $cmv = CPAN::Meta::Validator->new( $converted );
-    unless ( $cmv->is_valid ) {
-      my $errs = join("\n", $cmv->errors);
-      die "Failed to clean-up $old_version metadata. Errors:\n$errs\n";
+    unless ( $args->{no_validation} ) {
+      my $cmv = CPAN::Meta::Validator->new( $converted );
+      unless ( $cmv->is_valid ) {
+        my $errs = join("\n", $cmv->errors);
+        die "Failed to clean-up $old_version metadata. Errors:\n$errs\n";
+      }
     }
     return $converted;
   }
@@ -1350,10 +1406,12 @@ sub convert {
       last if $vers[$i+1] < $new_version;
       my $spec_string = "$vers[$i+1]-from-$vers[$i]";
       $converted = _convert( $converted, $down_convert{$spec_string}, $vers[$i+1] );
-      my $cmv = CPAN::Meta::Validator->new( $converted );
-      unless ( $cmv->is_valid ) {
-        my $errs = join("\n", $cmv->errors);
-        die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
+      unless ( $args->{no_validation} ) {
+        my $cmv = CPAN::Meta::Validator->new( $converted );
+        unless ( $cmv->is_valid ) {
+          my $errs = join("\n", $cmv->errors);
+          die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
+        }
       }
     }
     return $converted;
@@ -1365,22 +1423,48 @@ sub convert {
       last if $vers[$i+1] > $new_version;
       my $spec_string = "$vers[$i+1]-from-$vers[$i]";
       $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1] );
-      my $cmv = CPAN::Meta::Validator->new( $converted );
-      unless ( $cmv->is_valid ) {
-        my $errs = join("\n", $cmv->errors);
-        die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
+      unless ( $args->{no_validation} ) {
+        my $cmv = CPAN::Meta::Validator->new( $converted );
+        unless ( $cmv->is_valid ) {
+          my $errs = join("\n", $cmv->errors);
+          die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
+        }
       }
     }
     return $converted;
   }
 }
 
+#pod =method upgrade_fragment
+#pod
+#pod   my $new_struct = $cmc->upgrade_fragment;
+#pod
+#pod Returns a new hash reference with the metadata converted to the latest version
+#pod of the CPAN Meta Spec.  No validation is done on the result -- you must
+#pod validate after merging fragments into a complete metadata document.
+#pod
+#pod =cut
+
+sub upgrade_fragment {
+  my ($self) = @_;
+  my ($old_version) = $self->{spec};
+  my %expected =
+    map {; $_ => 1 }
+    grep { defined }
+    map { $fragments_generate{$old_version}{$_} }
+    keys %{ $self->{data} };
+  my $converted = $self->convert( version => $HIGHEST, no_validation => 1 );
+  for my $key ( keys %$converted ) {
+    next if $key =~ /^x_/i || $key eq 'meta-spec';
+    delete $converted->{$key} unless $expected{$key};
+  }
+  return $converted;
+}
+
 1;
 
 # ABSTRACT: Convert CPAN distribution metadata structures
 
-__END__
-
 =pod
 
 =encoding UTF-8
@@ -1391,7 +1475,7 @@ CPAN::Meta::Converter - Convert CPAN distribution metadata structures
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 SYNOPSIS
 
@@ -1419,6 +1503,13 @@ The constructor should be passed a valid metadata structure but invalid
 structures are accepted.  If no meta-spec version is provided, version 1.0 will
 be assumed.
 
+Optionally, you can provide a C<default_version> argument after C<$struct>:
+
+  my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
+
+This is only needed when converting a metadata fragment that does not include a
+C<meta-spec> field.
+
 =head2 convert
 
   my $new_struct = $cmc->convert( version => "2" );
@@ -1476,6 +1567,14 @@ license
 
 =back
 
+=head2 upgrade_fragment
+
+  my $new_struct = $cmc->upgrade_fragment;
+
+Returns a new hash reference with the metadata converted to the latest version
+of the CPAN Meta Spec.  No validation is done on the result -- you must
+validate after merging fragments into a complete metadata document.
+
 =head1 BUGS
 
 Please report any bugs or feature using the CPAN Request Tracker.
@@ -1507,3 +1606,8 @@ This is free software; you can redistribute it and/or modify it under
 the same terms as the Perl 5 programming language system itself.
 
 =cut
+
+__END__
+
+
+# vim: ts=2 sts=2 sw=2 et:
diff --git a/lib/CPAN/Meta/Feature.pm b/lib/CPAN/Meta/Feature.pm
index f97cc65..2014f86 100644
--- a/lib/CPAN/Meta/Feature.pm
+++ b/lib/CPAN/Meta/Feature.pm
@@ -2,28 +2,28 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::Feature;
-our $VERSION = '2.140640'; # VERSION
+our $VERSION = '2.141170'; # VERSION
 
 use CPAN::Meta::Prereqs;
 
-# =head1 DESCRIPTION
-#
-# A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
-# distribution and specified in the distribution's F<META.json> (or F<META.yml>)
-# file.
-#
-# For the most part, this class will only be used when operating on the result of
-# the C<feature> or C<features> methods on a L<CPAN::Meta> object.
-#
-# =method new
-#
-#   my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
-#
-# This returns a new Feature object.  The C<%spec> argument to the constructor
-# should be the same as the value of the C<optional_feature> entry in the
-# distmeta.  It must contain entries for C<description> and C<prereqs>.
-#
-# =cut
+#pod =head1 DESCRIPTION
+#pod
+#pod A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
+#pod distribution and specified in the distribution's F<META.json> (or F<META.yml>)
+#pod file.
+#pod
+#pod For the most part, this class will only be used when operating on the result of
+#pod the C<feature> or C<features> methods on a L<CPAN::Meta> object.
+#pod
+#pod =method new
+#pod
+#pod   my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
+#pod
+#pod This returns a new Feature object.  The C<%spec> argument to the constructor
+#pod should be the same as the value of the C<optional_feature> entry in the
+#pod distmeta.  It must contain entries for C<description> and C<prereqs>.
+#pod
+#pod =cut
 
 sub new {
   my ($class, $identifier, $spec) = @_;
@@ -37,28 +37,28 @@ sub new {
   bless \%guts => $class;
 }
 
-# =method identifier
-#
-# This method returns the feature's identifier.
-#
-# =cut
+#pod =method identifier
+#pod
+#pod This method returns the feature's identifier.
+#pod
+#pod =cut
 
 sub identifier  { $_[0]{identifier}  }
 
-# =method description
-#
-# This method returns the feature's long description.
-#
-# =cut
+#pod =method description
+#pod
+#pod This method returns the feature's long description.
+#pod
+#pod =cut
 
 sub description { $_[0]{description} }
 
-# =method prereqs
-#
-# This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
-# object.
-#
-# =cut
+#pod =method prereqs
+#pod
+#pod This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
+#pod object.
+#pod
+#pod =cut
 
 sub prereqs     { $_[0]{prereqs} }
 
@@ -78,7 +78,7 @@ CPAN::Meta::Feature - an optional feature provided by a CPAN distribution
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 DESCRIPTION
 
diff --git a/lib/CPAN/Meta/History.pm b/lib/CPAN/Meta/History.pm
index 1ebf389..33acc0a 100644
--- a/lib/CPAN/Meta/History.pm
+++ b/lib/CPAN/Meta/History.pm
@@ -3,7 +3,7 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::History;
-our $VERSION = '2.140640'; # VERSION
+our $VERSION = '2.141170'; # VERSION
 
 1;
 
@@ -21,7 +21,7 @@ CPAN::Meta::History - history of CPAN Meta Spec changes
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 DESCRIPTION
 
diff --git a/lib/CPAN/Meta/Prereqs.pm b/lib/CPAN/Meta/Prereqs.pm
index b6e6c73..fe369fe 100644
--- a/lib/CPAN/Meta/Prereqs.pm
+++ b/lib/CPAN/Meta/Prereqs.pm
@@ -2,47 +2,47 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::Prereqs;
-our $VERSION = '2.140640'; # VERSION
+our $VERSION = '2.141170'; # VERSION
 
-# =head1 DESCRIPTION
-#
-# A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
-# distribution or one of its optional features.  Each set of prereqs is
-# organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
-#
-# =cut
+#pod =head1 DESCRIPTION
+#pod
+#pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
+#pod distribution or one of its optional features.  Each set of prereqs is
+#pod organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
+#pod
+#pod =cut
 
 use Carp qw(confess);
 use Scalar::Util qw(blessed);
 use CPAN::Meta::Requirements 2.121;
 
-# =method new
-#
-#   my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
-#
-# This method returns a new set of Prereqs.  The input should look like the
-# contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
-# something more or less like this:
-#
-#   my $prereq = CPAN::Meta::Prereqs->new({
-#     runtime => {
-#       requires => {
-#         'Some::Module' => '1.234',
-#         ...,
-#       },
-#       ...,
-#     },
-#     ...,
-#   });
-#
-# You can also construct an empty set of prereqs with:
-#
-#   my $prereqs = CPAN::Meta::Prereqs->new;
-#
-# This empty set of prereqs is useful for accumulating new prereqs before finally
-# dumping the whole set into a structure or string.
-#
-# =cut
+#pod =method new
+#pod
+#pod   my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
+#pod
+#pod This method returns a new set of Prereqs.  The input should look like the
+#pod contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
+#pod something more or less like this:
+#pod
+#pod   my $prereq = CPAN::Meta::Prereqs->new({
+#pod     runtime => {
+#pod       requires => {
+#pod         'Some::Module' => '1.234',
+#pod         ...,
+#pod       },
+#pod       ...,
+#pod     },
+#pod     ...,
+#pod   });
+#pod
+#pod You can also construct an empty set of prereqs with:
+#pod
+#pod   my $prereqs = CPAN::Meta::Prereqs->new;
+#pod
+#pod This empty set of prereqs is useful for accumulating new prereqs before finally
+#pod dumping the whole set into a structure or string.
+#pod
+#pod =cut
 
 sub __legal_phases { qw(configure build test runtime develop)   }
 sub __legal_types  { qw(requires recommends suggests conflicts) }
@@ -78,19 +78,19 @@ sub new {
   return bless \%guts => $class;
 }
 
-# =method requirements_for
-#
-#   my $requirements = $prereqs->requirements_for( $phase, $type );
-#
-# This method returns a L<CPAN::Meta::Requirements> object for the given
-# phase/type combination.  If no prerequisites are registered for that
-# combination, a new CPAN::Meta::Requirements object will be returned, and it may
-# be added to as needed.
-#
-# If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
-# be raised.
-#
-# =cut
+#pod =method requirements_for
+#pod
+#pod   my $requirements = $prereqs->requirements_for( $phase, $type );
+#pod
+#pod This method returns a L<CPAN::Meta::Requirements> object for the given
+#pod phase/type combination.  If no prerequisites are registered for that
+#pod combination, a new CPAN::Meta::Requirements object will be returned, and it may
+#pod be added to as needed.
+#pod
+#pod If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
+#pod be raised.
+#pod
+#pod =cut
 
 sub requirements_for {
   my ($self, $phase, $type) = @_;
@@ -113,21 +113,21 @@ sub requirements_for {
   return $req;
 }
 
-# =method with_merged_prereqs
-#
-#   my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
-#
-#   my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
-#
-# This method returns a new CPAN::Meta::Prereqs objects in which all the
-# other prerequisites given are merged into the current set.  This is primarily
-# provided for combining a distribution's core prereqs with the prereqs of one of
-# its optional features.
-#
-# The new prereqs object has no ties to the originals, and altering it further
-# will not alter them.
-#
-# =cut
+#pod =method with_merged_prereqs
+#pod
+#pod   my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
+#pod
+#pod   my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
+#pod
+#pod This method returns a new CPAN::Meta::Prereqs objects in which all the
+#pod other prerequisites given are merged into the current set.  This is primarily
+#pod provided for combining a distribution's core prereqs with the prereqs of one of
+#pod its optional features.
+#pod
+#pod The new prereqs object has no ties to the originals, and altering it further
+#pod will not alter them.
+#pod
+#pod =cut
 
 sub with_merged_prereqs {
   my ($self, $other) = @_;
@@ -158,18 +158,18 @@ sub with_merged_prereqs {
   return (ref $self)->new(\%new_arg);
 }
 
-# =method merged_requirements
-#
-#     my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
-#     my $new_reqs = $prereqs->merged_requirements( \@phases );
-#     my $new_reqs = $preerqs->merged_requirements();
-#
-# This method joins together all requirements across a number of phases
-# and types into a new L<CPAN::Meta::Requirements> object.  If arguments
-# are omitted, it defaults to "runtime", "build" and "test" for phases
-# and "requires" and "recommends" for types.
-#
-# =cut
+#pod =method merged_requirements
+#pod
+#pod     my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
+#pod     my $new_reqs = $prereqs->merged_requirements( \@phases );
+#pod     my $new_reqs = $preerqs->merged_requirements();
+#pod
+#pod This method joins together all requirements across a number of phases
+#pod and types into a new L<CPAN::Meta::Requirements> object.  If arguments
+#pod are omitted, it defaults to "runtime", "build" and "test" for phases
+#pod and "requires" and "recommends" for types.
+#pod
+#pod =cut
 
 sub merged_requirements {
   my ($self, $phases, $types) = @_;
@@ -201,13 +201,13 @@ sub merged_requirements {
 }
 
 
-# =method as_string_hash
-#
-# This method returns a hashref containing structures suitable for dumping into a
-# distmeta data structure.  It is made up of hashes and strings, only; there will
-# be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
-#
-# =cut
+#pod =method as_string_hash
+#pod
+#pod This method returns a hashref containing structures suitable for dumping into a
+#pod distmeta data structure.  It is made up of hashes and strings, only; there will
+#pod be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
+#pod
+#pod =cut
 
 sub as_string_hash {
   my ($self) = @_;
@@ -226,22 +226,22 @@ sub as_string_hash {
   return \%hash;
 }
 
-# =method is_finalized
-#
-# This method returns true if the set of prereqs has been marked "finalized," and
-# cannot be altered.
-#
-# =cut
+#pod =method is_finalized
+#pod
+#pod This method returns true if the set of prereqs has been marked "finalized," and
+#pod cannot be altered.
+#pod
+#pod =cut
 
 sub is_finalized { $_[0]{finalized} }
 
-# =method finalize
-#
-# Calling C<finalize> on a Prereqs object will close it for further modification.
-# Attempting to make any changes that would actually alter the prereqs will
-# result in an exception being thrown.
-#
-# =cut
+#pod =method finalize
+#pod
+#pod Calling C<finalize> on a Prereqs object will close it for further modification.
+#pod Attempting to make any changes that would actually alter the prereqs will
+#pod result in an exception being thrown.
+#pod
+#pod =cut
 
 sub finalize {
   my ($self) = @_;
@@ -253,16 +253,16 @@ sub finalize {
   }
 }
 
-# =method clone
-#
-#   my $cloned_prereqs = $prereqs->clone;
-#
-# This method returns a Prereqs object that is identical to the original object,
-# but can be altered without affecting the original object.  Finalization does
-# not survive cloning, meaning that you may clone a finalized set of prereqs and
-# then modify the clone.
-#
-# =cut
+#pod =method clone
+#pod
+#pod   my $cloned_prereqs = $prereqs->clone;
+#pod
+#pod This method returns a Prereqs object that is identical to the original object,
+#pod but can be altered without affecting the original object.  Finalization does
+#pod not survive cloning, meaning that you may clone a finalized set of prereqs and
+#pod then modify the clone.
+#pod
+#pod =cut
 
 sub clone {
   my ($self) = @_;
@@ -286,7 +286,7 @@ CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 DESCRIPTION
 
diff --git a/lib/CPAN/Meta/Spec.pm b/lib/CPAN/Meta/Spec.pm
index 1ec27af..1739de8 100644
--- a/lib/CPAN/Meta/Spec.pm
+++ b/lib/CPAN/Meta/Spec.pm
@@ -7,7 +7,7 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::Spec;
-our $VERSION = '2.140640'; # VERSION
+our $VERSION = '2.141170'; # VERSION
 
 1;
 
@@ -28,7 +28,7 @@ CPAN::Meta::Spec - specification for CPAN distribution metadata
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 SYNOPSIS
 
@@ -289,11 +289,17 @@ etc.) as part of its configuration.  This field should be set to a false
 value to indicate that prerequisites included in metadata may be
 considered final and valid for static analysis.
 
+Note: when this field is true, post-configuration prerequisites are not
+guaranteed to bear any relation whatsoever to those stated in the metadata,
+and relying on them doing so is an error. See also
+L</Prerequisites for dynamically configured distributions> in the implementors'
+notes.
+
 This field explicitly B<does not> indicate whether installation may be
 safely performed without using a Makefile or Build file, as there may be
 special files to install or custom installation targets (e.g. for
 dual-life modules that exist on CPAN as well as in the Perl core).  This
-field only defines whether prerequisites are complete as given in the
+field only defines whether or not prerequisites are exactly as given in the
 metadata.
 
 =head3 generated_by
@@ -1103,6 +1109,34 @@ and version prerequisite C<$prereq>:
 If the values of C<$mod> and C<$prereq> have not been scrubbed, however,
 this presents security implications.
 
+=head2 Prerequisites for dynamically configured distributions
+
+When C<dynamic_config> is true, it is an error to presume that the
+prerequisites given in distribution metadata will have any relationship
+whatsoever to the actual prerequisites of the distribution.
+
+In practice, however, one can generally expect such prerequisites to be
+one of two things:
+
+=over 4
+
+=item *
+
+The minimum prerequisites for the distribution, to which dynamic configuration will only add items
+
+=item *
+
+Whatever the distribution configured with on the releaser's machine at release time
+
+=back
+
+The second case often turns out to have identical results to the first case,
+albeit only by accident.
+
+As such, consumers may use this data for informational analysis, but
+presenting it to the user as canonical or relying on it as such is
+invariably the height of folly.
+
 =head1 SEE ALSO
 
 =over 4
diff --git a/lib/CPAN/Meta/Validator.pm b/lib/CPAN/Meta/Validator.pm
index f8b2fca..748d1c6 100644
--- a/lib/CPAN/Meta/Validator.pm
+++ b/lib/CPAN/Meta/Validator.pm
@@ -2,26 +2,26 @@ use 5.006;
 use strict;
 use warnings;
 package CPAN::Meta::Validator;
-our $VERSION = '2.140640'; # VERSION
-
-# =head1 SYNOPSIS
-#
-#   my $struct = decode_json_file('META.json');
-#
-#   my $cmv = CPAN::Meta::Validator->new( $struct );
-#
-#   unless ( $cmv->is_valid ) {
-#     my $msg = "Invalid META structure.  Errors found:\n";
-#     $msg .= join( "\n", $cmv->errors );
-#     die $msg;
-#   }
-#
-# =head1 DESCRIPTION
-#
-# This module validates a CPAN Meta structure against the version of the
-# the specification claimed in the C<meta-spec> field of the structure.
-#
-# =cut
+our $VERSION = '2.141170'; # VERSION
+
+#pod =head1 SYNOPSIS
+#pod
+#pod   my $struct = decode_json_file('META.json');
+#pod
+#pod   my $cmv = CPAN::Meta::Validator->new( $struct );
+#pod
+#pod   unless ( $cmv->is_valid ) {
+#pod     my $msg = "Invalid META structure.  Errors found:\n";
+#pod     $msg .= join( "\n", $cmv->errors );
+#pod     die $msg;
+#pod   }
+#pod
+#pod =head1 DESCRIPTION
+#pod
+#pod This module validates a CPAN Meta structure against the version of the
+#pod the specification claimed in the C<meta-spec> field of the structure.
+#pod
+#pod =cut
 
 #--------------------------------------------------------------------------#
 # This code copied and adapted from Test::CPAN::Meta
@@ -437,13 +437,13 @@ my %definitions = (
 # Code
 #--------------------------------------------------------------------------#
 
-# =method new
-#
-#   my $cmv = CPAN::Meta::Validator->new( $struct )
-#
-# The constructor must be passed a metadata structure.
-#
-# =cut
+#pod =method new
+#pod
+#pod   my $cmv = CPAN::Meta::Validator->new( $struct )
+#pod
+#pod The constructor must be passed a metadata structure.
+#pod
+#pod =cut
 
 sub new {
   my ($class,$data) = @_;
@@ -459,16 +459,16 @@ sub new {
   return bless $self, $class;
 }
 
-# =method is_valid
-#
-#   if ( $cmv->is_valid ) {
-#     ...
-#   }
-#
-# Returns a boolean value indicating whether the metadata provided
-# is valid.
-#
-# =cut
+#pod =method is_valid
+#pod
+#pod   if ( $cmv->is_valid ) {
+#pod     ...
+#pod   }
+#pod
+#pod Returns a boolean value indicating whether the metadata provided
+#pod is valid.
+#pod
+#pod =cut
 
 sub is_valid {
     my $self = shift;
@@ -478,13 +478,13 @@ sub is_valid {
     return ! $self->errors;
 }
 
-# =method errors
-#
-#   warn( join "\n", $cmv->errors );
-#
-# Returns a list of errors seen during validation.
-#
-# =cut
+#pod =method errors
+#pod
+#pod   warn( join "\n", $cmv->errors );
+#pod
+#pod Returns a list of errors seen during validation.
+#pod
+#pod =cut
 
 sub errors {
     my $self = shift;
@@ -492,31 +492,31 @@ sub errors {
     return @{$self->{errors}};
 }
 
-# =begin :internals
-#
-# =head2 Check Methods
-#
-# =over
-#
-# =item *
-#
-# check_map($spec,$data)
-#
-# Checks whether a map (or hash) part of the data structure conforms to the
-# appropriate specification definition.
-#
-# =item *
-#
-# check_list($spec,$data)
-#
-# Checks whether a list (or array) part of the data structure conforms to
-# the appropriate specification definition.
-#
-# =item *
-#
-# =back
-#
-# =cut
+#pod =begin :internals
+#pod
+#pod =head2 Check Methods
+#pod
+#pod =over
+#pod
+#pod =item *
+#pod
+#pod check_map($spec,$data)
+#pod
+#pod Checks whether a map (or hash) part of the data structure conforms to the
+#pod appropriate specification definition.
+#pod
+#pod =item *
+#pod
+#pod check_list($spec,$data)
+#pod
+#pod Checks whether a list (or array) part of the data structure conforms to
+#pod the appropriate specification definition.
+#pod
+#pod =item *
+#pod
+#pod =back
+#pod
+#pod =cut
 
 my $spec_error = "Missing validation action in specification. "
   . "Must be one of 'map', 'list', or 'value'";
@@ -606,113 +606,113 @@ sub check_list {
     }
 }
 
-# =head2 Validator Methods
-#
-# =over
-#
-# =item *
-#
-# header($self,$key,$value)
-#
-# Validates that the header is valid.
-#
-# Note: No longer used as we now read the data structure, not the file.
-#
-# =item *
-#
-# url($self,$key,$value)
-#
-# Validates that a given value is in an acceptable URL format
-#
-# =item *
-#
-# urlspec($self,$key,$value)
-#
-# Validates that the URL to a META specification is a known one.
-#
-# =item *
-#
-# string_or_undef($self,$key,$value)
-#
-# Validates that the value is either a string or an undef value. Bit of a
-# catchall function for parts of the data structure that are completely user
-# defined.
-#
-# =item *
-#
-# string($self,$key,$value)
-#
-# Validates that a string exists for the given key.
-#
-# =item *
-#
-# file($self,$key,$value)
-#
-# Validate that a file is passed for the given key. This may be made more
-# thorough in the future. For now it acts like \&string.
-#
-# =item *
-#
-# exversion($self,$key,$value)
-#
-# Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
-#
-# =item *
-#
-# version($self,$key,$value)
-#
-# Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
-# are both valid. A leading 'v' like 'v1.2.3' is also valid.
-#
-# =item *
-#
-# boolean($self,$key,$value)
-#
-# Validates for a boolean value. Currently these values are '1', '0', 'true',
-# 'false', however the latter 2 may be removed.
-#
-# =item *
-#
-# license($self,$key,$value)
-#
-# Validates that a value is given for the license. Returns 1 if an known license
-# type, or 2 if a value is given but the license type is not a recommended one.
-#
-# =item *
-#
-# custom_1($self,$key,$value)
-#
-# Validates that the given key is in CamelCase, to indicate a user defined
-# keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
-# of the spec, this was only explicitly stated for 'resources'.
-#
-# =item *
-#
-# custom_2($self,$key,$value)
-#
-# Validates that the given key begins with 'x_' or 'X_', to indicate a user
-# defined keyword and only has characters in the class [-_a-zA-Z]
-#
-# =item *
-#
-# identifier($self,$key,$value)
-#
-# Validates that key is in an acceptable format for the META specification,
-# for an identifier, i.e. any that matches the regular expression
-# qr/[a-z][a-z_]/i.
-#
-# =item *
-#
-# module($self,$key,$value)
-#
-# Validates that a given key is in an acceptable module name format, e.g.
-# 'Test::CPAN::Meta::Version'.
-#
-# =back
-#
-# =end :internals
-#
-# =cut
+#pod =head2 Validator Methods
+#pod
+#pod =over
+#pod
+#pod =item *
+#pod
+#pod header($self,$key,$value)
+#pod
+#pod Validates that the header is valid.
+#pod
+#pod Note: No longer used as we now read the data structure, not the file.
+#pod
+#pod =item *
+#pod
+#pod url($self,$key,$value)
+#pod
+#pod Validates that a given value is in an acceptable URL format
+#pod
+#pod =item *
+#pod
+#pod urlspec($self,$key,$value)
+#pod
+#pod Validates that the URL to a META specification is a known one.
+#pod
+#pod =item *
+#pod
+#pod string_or_undef($self,$key,$value)
+#pod
+#pod Validates that the value is either a string or an undef value. Bit of a
+#pod catchall function for parts of the data structure that are completely user
+#pod defined.
+#pod
+#pod =item *
+#pod
+#pod string($self,$key,$value)
+#pod
+#pod Validates that a string exists for the given key.
+#pod
+#pod =item *
+#pod
+#pod file($self,$key,$value)
+#pod
+#pod Validate that a file is passed for the given key. This may be made more
+#pod thorough in the future. For now it acts like \&string.
+#pod
+#pod =item *
+#pod
+#pod exversion($self,$key,$value)
+#pod
+#pod Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
+#pod
+#pod =item *
+#pod
+#pod version($self,$key,$value)
+#pod
+#pod Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
+#pod are both valid. A leading 'v' like 'v1.2.3' is also valid.
+#pod
+#pod =item *
+#pod
+#pod boolean($self,$key,$value)
+#pod
+#pod Validates for a boolean value. Currently these values are '1', '0', 'true',
+#pod 'false', however the latter 2 may be removed.
+#pod
+#pod =item *
+#pod
+#pod license($self,$key,$value)
+#pod
+#pod Validates that a value is given for the license. Returns 1 if an known license
+#pod type, or 2 if a value is given but the license type is not a recommended one.
+#pod
+#pod =item *
+#pod
+#pod custom_1($self,$key,$value)
+#pod
+#pod Validates that the given key is in CamelCase, to indicate a user defined
+#pod keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
+#pod of the spec, this was only explicitly stated for 'resources'.
+#pod
+#pod =item *
+#pod
+#pod custom_2($self,$key,$value)
+#pod
+#pod Validates that the given key begins with 'x_' or 'X_', to indicate a user
+#pod defined keyword and only has characters in the class [-_a-zA-Z]
+#pod
+#pod =item *
+#pod
+#pod identifier($self,$key,$value)
+#pod
+#pod Validates that key is in an acceptable format for the META specification,
+#pod for an identifier, i.e. any that matches the regular expression
+#pod qr/[a-z][a-z_]/i.
+#pod
+#pod =item *
+#pod
+#pod module($self,$key,$value)
+#pod
+#pod Validates that a given key is in an acceptable module name format, e.g.
+#pod 'Test::CPAN::Meta::Version'.
+#pod
+#pod =back
+#pod
+#pod =end :internals
+#pod
+#pod =cut
 
 sub header {
     my ($self,$key,$value) = @_;
@@ -997,7 +997,7 @@ CPAN::Meta::Validator - validate CPAN distribution metadata structures
 
 =head1 VERSION
 
-version 2.140640
+version 2.141170
 
 =head1 SYNOPSIS
 
diff --git a/t/00-report-prereqs.t b/t/00-report-prereqs.t
index e0a51f2..707c81d 100644
--- a/t/00-report-prereqs.t
+++ b/t/00-report-prereqs.t
@@ -50,7 +50,7 @@ my $static_prereqs = do { my $x = {
                       },
        'develop' => {
                       'requires' => {
-                                      'Dist::Zilla' => '5.013',
+                                      'Dist::Zilla' => '5.015',
                                       'Dist::Zilla::Plugin::AutoVersion' => '0',
                                       'Dist::Zilla::Plugin::MakeMaker' => '0',
                                       'Dist::Zilla::Plugin::MakeMaker::Highlander' => '0.003',
@@ -74,7 +74,6 @@ my $static_prereqs = do { my $x = {
                                       'CPAN::Meta::YAML' => '0.008',
                                       'Carp' => '0',
                                       'JSON::PP' => '2.27200',
-                                      'List::Util' => '1.33',
                                       'Parse::CPAN::Meta' => '1.4414',
                                       'Scalar::Util' => '0',
                                       'perl' => '5.008',
@@ -96,6 +95,7 @@ my $static_prereqs = do { my $x = {
                                    'File::Spec::Functions' => '0',
                                    'File::Temp' => '0.20',
                                    'IO::Dir' => '0',
+                                   'List::Util' => '0',
                                    'Test::More' => '0.88',
                                    'overload' => '0',
                                    'utf8' => '0'
diff --git a/t/converter-fragments.t b/t/converter-fragments.t
new file mode 100644
index 0000000..18dad14
--- /dev/null
+++ b/t/converter-fragments.t
@@ -0,0 +1,158 @@
+use strict;
+use warnings;
+use Test::More 0.88;
+
+use CPAN::Meta::Converter;
+
+delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults
+
+my $spec2 = {
+    version => '2',
+    url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
+};
+
+my @cases = (
+    #<<< No perltidy
+    {
+        label  => "v1.4 requires -> v2 prereqs",
+        from   => "1.4",
+        to     => "2",
+        input  => {
+            requires => {
+                'File::Spec' => "0.80",
+            },
+        },
+        expect => {
+            'meta-spec' => $spec2,
+            prereqs => {
+                runtime => {
+                    requires => {
+                        'File::Spec' => "0.80",
+                    },
+                }
+            }
+        },
+    },
+    {
+        label  => "v1.4 x_custom -> v2 x_custom",
+        from   => "1.4",
+        to     => "2",
+        input  => {
+            x_authority => 'DAGOLDEN',
+        },
+        expect => {
+            'meta-spec' => $spec2,
+            x_authority => 'DAGOLDEN',
+        },
+    },
+    {
+        label  => "meta-spec included",
+        to     => "2",
+        input  => {
+            'meta-spec' => { version => '1.0' },
+            requires => {
+                'File::Spec' => "0.80",
+            },
+        },
+        expect => {
+            'meta-spec' => $spec2,
+            prereqs => {
+                runtime => {
+                    requires => {
+                        'File::Spec' => "0.80",
+                    },
+                }
+            }
+        },
+    },
+    {
+        # this is a test of default version and intentionally gives bad
+        # data that will get dropped by the conversion
+        label  => "default version",
+        from   => "2",
+        to     => "2",
+        input  => {
+            requires => {
+                'File::Spec' => "0.80",
+            },
+        },
+        expect => {
+            'meta-spec' => $spec2,
+        },
+    },
+    {
+        # fields deprecated from older versions
+        label  => "v1.4 prereq stuff -> v2 prereqs",
+        from   => "1.4",
+        to     => "2",
+        input  => {
+            configure_requires => {
+                'File::Spec' => "0.80",
+            },
+            build_requires => {
+                'Scalar::Util' => '1.0',
+            },
+            requires => {
+                'B' => '3.1',
+            },
+            recommends => {
+                'Config' => '4.0',
+            },
+            conflicts => {
+                'File::Temp' => "0.2",
+            },
+        },
+        expect => {
+            'meta-spec' => $spec2,
+            prereqs => {
+                configure => {
+                    requires => {
+                        'File::Spec' => "0.80",
+                    },
+                },
+                build => {
+                    requires => {
+                        'Scalar::Util' => '1.0',
+                    },
+                },
+                runtime => {
+                    conflicts => {
+                        'File::Temp' => "0.2",
+                    },
+                    requires => {
+                        'B' => '3.1',
+                    },
+                    recommends => {
+                        'Config' => '4.0',
+                    },
+                },
+            },
+        },
+    },
+    {
+        label  => "v1.1 license_url: -> v2 license",
+        from   => "1.1",
+        to     => "2",
+        input  => {
+            license_url => 'http://opensource.org/licenses/Artistic-1.0',
+            license => 'perl',
+        },
+        expect => {
+            'meta-spec' => $spec2,
+            license => [ 'perl_5' ],
+        },
+    },
+);
+
+for my $c (@cases) {
+    my $cmc = CPAN::Meta::Converter->new(
+        $c->{input}, $c->{from} ? (default_version => $c->{from} ) : ()
+    );
+    my $got = $cmc->upgrade_fragment;
+    my $exp = $c->{expect};
+    is_deeply( $got, $exp, $c->{label} )
+      or diag "GOT:\n" . explain($got) . "\nEXPECTED:\n" . explain($exp);
+}
+
+done_testing;
+# vim: ts=4 sts=4 sw=4 et:
diff --git a/xt/author/00-compile.t b/xt/author/00-compile.t
index 69212a5..d8b8bc0 100644
--- a/xt/author/00-compile.t
+++ b/xt/author/00-compile.t
@@ -2,7 +2,7 @@ use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.039
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.040
 
 use Test::More  tests => 7 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
diff --git a/xt/author/pod-spell.t b/xt/author/pod-spell.t
index 40ca70d..7970a7f 100644
--- a/xt/author/pod-spell.t
+++ b/xt/author/pod-spell.t
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 use Test::More;
 
-# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006006
+# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006007
 use Test::Spelling 0.12;
 use Pod::Wordlist;
 
@@ -14,6 +14,7 @@ distmeta
 dir
 mailto
 metacpan
+releaser
 subkey
 subkeys
 David
@@ -66,6 +67,9 @@ leont
 Mark
 Fowler
 markf
+Matt
+Trout
+mst
 Michael
 Schwern
 mschwern
@@ -78,12 +82,13 @@ dolmen
 Randy
 Sims
 randys
+moznion
 lib
 CPAN
 Meta
+History
+Prereqs
 Spec
+Validator
 Converter
-Prereqs
-History
 Feature
-Validator

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libcpan-meta-perl.git



More information about the Pkg-perl-cvs-commits mailing list