From 85b1cb07bd15b67e4656e4ba7f54fa03f273b090 Mon Sep 17 00:00:00 2001 From: Steve Hay Date: Wed, 5 Mar 2014 08:42:20 +0000 Subject: [PATCH] Upgrade CPAN-Meta from version 2.133380 to 2.140630 --- MANIFEST | 1 + Porting/Maintainers.pl | 3 +- cpan/CPAN-Meta/lib/CPAN/Meta.pm | 309 ++++++++++++++++++++- cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm | 79 +++++- cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm | 38 ++- cpan/CPAN-Meta/lib/CPAN/Meta/History.pm | 4 +- cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm | 108 ++++++- cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm | 61 +++- cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm | 180 +++++++++++- cpan/CPAN-Meta/t/data-fail/META-2.json | 2 +- cpan/CPAN-Meta/t/data-fixable/META-2.json | 2 +- .../t/data-fixable/invalid-meta-spec-version.json | 2 +- .../meta-spec-version-trailing-zeros.json | 2 +- cpan/CPAN-Meta/t/data-fixable/restrictive-2.json | 2 +- .../CPAN-Meta/t/data-fixable/version-ranges-2.json | 2 +- cpan/CPAN-Meta/t/data-test/META-2.json | 2 +- cpan/CPAN-Meta/t/data-test/META-2.meta | 90 ++++++ .../t/data-test/provides-version-missing.json | 2 +- cpan/CPAN-Meta/t/data-test/restricted-2.json | 2 +- cpan/CPAN-Meta/t/data-test/version-not-normal.json | 2 +- cpan/CPAN-Meta/t/data-test/version-ranges-2.json | 2 +- cpan/CPAN-Meta/t/meta-obj.t | 4 +- cpan/CPAN-Meta/t/no-index.t | 2 +- cpan/CPAN-Meta/t/save-load.t | 9 +- pod/perldelta.pod | 6 + 25 files changed, 870 insertions(+), 46 deletions(-) create mode 100644 cpan/CPAN-Meta/t/data-test/META-2.meta diff --git a/MANIFEST b/MANIFEST index 81cddf0..d50c7e7 100644 --- a/MANIFEST +++ b/MANIFEST @@ -326,6 +326,7 @@ cpan/CPAN-Meta/t/data-test/META-1_2.yml cpan/CPAN-Meta/t/data-test/META-1_3.yml cpan/CPAN-Meta/t/data-test/META-1_4.yml cpan/CPAN-Meta/t/data-test/META-2.json +cpan/CPAN-Meta/t/data-test/META-2.meta cpan/CPAN-Meta/t/data-test/provides-version-missing.json cpan/CPAN-Meta/t/data-test/resources.yml cpan/CPAN-Meta/t/data-test/restricted-2.json diff --git a/Porting/Maintainers.pl b/Porting/Maintainers.pl index 96721b9..8ccfa50 100755 --- a/Porting/Maintainers.pl +++ b/Porting/Maintainers.pl @@ -302,10 +302,9 @@ 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.133380.tar.gz', + 'DISTRIBUTION' => 'DAGOLDEN/CPAN-Meta-2.140630.tar.gz', 'FILES' => q[cpan/CPAN-Meta], 'EXCLUDED' => [ - qw(t/00-compile.t), qw[t/00-report-prereqs.t], qr{t/README-data.txt}, qr{^xt}, diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta.pm b/cpan/CPAN-Meta/lib/CPAN/Meta.pm index 87bbfa2..07e2622 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta.pm @@ -2,18 +2,81 @@ use 5.006; use strict; use warnings; package CPAN::Meta; -our $VERSION = '2.133380'; # VERSION - +our $VERSION = '2.140630'; # 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 or, for +# older distributions, F, which describes the distribution, its +# contents, and the requirements for building and installing the distribution. +# The data structure stored in the F file is described in +# L. +# +# CPAN::Meta provides a simple class to represent this distribution metadata (or +# I), 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 use Carp qw(carp croak); use CPAN::Meta::Feature; use CPAN::Meta::Prereqs; use CPAN::Meta::Converter; use CPAN::Meta::Validator; -use Parse::CPAN::Meta 1.4403 (); +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 BEGIN { my @STRING_READERS = qw( @@ -32,6 +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 and C methods may also be called as C and +# C, respectively, to match the field name in the distmeta structure. +# +# =cut BEGIN { my @LIST_READERS = qw( @@ -55,6 +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 BEGIN { my @MAP_READERS = qw( @@ -78,6 +169,16 @@ BEGIN { } } +# =head1 CUSTOM DATA +# +# A list of custom keys are available from the C method and +# particular keys may be retrieved with the C method. +# +# say $meta->custom($_) for $meta->custom_keys; +# +# If a custom key refers to a data structure, a deep clone is returned. +# +# =cut sub custom_keys { return grep { /^x_/i } keys %{$_[0]}; @@ -90,6 +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 sub _new { my ($class, $struct, $options) = @_; @@ -130,6 +254,15 @@ sub new { return $self; } +# =method create +# +# my $meta = CPAN::Meta->create($distmeta_struct, \%options); +# +# This is same as C, except that C and C fields +# will be generated if not provided. This means the metadata structure is +# assumed to otherwise follow the latest L. +# +# =cut sub create { my ($class, $struct, $options) = @_; @@ -141,6 +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 object, just +# like C. It will die if the deserialized version fails to validate +# against its stated specification version. +# +# It takes the same options as C but C defaults to +# true. +# +# =cut sub load_file { my ($class, $file, $options) = @_; @@ -158,6 +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. +# +# =cut sub load_yaml_string { my ($class, $yaml, $options) = @_; @@ -172,6 +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. +# +# =cut sub load_json_string { my ($class, $json, $options) = @_; @@ -186,6 +348,50 @@ 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 to guess. In other respects it is identical to +# C. +# +# =cut + +sub load_string { + my ($class, $string, $options) = @_; + $options->{lazy_validation} = 1 unless exists $options->{lazy_validation}; + + my $self; + eval { + my $struct = Parse::CPAN::Meta->load_string( $string ); + $self = $class->_new($struct, $options); + }; + croak($@) if $@; + 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, which defaults to '2'. On Perl 5.8.1 or later, the file +# is saved with UTF-8 encoding. +# +# For C 2 (or higher), the filename should end in '.json'. L +# is the default JSON backend. Using another JSON backend requires L 2.5 or +# later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate +# backend like L. +# +# For C less than 2, the filename should end in '.yml'. +# L 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 sub save { my ($self, $file, $options) = @_; @@ -213,12 +419,32 @@ sub save { return 1; } +# =method meta_spec_version +# +# This method returns the version part of the C entry in the distmeta +# structure. It is equivalent to: +# +# $meta->meta_spec->{version}; +# +# =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 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 sub effective_prereqs { my ($self, $features) = @_; @@ -233,6 +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 and C keys in the C property of +# the distmeta structure. +# +# C<$filename> should be given in unix format. +# +# =cut sub should_index_file { my ($self, $filename) = @_; @@ -249,6 +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 and C keys in the C +# property of the distmeta structure. +# +# =cut sub should_index_package { my ($self, $package) = @_; @@ -264,6 +510,14 @@ sub should_index_package { return 1; } +# =method features +# +# my @feature_objects = $meta->features; +# +# This method returns a list of L objects, one for each +# optional feature described by the distribution's metadata. +# +# =cut sub features { my ($self) = @_; @@ -275,6 +529,15 @@ sub features { return @features; } +# =method feature +# +# my $feature_object = $meta->feature( $identifier ); +# +# This method returns a L object for the optional feature +# with the given identifier. If no feature with that identifier exists, an +# exception will be raised. +# +# =cut sub feature { my ($self, $ident) = @_; @@ -285,6 +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 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 sub as_struct { my ($self, $options) = @_; @@ -296,6 +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 UTF-8 encoded.) It takes an optional hashref +# of options. If the hashref contains a C 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 greater than or equal to 2, the string will be serialized as +# JSON. For C less than 2, the string will be serialized as YAML. In +# both cases, the same rules are followed as in the C method for choosing +# a serialization backend. +# +# =cut sub as_string { my ($self, $options) = @_; @@ -348,7 +641,7 @@ CPAN::Meta - the distribution metadata for a CPAN dist =head1 VERSION -version 2.133380 +version 2.140630 =head1 SYNOPSIS @@ -454,6 +747,14 @@ given YAML string. In other respects it is identical to C. 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. +=head2 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 to guess. In other respects it is identical to +C. + =head2 save $meta->save($distmeta_file, \%options); diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm index aa8749b..2b53f7d 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Converter.pm @@ -2,8 +2,25 @@ use 5.006; use strict; use warnings; package CPAN::Meta::Converter; -our $VERSION = '2.133380'; # VERSION +our $VERSION = '2.140630'; # 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 use CPAN::Meta::Validator; use CPAN::Meta::Requirements; @@ -28,7 +45,7 @@ sub _dclone { } my %known_specs = ( - '2' => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + '2' => 'https://metacpan.org/pod/CPAN::Meta::Spec', '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html', '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html', '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html', @@ -1217,6 +1234,15 @@ my %cleanup = ( # 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 sub new { my ($class,$data) = @_; @@ -1251,6 +1277,53 @@ sub _extract_spec_version { return "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 will die if any conversion/standardization still results in an +# invalid structure. +# +# Valid parameters include: +# +# =over +# +# =item * +# +# C -- 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 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 field will result in a C +# field of 'unknown'. Fields that may get an 'unknown' include: +# +# =for :list +# * abstract +# * author +# * license +# +# =cut sub convert { my ($self, %args) = @_; @@ -1318,7 +1391,7 @@ CPAN::Meta::Converter - Convert CPAN distribution metadata structures =head1 VERSION -version 2.133380 +version 2.140630 =head1 SYNOPSIS diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm index 6631586..e07f29b 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Feature.pm @@ -2,10 +2,28 @@ use 5.006; use strict; use warnings; package CPAN::Meta::Feature; -our $VERSION = '2.133380'; # VERSION +our $VERSION = '2.140630'; # 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 (or F) +# file. +# +# For the most part, this class will only be used when operating on the result of +# the C or C methods on a L 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 entry in the +# distmeta. It must contain entries for C and C. +# +# =cut sub new { my ($class, $identifier, $spec) = @_; @@ -19,12 +37,28 @@ sub new { bless \%guts => $class; } +# =method identifier +# +# This method returns the feature's identifier. +# +# =cut sub identifier { $_[0]{identifier} } +# =method description +# +# This method returns the feature's long description. +# +# =cut sub description { $_[0]{description} } +# =method prereqs +# +# This method returns the feature's prerequisites as a L +# object. +# +# =cut sub prereqs { $_[0]{prereqs} } @@ -44,7 +78,7 @@ CPAN::Meta::Feature - an optional feature provided by a CPAN distribution =head1 VERSION -version 2.133380 +version 2.140630 =head1 DESCRIPTION diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm index 30bbb06..b7b6ebe 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/History.pm @@ -3,7 +3,7 @@ use 5.006; use strict; use warnings; package CPAN::Meta::History; -our $VERSION = '2.133380'; # VERSION +our $VERSION = '2.140630'; # VERSION 1; @@ -21,7 +21,7 @@ CPAN::Meta::History - history of CPAN Meta Spec changes =head1 VERSION -version 2.133380 +version 2.140630 =head1 DESCRIPTION diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm index a4e6057..4da420b 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Prereqs.pm @@ -2,13 +2,47 @@ use 5.006; use strict; use warnings; package CPAN::Meta::Prereqs; -our $VERSION = '2.133380'; # VERSION +our $VERSION = '2.140630'; # 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. +# +# =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 field described in L, 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 sub __legal_phases { qw(configure build test runtime develop) } sub __legal_types { qw(requires recommends suggests conflicts) } @@ -44,6 +78,19 @@ sub new { return bless \%guts => $class; } +# =method requirements_for +# +# my $requirements = $prereqs->requirements_for( $phase, $type ); +# +# This method returns a L 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 sub requirements_for { my ($self, $phase, $type) = @_; @@ -66,6 +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 sub with_merged_prereqs { my ($self, $other) = @_; @@ -96,6 +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 object. If arguments +# are omitted, it defaults to "runtime", "build" and "test" for phases +# and "requires" and "recommends" for types. +# +# =cut sub merged_requirements { my ($self, $phases, $types) = @_; @@ -127,6 +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 objects inside it. +# +# =cut sub as_string_hash { my ($self) = @_; @@ -145,9 +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 sub is_finalized { $_[0]{finalized} } +# =method finalize +# +# Calling C 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 sub finalize { my ($self) = @_; @@ -159,6 +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 sub clone { my ($self) = @_; @@ -182,7 +286,7 @@ CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type =head1 VERSION -version 2.133380 +version 2.140630 =head1 DESCRIPTION diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm index bc745f9..33a4a23 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Spec.pm @@ -7,7 +7,7 @@ use 5.006; use strict; use warnings; package CPAN::Meta::Spec; -our $VERSION = '2.133380'; # VERSION +our $VERSION = '2.140630'; # VERSION 1; @@ -28,7 +28,7 @@ CPAN::Meta::Spec - specification for CPAN distribution metadata =head1 VERSION -version 2.133380 +version 2.140630 =head1 SYNOPSIS @@ -82,7 +82,7 @@ version 2.133380 keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', - url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', }; @@ -395,6 +395,20 @@ This is a I of the metadata specification document corresponding to the given version. This is strictly for human-consumption and should not impact the interpretation of the document. +For the version 2 spec, either of these are recommended: + +=over 4 + +=item * + +C + +=item * + +C + +=back + =back =head3 name @@ -408,7 +422,8 @@ Example: This field is the name of the distribution. This is often created by taking the "main package" in the distribution and changing C<::> to C<->, but the name may be completely unrelated to the packages within -the distribution. C.f. L. +the distribution. For example, L is distributed as part +of the distribution name "libwww-perl". =head3 release_status @@ -662,8 +677,8 @@ Example: This describes all packages provided by this distribution. This information is used by distribution and automation mechanisms like -PAUSE, CPAN, and search.cpan.org to build indexes saying in which -distribution various packages can be found. +PAUSE, CPAN, metacpan.org and search.cpan.org to build indexes saying in +which distribution various packages can be found. The keys of C are package names that can be found within the distribution. If a package name key is provided, it must @@ -1090,21 +1105,41 @@ this presents security implications. =head1 SEE ALSO +=over 4 + +=item * + CPAN, L -CPAN.pm, L +=item * -CPANPLUS, L +JSON, L -ExtUtils::MakeMaker, L +=item * -Module::Build, L +YAML, L -Module::Install, L +=item * -JSON, L +L -YAML, L +=item * + +L + +=item * + +L + +=item * + +L + +=item * + +L + +=back =head1 HISTORY diff --git a/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm b/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm index e094b8f..e9b9550 100644 --- a/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm +++ b/cpan/CPAN-Meta/lib/CPAN/Meta/Validator.pm @@ -2,8 +2,26 @@ use 5.006; use strict; use warnings; package CPAN::Meta::Validator; -our $VERSION = '2.133380'; # VERSION - +our $VERSION = '2.140630'; # 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 field of the structure. +# +# =cut #--------------------------------------------------------------------------# # This code copied and adapted from Test::CPAN::Meta @@ -419,6 +437,13 @@ my %definitions = ( # Code #--------------------------------------------------------------------------# +# =method new +# +# my $cmv = CPAN::Meta::Validator->new( $struct ) +# +# The constructor must be passed a metadata structure. +# +# =cut sub new { my ($class,$data) = @_; @@ -434,6 +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 sub is_valid { my $self = shift; @@ -443,6 +478,13 @@ sub is_valid { return ! $self->errors; } +# =method errors +# +# warn( join "\n", $cmv->errors ); +# +# Returns a list of errors seen during validation. +# +# =cut sub errors { my $self = shift; @@ -450,6 +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 my $spec_error = "Missing validation action in specification. " . "Must be one of 'map', 'list', or 'value'"; @@ -539,6 +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 sub header { my ($self,$key,$value) = @_; @@ -823,7 +997,7 @@ CPAN::Meta::Validator - validate CPAN distribution metadata structures =head1 VERSION -version 2.133380 +version 2.140630 =head1 SYNOPSIS diff --git a/cpan/CPAN-Meta/t/data-fail/META-2.json b/cpan/CPAN-Meta/t/data-fail/META-2.json index 4cad8f3..589ed11 100644 --- a/cpan/CPAN-Meta/t/data-fail/META-2.json +++ b/cpan/CPAN-Meta/t/data-fail/META-2.json @@ -7,7 +7,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "name" : "Module-Build", "dynamic_config" : 1, diff --git a/cpan/CPAN-Meta/t/data-fixable/META-2.json b/cpan/CPAN-Meta/t/data-fixable/META-2.json index 6734399..cd28769 100644 --- a/cpan/CPAN-Meta/t/data-fixable/META-2.json +++ b/cpan/CPAN-Meta/t/data-fixable/META-2.json @@ -7,7 +7,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-fixable/invalid-meta-spec-version.json b/cpan/CPAN-Meta/t/data-fixable/invalid-meta-spec-version.json index 183781b..ead6d7f 100644 --- a/cpan/CPAN-Meta/t/data-fixable/invalid-meta-spec-version.json +++ b/cpan/CPAN-Meta/t/data-fixable/invalid-meta-spec-version.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "99", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-fixable/meta-spec-version-trailing-zeros.json b/cpan/CPAN-Meta/t/data-fixable/meta-spec-version-trailing-zeros.json index 3990195..2007d6e 100644 --- a/cpan/CPAN-Meta/t/data-fixable/meta-spec-version-trailing-zeros.json +++ b/cpan/CPAN-Meta/t/data-fixable/meta-spec-version-trailing-zeros.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2.0", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-fixable/restrictive-2.json b/cpan/CPAN-Meta/t/data-fixable/restrictive-2.json index 2fdd9fb..6b8e0e9 100644 --- a/cpan/CPAN-Meta/t/data-fixable/restrictive-2.json +++ b/cpan/CPAN-Meta/t/data-fixable/restrictive-2.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-fixable/version-ranges-2.json b/cpan/CPAN-Meta/t/data-fixable/version-ranges-2.json index 8c13c75..432e745 100644 --- a/cpan/CPAN-Meta/t/data-fixable/version-ranges-2.json +++ b/cpan/CPAN-Meta/t/data-fixable/version-ranges-2.json @@ -2,7 +2,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", diff --git a/cpan/CPAN-Meta/t/data-test/META-2.json b/cpan/CPAN-Meta/t/data-test/META-2.json index e0c7e32..d09b71e 100644 --- a/cpan/CPAN-Meta/t/data-test/META-2.json +++ b/cpan/CPAN-Meta/t/data-test/META-2.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-test/META-2.meta b/cpan/CPAN-Meta/t/data-test/META-2.meta new file mode 100644 index 0000000..d09b71e --- /dev/null +++ b/cpan/CPAN-Meta/t/data-test/META-2.meta @@ -0,0 +1,90 @@ +{ + "resources" : { + "license" : [ + "http://dev.perl.org/licenses/" + ], + "repository" : { + "url" : "svn://repo.example.com/foo-bar#fakeanchor", + "web" : "http://www.example.com" + } + }, + "generated_by" : "Module::Build version 0.36", + "meta-spec" : { + "version" : "2", + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" + }, + "version" : "0.36", + "name" : "Module-Build", + "dynamic_config" : 1, + "author" : [ + "Ken Williams ", + "Module-Build List " + ], + "release_status" : "stable", + "license" : [ + "perl_5", + "bsd" + ], + "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", + "keywords" : [ + "toolchain", + "cpan", + "dual-life" + ], + "prereqs" : { + "runtime" : { + "requires" : { + "File::Copy" : "0", + "IO::File" : "0", + "Data::Dumper" : "0", + "File::Spec" : "0", + "Config" : "0", + "ExtUtils::Install" : "0", + "perl" : "5.006", + "File::Compare" : "0", + "File::Find" : "0", + "File::Path" : "0", + "File::Basename" : "0", + "Cwd" : "0" + }, + "recommends" : { + "YAML" : "0.35", + "ExtUtils::ParseXS" : "2.02", + "Pod::Text" : "0", + "ExtUtils::Install" : "0.3", + "Archive::Tar" : "1.00" + } + }, + "build" : { + "requires" : { + "Build::Requires": "1.1", + "Test::More" : "0" + } + }, + "test" : { + "requires" : { + "Test::More" : "0.88", + "Test::Requires" : "1.2" + } + } + }, + "optional_features" : { + "domination" : { + "prereqs" : { + "develop" : { + "requires" : { + "Genius::Evil" : "1.234" + } + }, + "runtime" : { + "requires" : { + "Machine::Weather" : "2.0" + } + } + }, + "description" : "Take over the world" + } + }, + "abstract" : "Build and install Perl modules", + "x_whatever" : "Custom key" +} diff --git a/cpan/CPAN-Meta/t/data-test/provides-version-missing.json b/cpan/CPAN-Meta/t/data-test/provides-version-missing.json index 2264e92..eaa334f 100644 --- a/cpan/CPAN-Meta/t/data-test/provides-version-missing.json +++ b/cpan/CPAN-Meta/t/data-test/provides-version-missing.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-test/restricted-2.json b/cpan/CPAN-Meta/t/data-test/restricted-2.json index 88886db..2cb9276 100644 --- a/cpan/CPAN-Meta/t/data-test/restricted-2.json +++ b/cpan/CPAN-Meta/t/data-test/restricted-2.json @@ -11,7 +11,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", diff --git a/cpan/CPAN-Meta/t/data-test/version-not-normal.json b/cpan/CPAN-Meta/t/data-test/version-not-normal.json index a275a86..431d663 100644 --- a/cpan/CPAN-Meta/t/data-test/version-not-normal.json +++ b/cpan/CPAN-Meta/t/data-test/version-not-normal.json @@ -2,7 +2,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", diff --git a/cpan/CPAN-Meta/t/data-test/version-ranges-2.json b/cpan/CPAN-Meta/t/data-test/version-ranges-2.json index 6d23170..7bf7b0d 100644 --- a/cpan/CPAN-Meta/t/data-test/version-ranges-2.json +++ b/cpan/CPAN-Meta/t/data-test/version-ranges-2.json @@ -2,7 +2,7 @@ "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", diff --git a/cpan/CPAN-Meta/t/meta-obj.t b/cpan/CPAN-Meta/t/meta-obj.t index bb39c46..1491abc 100644 --- a/cpan/CPAN-Meta/t/meta-obj.t +++ b/cpan/CPAN-Meta/t/meta-obj.t @@ -67,7 +67,7 @@ my $distmeta = { keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', - url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', x_authority => 'cpan:FLORA', @@ -145,7 +145,7 @@ is_deeply( $meta->meta_spec, { version => '2', - url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, '->meta_spec', ); diff --git a/cpan/CPAN-Meta/t/no-index.t b/cpan/CPAN-Meta/t/no-index.t index 456633a..8940117 100644 --- a/cpan/CPAN-Meta/t/no-index.t +++ b/cpan/CPAN-Meta/t/no-index.t @@ -15,7 +15,7 @@ my %distmeta = ( license => [ 'perl_5' ], 'meta-spec' => { version => '2', - url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, dynamic_config => 1, generated_by => 'Module::Build version 0.36', diff --git a/cpan/CPAN-Meta/t/save-load.t b/cpan/CPAN-Meta/t/save-load.t index 3c68f90..e22c039 100644 --- a/cpan/CPAN-Meta/t/save-load.t +++ b/cpan/CPAN-Meta/t/save-load.t @@ -67,7 +67,7 @@ my $distmeta = { keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', - url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', }; @@ -98,4 +98,11 @@ ok( $loaded = Parse::CPAN::Meta->load_file($metayml), 'load saved file' ); is( $loaded->{name}, 'Module-Build', 'name correct'); is( $loaded->{requires}{perl}, "5.006", 'prereq correct' ); +# file without suffix + +ok( $loaded = CPAN::Meta->load_file('t/data-test/META-2.meta'), 'load_file META-2.meta' ); + +my $string = do { open my $fh, '<', 't/data-test/META-2.meta'; local $/; <$fh> }; +ok( $loaded = CPAN::Meta->load_string($string), 'load META-2.meta from string' ); + done_testing; diff --git a/pod/perldelta.pod b/pod/perldelta.pod index eb15ae5..0dcf601 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -126,6 +126,12 @@ overrides. [perl #121196] =item * +L has been upgraded from version 2.133380 to 2.140630. + +Added a C method that guesses whether the string is YAML or JSON. + +=item * + L has been upgraded from version 0.042 to 0.043. No longer sends absolute request URI when tunneling SSL via proxy and fixes -- 2.7.4