← Index
NYTProf Performance Profile   « line view »
For Makefile.PL
  Run on Sun Mar 1 16:04:44 2015
Reported on Sun Mar 1 16:09:02 2015

FilenameC:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm
StatementsExecuted 6133 statements in 15.6ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1110s0sCPAN::Meta::::BEGIN@1.4 CPAN::Meta::BEGIN@1.4
1110s0sCPAN::Meta::::BEGIN@2.5 CPAN::Meta::BEGIN@2.5
1110s0sCPAN::Meta::::BEGIN@3.6 CPAN::Meta::BEGIN@3.6
1110s0sCPAN::Meta::Converter::::BEGIN@25CPAN::Meta::Converter::BEGIN@25
1110s0sCPAN::Meta::Converter::::BEGIN@26CPAN::Meta::Converter::BEGIN@26
1110s0sCPAN::Meta::Converter::::BEGIN@27CPAN::Meta::Converter::BEGIN@27
1110s0sCPAN::Meta::Converter::::BEGIN@35CPAN::Meta::Converter::BEGIN@35
1110s0sCPAN::Meta::Converter::::BEGIN@474CPAN::Meta::Converter::BEGIN@474
1110s0sCPAN::Meta::Converter::::BEGIN@489CPAN::Meta::Converter::BEGIN@489
1110s0sCPAN::Meta::Converter::::BEGIN@52CPAN::Meta::Converter::BEGIN@52
1110s0sCPAN::Meta::Converter::::BEGIN@53CPAN::Meta::Converter::BEGIN@53
110610s0sCPAN::Meta::Converter::::CORE:matchCPAN::Meta::Converter::CORE:match (opcode)
4110s0sCPAN::Meta::Converter::::CORE:qrCPAN::Meta::Converter::CORE:qr (opcode)
21210s0sCPAN::Meta::Converter::::CORE:regcompCPAN::Meta::Converter::CORE:regcomp (opcode)
14310s0sCPAN::Meta::Converter::::CORE:sortCPAN::Meta::Converter::CORE:sort (opcode)
0000s0sCPAN::Meta::Converter::::__ANON__[:43]CPAN::Meta::Converter::__ANON__[:43]
36110s0sCPAN::Meta::Converter::::__ANON__[:490]CPAN::Meta::Converter::__ANON__[:490]
0000s0sCPAN::Meta::Converter::::__ANON__[:54]CPAN::Meta::Converter::__ANON__[:54]
0000s0sCPAN::Meta::Converter::::__ANON__[:624]CPAN::Meta::Converter::__ANON__[:624]
0000s0sCPAN::Meta::Converter::::__ANON__[:632]CPAN::Meta::Converter::__ANON__[:632]
0000s0sCPAN::Meta::Converter::::__ANON__[:633]CPAN::Meta::Converter::__ANON__[:633]
4110s0sCPAN::Meta::Converter::::__ANON__[:670]CPAN::Meta::Converter::__ANON__[:670]
4110s0sCPAN::Meta::Converter::::__ANON__[:671]CPAN::Meta::Converter::__ANON__[:671]
3110s0sCPAN::Meta::Converter::::__ANON__[:709]CPAN::Meta::Converter::__ANON__[:709]
3110s0sCPAN::Meta::Converter::::__ANON__[:711]CPAN::Meta::Converter::__ANON__[:711]
3110s0sCPAN::Meta::Converter::::__ANON__[:712]CPAN::Meta::Converter::__ANON__[:712]
17110s0sCPAN::Meta::Converter::::_author_listCPAN::Meta::Converter::_author_list
0000s0sCPAN::Meta::Converter::::_bad_version_hookCPAN::Meta::Converter::_bad_version_hook
17110s0sCPAN::Meta::Converter::::_change_meta_specCPAN::Meta::Converter::_change_meta_spec
0000s0sCPAN::Meta::Converter::::_clean_versionCPAN::Meta::Converter::_clean_version
4110s0sCPAN::Meta::Converter::::_cleanup_optional_features_2CPAN::Meta::Converter::_cleanup_optional_features_2
4110s0sCPAN::Meta::Converter::::_cleanup_prereqsCPAN::Meta::Converter::_cleanup_prereqs
4110s0sCPAN::Meta::Converter::::_cleanup_resources_2CPAN::Meta::Converter::_cleanup_resources_2
53910s0sCPAN::Meta::Converter::::_convertCPAN::Meta::Converter::_convert (recurses: max depth 2, inclusive time 0s)
54320s218msCPAN::Meta::Converter::::_dcloneCPAN::Meta::Converter::_dclone
9110s0sCPAN::Meta::Converter::::_downgrade_licenseCPAN::Meta::Converter::_downgrade_license
9110s0sCPAN::Meta::Converter::::_downgrade_optional_featuresCPAN::Meta::Converter::_downgrade_optional_features
9110s0sCPAN::Meta::Converter::::_downgrade_resourcesCPAN::Meta::Converter::_downgrade_resources
54310s0sCPAN::Meta::Converter::::_extract_prereqsCPAN::Meta::Converter::_extract_prereqs
17110s0sCPAN::Meta::Converter::::_extract_spec_versionCPAN::Meta::Converter::_extract_spec_version
0000s0sCPAN::Meta::Converter::::_feature_2CPAN::Meta::Converter::_feature_2
17110s0sCPAN::Meta::Converter::::_generated_byCPAN::Meta::Converter::_generated_by
9110s0sCPAN::Meta::Converter::::_get_build_requiresCPAN::Meta::Converter::_get_build_requires
60210s0sCPAN::Meta::Converter::::_is_module_nameCPAN::Meta::Converter::_is_module_name
15110s0sCPAN::Meta::Converter::::_is_urlishCPAN::Meta::Converter::_is_urlish
68110s0sCPAN::Meta::Converter::::_keepCPAN::Meta::Converter::_keep
17110s0sCPAN::Meta::Converter::::_keep_or_oneCPAN::Meta::Converter::_keep_or_one
17110s0sCPAN::Meta::Converter::::_keep_or_unknownCPAN::Meta::Converter::_keep_or_unknown
0000s0sCPAN::Meta::Converter::::_keep_or_zeroCPAN::Meta::Converter::_keep_or_zero
0000s0sCPAN::Meta::Converter::::_license_1CPAN::Meta::Converter::_license_1
8110s0sCPAN::Meta::Converter::::_license_2CPAN::Meta::Converter::_license_2
85210s0sCPAN::Meta::Converter::::_listifyCPAN::Meta::Converter::_listify
0000s0sCPAN::Meta::Converter::::_no_index_1_2CPAN::Meta::Converter::_no_index_1_2
17110s0sCPAN::Meta::Converter::::_no_index_directoryCPAN::Meta::Converter::_no_index_directory
0000s0sCPAN::Meta::Converter::::_no_prefix_ucfirst_customCPAN::Meta::Converter::_no_prefix_ucfirst_custom
0000s0sCPAN::Meta::Converter::::_optional_features_1_4CPAN::Meta::Converter::_optional_features_1_4
0000s0sCPAN::Meta::Converter::::_optional_features_as_mapCPAN::Meta::Converter::_optional_features_as_map
0000s0sCPAN::Meta::Converter::::_prefix_customCPAN::Meta::Converter::_prefix_custom
4110s0sCPAN::Meta::Converter::::_prereqs_from_1CPAN::Meta::Converter::_prereqs_from_1
10110s0sCPAN::Meta::Converter::::_prereqs_relCPAN::Meta::Converter::_prereqs_rel
17110s0sCPAN::Meta::Converter::::_providesCPAN::Meta::Converter::_provides
4110s0sCPAN::Meta::Converter::::_release_statusCPAN::Meta::Converter::_release_status
5210s0sCPAN::Meta::Converter::::_release_status_from_versionCPAN::Meta::Converter::_release_status_from_version
4110s0sCPAN::Meta::Converter::::_repo_typeCPAN::Meta::Converter::_repo_type
0000s0sCPAN::Meta::Converter::::_resources_1_2CPAN::Meta::Converter::_resources_1_2
0000s0sCPAN::Meta::Converter::::_resources_1_3CPAN::Meta::Converter::_resources_1_3
0000s0sCPAN::Meta::Converter::::_ucfirst_customCPAN::Meta::Converter::_ucfirst_custom
4110s0sCPAN::Meta::Converter::::_upgrade_optional_featuresCPAN::Meta::Converter::_upgrade_optional_features
4110s0sCPAN::Meta::Converter::::_upgrade_resources_2CPAN::Meta::Converter::_upgrade_resources_2
4110s0sCPAN::Meta::Converter::::_url_listCPAN::Meta::Converter::_url_list
15110s0sCPAN::Meta::Converter::::_url_or_dropCPAN::Meta::Converter::_url_or_drop
90410s0sCPAN::Meta::Converter::::_version_mapCPAN::Meta::Converter::_version_map
17310s156msCPAN::Meta::Converter::::convertCPAN::Meta::Converter::convert
17310s0sCPAN::Meta::Converter::::newCPAN::Meta::Converter::new
0000s0sCPAN::Meta::Converter::::upgrade_fragmentCPAN::Meta::Converter::upgrade_fragment
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
120s10s
# spent 0s within CPAN::Meta::BEGIN@1.4 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 1
use 5.006;
# spent 0s making 1 call to CPAN::Meta::BEGIN@1.4
220s20s
# spent 0s within CPAN::Meta::BEGIN@2.5 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 2
use strict;
# spent 0s making 1 call to CPAN::Meta::BEGIN@2.5 # spent 0s making 1 call to strict::import
320s20s
# spent 0s within CPAN::Meta::BEGIN@3.6 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 3
use warnings;
# spent 0s making 1 call to CPAN::Meta::BEGIN@3.6 # spent 0s making 1 call to warnings::import
4package CPAN::Meta::Converter;
5# VERSION
610s$CPAN::Meta::Converter::VERSION = '2.143240';
7#pod =head1 SYNOPSIS
8#pod
9#pod my $struct = decode_json_file('META.json');
10#pod
11#pod my $cmc = CPAN::Meta::Converter->new( $struct );
12#pod
13#pod my $new_struct = $cmc->convert( version => "2" );
14#pod
15#pod =head1 DESCRIPTION
16#pod
17#pod This module converts CPAN Meta structures from one form to another. The
18#pod primary use is to convert older structures to the most modern version of
19#pod the specification, but other transformations may be implemented in the
20#pod future as needed. (E.g. stripping all custom fields or stripping all
21#pod optional fields.)
22#pod
23#pod =cut
24
2520s10s
# spent 0s within CPAN::Meta::Converter::BEGIN@25 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 25
use CPAN::Meta::Validator;
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@25
2620s10s
# spent 0s within CPAN::Meta::Converter::BEGIN@26 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 26
use CPAN::Meta::Requirements;
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@26
2730s20s
# spent 0s within CPAN::Meta::Converter::BEGIN@27 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 27
use Parse::CPAN::Meta 1.4400 ();
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@27 # spent 0s making 1 call to version::vxs::_VERSION
28
29# To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls
30# before 5.10, we fall back to the EUMM bundled compatibility version module if
31# that's the only thing available. This shouldn't ever happen in a normal CPAN
32# install of CPAN::Meta::Requirements, as version.pm will be picked up from
33# prereqs and be available at runtime.
34
35
# spent 0s within CPAN::Meta::Converter::BEGIN@35 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 40
BEGIN {
3610s eval "use version ()"; ## no critic
# spent 0s executing statements in string eval
# includes 0s spent executing 1 call to 1 sub defined therein.
3710s if ( my $err = $@ ) {
38 eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic
39 }
4010s10s}
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@35
41
42# Perl 5.10.0 didn't have "is_qv" in version.pm
4310s10s*_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} };
# spent 0s making 1 call to UNIVERSAL::can
44
45
# spent 218ms (0s+218) within CPAN::Meta::Converter::_dclone which was called 54 times, avg 4.04ms/call: # 19 times (0s+62.4ms) by CPAN::Meta::as_struct at line 568 of CPAN/Meta.pm, avg 3.28ms/call # 18 times (0s+0s) by CPAN::Meta::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta.pm:168] at line 166 of CPAN/Meta.pm, avg 0s/call # 17 times (0s+156ms) by CPAN::Meta::Converter::convert at line 1408, avg 9.18ms/call
sub _dclone {
46540s my $ref = shift;
47
48 # if an object is in the data structure and doesn't specify how to
49 # turn itself into JSON, we just stringify the object. That does the
50 # right thing for typical things that might be there, like version objects,
51 # Path::Class objects, etc.
5220s20s
# spent 0s within CPAN::Meta::Converter::BEGIN@52 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 52
no warnings 'once';
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@52 # spent 0s making 1 call to warnings::unimport
5320s20s
# spent 0s within CPAN::Meta::Converter::BEGIN@53 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 53
no warnings 'redefine';
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@53 # spent 0s making 1 call to warnings::unimport
54540s local *UNIVERSAL::TO_JSON = sub { "$_[0]" };
55
56540s27031.2ms my $json = Parse::CPAN::Meta->json_backend()->new
# spent 15.6ms making 54 calls to JSON::PP::utf8, avg 289µs/call # spent 15.6ms making 54 calls to Parse::CPAN::Meta::json_backend, avg 289µs/call # spent 0s making 54 calls to JSON::PP::allow_blessed, avg 0s/call # spent 0s making 54 calls to JSON::PP::convert_blessed, avg 0s/call # spent 0s making 54 calls to JSON::PP::new, avg 0s/call
57 ->utf8
58 ->allow_blessed
59 ->convert_blessed;
60540s108187ms $json->decode($json->encode($ref))
# spent 109ms making 54 calls to JSON::PP::decode, avg 2.02ms/call # spent 78.0ms making 54 calls to JSON::PP::encode, avg 1.44ms/call
61}
62
6310smy %known_specs = (
64 '2' => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
65 '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
66 '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html',
67 '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
68 '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html',
69 '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html'
70);
71
7210s10smy @spec_list = sort { $a <=> $b } keys %known_specs;
# spent 0s making 1 call to CPAN::Meta::Converter::CORE:sort
7310smy ($LOWEST, $HIGHEST) = @spec_list[0,-1];
74
75#--------------------------------------------------------------------------#
76# converters
77#
78# called as $converter->($element, $field_name, $full_meta, $to_version)
79#
80# defined return value used for field
81# undef return value means field is skipped
82#--------------------------------------------------------------------------#
83
84680s
# spent 0s within CPAN::Meta::Converter::_keep which was called 68 times, avg 0s/call: # 68 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _keep { $_[0] }
85
86170s
# spent 0s within CPAN::Meta::Converter::_keep_or_one which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _keep_or_one { defined($_[0]) ? $_[0] : 1 }
87
88sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 }
89
90170s
# spent 0s within CPAN::Meta::Converter::_keep_or_unknown which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _keep_or_unknown { defined($_[0]) && length($_[0]) ? $_[0] : "unknown" }
91
92
# spent 0s within CPAN::Meta::Converter::_generated_by which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _generated_by {
93170s my $gen = shift;
94170s170s my $sig = __PACKAGE__ . " version " . (__PACKAGE__->VERSION || "<dev>");
# spent 0s making 17 calls to version::vxs::_VERSION, avg 0s/call
95
96170s return $sig unless defined $gen and length $gen;
97170s340s return $gen if $gen =~ /\Q$sig/;
# spent 0s making 17 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::CORE:regcomp, avg 0s/call
9860s return "$gen, $sig";
99}
100
101850s
# spent 0s within CPAN::Meta::Converter::_listify which was called 85 times, avg 0s/call: # 68 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call # 17 times (0s+0s) by CPAN::Meta::Converter::_author_list at line 617, avg 0s/call
sub _listify { ! defined $_[0] ? undef : ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] }
102
103sub _prefix_custom {
104 my $key = shift;
105 $key =~ s/^(?!x_) # Unless it already starts with x_
106 (?:x-?)? # Remove leading x- or x (if present)
107 /x_/ix; # and prepend x_
108 return $key;
109}
110
111sub _ucfirst_custom {
112 my $key = shift;
113 $key = ucfirst $key unless $key =~ /[A-Z]/;
114 return $key;
115}
116
117sub _no_prefix_ucfirst_custom {
118 my $key = shift;
119 $key =~ s/^x_//;
120 return _ucfirst_custom($key);
121}
122
123
# spent 0s within CPAN::Meta::Converter::_change_meta_spec which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _change_meta_spec {
124170s my ($element, undef, undef, $version) = @_;
125 return {
126170s version => $version,
127 url => $known_specs{$version},
128 };
129}
130
13110smy @open_source = (
132 'perl',
133 'gpl',
134 'apache',
135 'artistic',
136 'artistic_2',
137 'lgpl',
138 'bsd',
139 'gpl',
140 'mit',
141 'mozilla',
142 'open_source',
143);
144
14510smy %is_open_source = map {; $_ => 1 } @open_source;
146
14710smy @valid_licenses_1 = (
148 @open_source,
149 'unrestricted',
150 'restrictive',
151 'unknown',
152);
153
154my %license_map_1 = (
15510s ( map { $_ => $_ } @valid_licenses_1 ),
156 artistic2 => 'artistic_2',
157);
158
159sub _license_1 {
160 my ($element) = @_;
161 return 'unknown' unless defined $element;
162 if ( $license_map_1{lc $element} ) {
163 return $license_map_1{lc $element};
164 }
165 else {
166 return 'unknown';
167 }
168}
169
17010smy @valid_licenses_2 = qw(
171 agpl_3
172 apache_1_1
173 apache_2_0
174 artistic_1
175 artistic_2
176 bsd
177 freebsd
178 gfdl_1_2
179 gfdl_1_3
180 gpl_1
181 gpl_2
182 gpl_3
183 lgpl_2_1
184 lgpl_3_0
185 mit
186 mozilla_1_0
187 mozilla_1_1
188 openssl
189 perl_5
190 qpl_1_0
191 ssleay
192 sun
193 zlib
194 open_source
195 restricted
196 unrestricted
197 unknown
198);
199
200# The "old" values were defined by Module::Build, and were often vague. I have
201# made the decisions below based on reading Module::Build::API and how clearly
202# it specifies the version of the license.
203my %license_map_2 = (
20410s (map { $_ => $_ } @valid_licenses_2),
205 apache => 'apache_2_0', # clearly stated as 2.0
206 artistic => 'artistic_1', # clearly stated as 1
207 artistic2 => 'artistic_2', # clearly stated as 2
208 gpl => 'open_source', # we don't know which GPL; punt
209 lgpl => 'open_source', # we don't know which LGPL; punt
210 mozilla => 'open_source', # we don't know which MPL; punt
211 perl => 'perl_5', # clearly Perl 5
212 restrictive => 'restricted',
213);
214
215
# spent 0s within CPAN::Meta::Converter::_license_2 which was called 8 times, avg 0s/call: # 8 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _license_2 {
21680s my ($element) = @_;
21780s return [ 'unknown' ] unless defined $element;
21880s $element = [ $element ] unless ref $element eq 'ARRAY';
21980s my @new_list;
22080s for my $lic ( @$element ) {
22180s next unless defined $lic;
22280s if ( my $new = $license_map_2{lc $lic} ) {
223 push @new_list, $new;
224 }
225 }
22680s return @new_list ? \@new_list : [ 'unknown' ];
227}
228
22910smy %license_downgrade_map = qw(
230 agpl_3 open_source
231 apache_1_1 apache
232 apache_2_0 apache
233 artistic_1 artistic
234 artistic_2 artistic_2
235 bsd bsd
236 freebsd open_source
237 gfdl_1_2 open_source
238 gfdl_1_3 open_source
239 gpl_1 gpl
240 gpl_2 gpl
241 gpl_3 gpl
242 lgpl_2_1 lgpl
243 lgpl_3_0 lgpl
244 mit mit
245 mozilla_1_0 mozilla
246 mozilla_1_1 mozilla
247 openssl open_source
248 perl_5 perl
249 qpl_1_0 open_source
250 ssleay open_source
251 sun open_source
252 zlib open_source
253 open_source open_source
254 restricted restrictive
255 unrestricted unrestricted
256 unknown unknown
257);
258
259
# spent 0s within CPAN::Meta::Converter::_downgrade_license which was called 9 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _downgrade_license {
26090s my ($element) = @_;
26190s if ( ! defined $element ) {
262 return "unknown";
263 }
264 elsif( ref $element eq 'ARRAY' ) {
26590s if ( @$element > 1) {
266 if (grep { !$is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element) {
267 return 'unknown';
268 }
269 else {
270 return 'open_source';
271 }
272 }
273 elsif ( @$element == 1 ) {
274 return $license_downgrade_map{lc $element->[0]} || "unknown";
275 }
276 }
277 elsif ( ! ref $element ) {
278 return $license_downgrade_map{lc $element} || "unknown";
279 }
280 return "unknown";
281}
282
28310smy $no_index_spec_1_2 = {
284 'file' => \&_listify,
285 'dir' => \&_listify,
286 'package' => \&_listify,
287 'namespace' => \&_listify,
288};
289
29010smy $no_index_spec_1_3 = {
291 'file' => \&_listify,
292 'directory' => \&_listify,
293 'package' => \&_listify,
294 'namespace' => \&_listify,
295};
296
29710smy $no_index_spec_2 = {
298 'file' => \&_listify,
299 'directory' => \&_listify,
300 'package' => \&_listify,
301 'namespace' => \&_listify,
302 ':custom' => \&_prefix_custom,
303};
304
305sub _no_index_1_2 {
306 my (undef, undef, $meta) = @_;
307 my $no_index = $meta->{no_index} || $meta->{private};
308 return unless $no_index;
309
310 # cleanup wrong format
311 if ( ! ref $no_index ) {
312 my $item = $no_index;
313 $no_index = { dir => [ $item ], file => [ $item ] };
314 }
315 elsif ( ref $no_index eq 'ARRAY' ) {
316 my $list = $no_index;
317 $no_index = { dir => [ @$list ], file => [ @$list ] };
318 }
319
320 # common mistake: files -> file
321 if ( exists $no_index->{files} ) {
322 $no_index->{file} = delete $no_index->{file};
323 }
324 # common mistake: modules -> module
325 if ( exists $no_index->{modules} ) {
326 $no_index->{module} = delete $no_index->{module};
327 }
328 return _convert($no_index, $no_index_spec_1_2);
329}
330
331
# spent 0s within CPAN::Meta::Converter::_no_index_directory which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _no_index_directory {
332170s my ($element, $key, $meta, $version) = @_;
333170s return unless $element;
334
335 # cleanup wrong format
336170s if ( ! ref $element ) {
337 my $item = $element;
338 $element = { directory => [ $item ], file => [ $item ] };
339 }
340 elsif ( ref $element eq 'ARRAY' ) {
341 my $list = $element;
342 $element = { directory => [ @$list ], file => [ @$list ] };
343 }
344
345170s if ( exists $element->{dir} ) {
346 $element->{directory} = delete $element->{dir};
347 }
348 # common mistake: files -> file
349170s if ( exists $element->{files} ) {
350 $element->{file} = delete $element->{file};
351 }
352 # common mistake: modules -> module
353170s if ( exists $element->{modules} ) {
354 $element->{module} = delete $element->{module};
355 }
356170s my $spec = $version == 2 ? $no_index_spec_2 : $no_index_spec_1_3;
357170s170s return _convert($element, $spec);
# spent 0s making 17 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 1, sum of overlapping time 0s
358}
359
360
# spent 0s within CPAN::Meta::Converter::_is_module_name which was called 60 times, avg 0s/call: # 30 times (0s+0s) by CPAN::Meta::Converter::_version_map at line 405, avg 0s/call # 30 times (0s+0s) by CPAN::Meta::Converter::_version_map at line 411, avg 0s/call
sub _is_module_name {
361600s my $mod = shift;
362600s return unless defined $mod && length $mod;
363600s600s return $mod =~ m{^[A-Za-z][A-Za-z0-9_]*(?:::[A-Za-z0-9_]+)*$};
# spent 0s making 60 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call
364}
365
366sub _clean_version {
367 my ($element) = @_;
368 return 0 if ! defined $element;
369
370 $element =~ s{^\s*}{};
371 $element =~ s{\s*$}{};
372 $element =~ s{^\.}{0.};
373
374 return 0 if ! length $element;
375 return 0 if ( $element eq 'undef' || $element eq '<undef>' );
376
377 my $v = eval { version->new($element) };
378 # XXX check defined $v and not just $v because version objects leak memory
379 # in boolean context -- dagolden, 2012-02-03
380 if ( defined $v ) {
381 return _is_qv($v) ? $v->normal : $element;
382 }
383 else {
384 return 0;
385 }
386}
387
388sub _bad_version_hook {
389 my ($v) = @_;
390 $v =~ s{[a-z]+$}{}; # strip trailing alphabetics
391 my $vobj = eval { version->new($v) };
392 return defined($vobj) ? $vobj : version->new(0); # or give up
393}
394
395
# spent 0s within CPAN::Meta::Converter::_version_map which was called 90 times, avg 0s/call: # 54 times (0s+0s) by CPAN::Meta::Converter::_extract_prereqs at line 509, avg 0s/call # 24 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call # 8 times (0s+0s) by CPAN::Meta::Converter::_prereqs_from_1 at line 434, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::_prereqs_from_1 at line 438, avg 0s/call
sub _version_map {
396900s my ($element) = @_;
397900s return unless defined $element;
398450s if ( ref $element eq 'HASH' ) {
399 # XXX turn this into CPAN::Meta::Requirements with bad version hook
400 # and then turn it back into a hash
401450s450s my $new_map = CPAN::Meta::Requirements->new(
# spent 0s making 45 calls to CPAN::Meta::Requirements::new, avg 0s/call
402 { bad_version_hook => \&_bad_version_hook } # punt
403 );
404450s while ( my ($k,$v) = each %$element ) {
405300s300s next unless _is_module_name($k);
# spent 0s making 30 calls to CPAN::Meta::Converter::_is_module_name, avg 0s/call
406300s if ( !defined($v) || !length($v) || $v eq 'undef' || $v eq '<undef>' ) {
407 $v = 0;
408 }
409 # some weird, old META have bad yml with module => module
410 # so check if value is like a module name and not like a version
411300s300s if ( _is_module_name($v) && ! version::is_lax($v) ) {
# spent 0s making 30 calls to CPAN::Meta::Converter::_is_module_name, avg 0s/call
412 $new_map->add_minimum($k => 0);
413 $new_map->add_minimum($v => 0);
414 }
415300s300s $new_map->add_string_requirement($k => $v);
# spent 0s making 30 calls to CPAN::Meta::Requirements::add_string_requirement, avg 0s/call
416 }
417450s450s return $new_map->as_string_hash;
# spent 0s making 45 calls to CPAN::Meta::Requirements::as_string_hash, avg 0s/call
418 }
419 elsif ( ref $element eq 'ARRAY' ) {
420 my $hashref = { map { $_ => 0 } @$element };
421 return _version_map($hashref); # cleanup any weird stuff
422 }
423 elsif ( ref $element eq '' && length $element ) {
424 return { $element => 0 }
425 }
426 return;
427}
428
429
# spent 0s within CPAN::Meta::Converter::_prereqs_from_1 which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _prereqs_from_1 {
43040s my (undef, undef, $meta) = @_;
43140s my $prereqs = {};
43240s for my $phase ( qw/build configure/ ) {
43380s my $key = "${phase}_requires";
43480s80s $prereqs->{$phase}{requires} = _version_map($meta->{$key})
# spent 0s making 8 calls to CPAN::Meta::Converter::_version_map, avg 0s/call
435 if $meta->{$key};
436 }
43740s for my $rel ( qw/requires recommends conflicts/ ) {
438120s40s $prereqs->{runtime}{$rel} = _version_map($meta->{$rel})
# spent 0s making 4 calls to CPAN::Meta::Converter::_version_map, avg 0s/call
439 if $meta->{$rel};
440 }
44140s return $prereqs;
442}
443
44410smy $prereqs_spec = {
445 configure => \&_prereqs_rel,
446 build => \&_prereqs_rel,
447 test => \&_prereqs_rel,
448 runtime => \&_prereqs_rel,
449 develop => \&_prereqs_rel,
450 ':custom' => \&_prefix_custom,
451};
452
45310smy $relation_spec = {
454 requires => \&_version_map,
455 recommends => \&_version_map,
456 suggests => \&_version_map,
457 conflicts => \&_version_map,
458 ':custom' => \&_prefix_custom,
459};
460
461
# spent 0s within CPAN::Meta::Converter::_cleanup_prereqs which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _cleanup_prereqs {
46240s my ($prereqs, $key, $meta, $to_version) = @_;
46340s return unless $prereqs && ref $prereqs eq 'HASH';
46420s20s return _convert( $prereqs, $prereqs_spec, $to_version );
# spent 0s making 2 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 1, sum of overlapping time 0s
465}
466
467
# spent 0s within CPAN::Meta::Converter::_prereqs_rel which was called 10 times, avg 0s/call: # 10 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _prereqs_rel {
468100s my ($relation, $key, $meta, $to_version) = @_;
469100s return unless $relation && ref $relation eq 'HASH';
47060s60s return _convert( $relation, $relation_spec, $to_version );
# spent 0s making 6 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 2, sum of overlapping time 0s
471}
472
473
474
# spent 0s within CPAN::Meta::Converter::BEGIN@474 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 492
BEGIN {
47510s my @old_prereqs = qw(
476 requires
477 configure_requires
478 recommends
479 conflicts
480 );
481
48210s for ( @old_prereqs ) {
48340s my $sub = "_get_$_";
48440s80s my ($phase,$type) = split qr/_/, $_;
# spent 0s making 4 calls to CPAN::Meta::Converter::CORE:qr, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::CORE:regcomp, avg 0s/call
48540s if ( ! defined $type ) {
48630s $type = $phase;
48730s $phase = 'runtime';
488 }
48920s20s
# spent 0s within CPAN::Meta::Converter::BEGIN@489 which was called: # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 489
no strict 'refs';
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@489 # spent 0s making 1 call to strict::unimport
490400s360s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:490] which was called 36 times, avg 0s/call: # 36 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
*{$sub} = sub { _extract_prereqs($_[2]->{prereqs},$phase,$type) };
# spent 0s making 36 calls to CPAN::Meta::Converter::_extract_prereqs, avg 0s/call
491 }
492115.6ms10s}
# spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@474
493
494
# spent 0s within CPAN::Meta::Converter::_get_build_requires which was called 9 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _get_build_requires {
49590s my ($data, $key, $meta) = @_;
496
49790s90s my $test_h = _extract_prereqs($_[2]->{prereqs}, qw(test requires)) || {};
# spent 0s making 9 calls to CPAN::Meta::Converter::_extract_prereqs, avg 0s/call
49890s90s my $build_h = _extract_prereqs($_[2]->{prereqs}, qw(build requires)) || {};
# spent 0s making 9 calls to CPAN::Meta::Converter::_extract_prereqs, avg 0s/call
499
50090s90s my $test_req = CPAN::Meta::Requirements->from_string_hash($test_h);
# spent 0s making 9 calls to CPAN::Meta::Requirements::from_string_hash, avg 0s/call
50190s90s my $build_req = CPAN::Meta::Requirements->from_string_hash($build_h);
# spent 0s making 9 calls to CPAN::Meta::Requirements::from_string_hash, avg 0s/call
502
50390s180s $test_req->add_requirements($build_req)->as_string_hash;
# spent 0s making 9 calls to CPAN::Meta::Requirements::add_requirements, avg 0s/call # spent 0s making 9 calls to CPAN::Meta::Requirements::as_string_hash, avg 0s/call
504}
505
506
# spent 0s within CPAN::Meta::Converter::_extract_prereqs which was called 54 times, avg 0s/call: # 36 times (0s+0s) by CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:490] at line 490, avg 0s/call # 9 times (0s+0s) by CPAN::Meta::Converter::_get_build_requires at line 497, avg 0s/call # 9 times (0s+0s) by CPAN::Meta::Converter::_get_build_requires at line 498, avg 0s/call
sub _extract_prereqs {
507540s my ($prereqs, $phase, $type) = @_;
508540s return unless ref $prereqs eq 'HASH';
509540s540s return scalar _version_map($prereqs->{$phase}{$type});
# spent 0s making 54 calls to CPAN::Meta::Converter::_version_map, avg 0s/call
510}
511
512
# spent 0s within CPAN::Meta::Converter::_downgrade_optional_features which was called 9 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _downgrade_optional_features {
51390s my (undef, undef, $meta) = @_;
51490s return unless exists $meta->{optional_features};
515 my $origin = $meta->{optional_features};
516 my $features = {};
517 for my $name ( keys %$origin ) {
518 $features->{$name} = {
519 description => $origin->{$name}{description},
520 requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','requires'),
521 configure_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','configure_requires'),
522 build_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','build_requires'),
523 recommends => _extract_prereqs($origin->{$name}{prereqs},'runtime','recommends'),
524 conflicts => _extract_prereqs($origin->{$name}{prereqs},'runtime','conflicts'),
525 };
526 for my $k (keys %{$features->{$name}} ) {
527 delete $features->{$name}{$k} unless defined $features->{$name}{$k};
528 }
529 }
530 return $features;
531}
532
533
# spent 0s within CPAN::Meta::Converter::_upgrade_optional_features which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _upgrade_optional_features {
53440s my (undef, undef, $meta) = @_;
53540s return unless exists $meta->{optional_features};
536 my $origin = $meta->{optional_features};
537 my $features = {};
538 for my $name ( keys %$origin ) {
539 $features->{$name} = {
540 description => $origin->{$name}{description},
541 prereqs => _prereqs_from_1(undef, undef, $origin->{$name}),
542 };
543 delete $features->{$name}{prereqs}{configure};
544 }
545 return $features;
546}
547
54810smy $optional_features_2_spec = {
549 description => \&_keep,
550 prereqs => \&_cleanup_prereqs,
551 ':custom' => \&_prefix_custom,
552};
553
554sub _feature_2 {
555 my ($element, $key, $meta, $to_version) = @_;
556 return unless $element && ref $element eq 'HASH';
557 _convert( $element, $optional_features_2_spec, $to_version );
558}
559
560
# spent 0s within CPAN::Meta::Converter::_cleanup_optional_features_2 which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _cleanup_optional_features_2 {
56140s my ($element, $key, $meta, $to_version) = @_;
56240s return unless $element && ref $element eq 'HASH';
563 my $new_data = {};
564 for my $k ( keys %$element ) {
565 $new_data->{$k} = _feature_2( $element->{$k}, $k, $meta, $to_version );
566 }
567 return unless keys %$new_data;
568 return $new_data;
569}
570
571sub _optional_features_1_4 {
572 my ($element) = @_;
573 return unless $element;
574 $element = _optional_features_as_map($element);
575 for my $name ( keys %$element ) {
576 for my $drop ( qw/requires_packages requires_os excluded_os/ ) {
577 delete $element->{$name}{$drop};
578 }
579 }
580 return $element;
581}
582
583sub _optional_features_as_map {
584 my ($element) = @_;
585 return unless $element;
586 if ( ref $element eq 'ARRAY' ) {
587 my %map;
588 for my $feature ( @$element ) {
589 my (@parts) = %$feature;
590 $map{$parts[0]} = $parts[1];
591 }
592 $element = \%map;
593 }
594 return $element;
595}
596
597150s80s
# spent 0s within CPAN::Meta::Converter::_is_urlish which was called 15 times, avg 0s/call: # 15 times (0s+0s) by CPAN::Meta::Converter::_url_or_drop at line 601, avg 0s/call
sub _is_urlish { defined $_[0] && $_[0] =~ m{\A[-+.a-z0-9]+:.+}i }
# spent 0s making 8 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call
598
599
# spent 0s within CPAN::Meta::Converter::_url_or_drop which was called 15 times, avg 0s/call: # 15 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _url_or_drop {
600150s my ($element) = @_;
601150s150s return $element if _is_urlish($element);
# spent 0s making 15 calls to CPAN::Meta::Converter::_is_urlish, avg 0s/call
60270s return;
603}
604
605
# spent 0s within CPAN::Meta::Converter::_url_list which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _url_list {
60640s my ($element) = @_;
60740s return unless $element;
608 $element = _listify( $element );
609 $element = [ grep { _is_urlish($_) } @$element ];
610 return unless @$element;
611 return $element;
612}
613
614
# spent 0s within CPAN::Meta::Converter::_author_list which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _author_list {
615170s my ($element) = @_;
616170s return [ 'unknown' ] unless $element;
617170s170s $element = _listify( $element );
# spent 0s making 17 calls to CPAN::Meta::Converter::_listify, avg 0s/call
618170s $element = [ map { defined $_ && length $_ ? $_ : 'unknown' } @$element ];
619170s return [ 'unknown' ] unless @$element;
620130s return $element;
621}
622
623my $resource2_upgrade = {
624 license => sub { return _is_urlish($_[0]) ? _listify( $_[0] ) : undef },
625 homepage => \&_url_or_drop,
626 bugtracker => sub {
627 my ($item) = @_;
628 return unless $item;
629 if ( $item =~ m{^mailto:(.*)$} ) { return { mailto => $1 } }
630 elsif( _is_urlish($item) ) { return { web => $item } }
631 else { return }
632 },
633 repository => sub { return _is_urlish($_[0]) ? { url => $_[0] } : undef },
63410s ':custom' => \&_prefix_custom,
635};
636
637
# spent 0s within CPAN::Meta::Converter::_upgrade_resources_2 which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _upgrade_resources_2 {
63840s my (undef, undef, $meta, $version) = @_;
63940s return unless exists $meta->{resources};
640 return _convert($meta->{resources}, $resource2_upgrade);
641}
642
64310smy $bugtracker2_spec = {
644 web => \&_url_or_drop,
645 mailto => \&_keep,
646 ':custom' => \&_prefix_custom,
647};
648
649
# spent 0s within CPAN::Meta::Converter::_repo_type which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _repo_type {
65040s my ($element, $key, $meta, $to_version) = @_;
65140s return $element if defined $element;
652 return unless exists $meta->{url};
653 my $repo_url = $meta->{url};
654 for my $type ( qw/git svn/ ) {
655 return $type if $repo_url =~ m{\A$type};
656 }
657 return;
658}
659
66010smy $repository2_spec = {
661 web => \&_url_or_drop,
662 url => \&_url_or_drop,
663 type => \&_repo_type,
664 ':custom' => \&_prefix_custom,
665};
666
667my $resources2_cleanup = {
668 license => \&_url_list,
669 homepage => \&_url_or_drop,
67040s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:670] which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
bugtracker => sub { ref $_[0] ? _convert( $_[0], $bugtracker2_spec ) : undef },
67180s40s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:671] which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
repository => sub { my $data = shift; ref $data ? _convert( $data, $repository2_spec ) : undef },
# spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 2, sum of overlapping time 0s
67210s ':custom' => \&_prefix_custom,
673};
674
675
# spent 0s within CPAN::Meta::Converter::_cleanup_resources_2 which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _cleanup_resources_2 {
67640s my ($resources, $key, $meta, $to_version) = @_;
67740s return unless $resources && ref $resources eq 'HASH';
67840s40s return _convert($resources, $resources2_cleanup, $to_version);
# spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 1, sum of overlapping time 0s
679}
680
68110smy $resource1_spec = {
682 license => \&_url_or_drop,
683 homepage => \&_url_or_drop,
684 bugtracker => \&_url_or_drop,
685 repository => \&_url_or_drop,
686 ':custom' => \&_keep,
687};
688
689sub _resources_1_3 {
690 my (undef, undef, $meta, $version) = @_;
691 return unless exists $meta->{resources};
692 return _convert($meta->{resources}, $resource1_spec);
693}
694
69510s*_resources_1_4 = *_resources_1_3;
696
697sub _resources_1_2 {
698 my (undef, undef, $meta) = @_;
699 my $resources = $meta->{resources} || {};
700 if ( $meta->{license_url} && ! $resources->{license} ) {
701 $resources->{license} = $meta->{license_url}
702 if _is_urlish($meta->{license_url});
703 }
704 return unless keys %$resources;
705 return _convert($resources, $resource1_spec);
706}
707
708my $resource_downgrade_spec = {
70930s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:709] which was called 3 times, avg 0s/call: # 3 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
license => sub { return ref $_[0] ? $_[0]->[0] : $_[0] },
710 homepage => \&_url_or_drop,
71130s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:711] which was called 3 times, avg 0s/call: # 3 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
bugtracker => sub { return $_[0]->{web} },
71230s
# spent 0s within CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:712] which was called 3 times, avg 0s/call: # 3 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
repository => sub { return $_[0]->{url} || $_[0]->{web} },
71310s ':custom' => \&_no_prefix_ucfirst_custom,
714};
715
716
# spent 0s within CPAN::Meta::Converter::_downgrade_resources which was called 9 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _downgrade_resources {
71790s my (undef, undef, $meta, $version) = @_;
71890s return unless exists $meta->{resources};
71930s30s return _convert($meta->{resources}, $resource_downgrade_spec);
# spent 0s making 3 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 1, sum of overlapping time 0s
720}
721
722
# spent 0s within CPAN::Meta::Converter::_release_status which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _release_status {
72340s my ($element, undef, $meta) = @_;
72440s30s return $element if $element && $element =~ m{\A(?:stable|testing|unstable)\z};
# spent 0s making 3 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call
72510s10s return _release_status_from_version(undef, undef, $meta);
726}
727
728
# spent 0s within CPAN::Meta::Converter::_release_status_from_version which was called 5 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call # once (0s+0s) by CPAN::Meta::Converter::_release_status at line 725
sub _release_status_from_version {
72950s my (undef, undef, $meta) = @_;
73050s my $version = $meta->{version} || '';
73150s50s return ( $version =~ /_/ ) ? 'testing' : 'stable';
# spent 0s making 5 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call
732}
733
73410smy $provides_spec = {
735 file => \&_keep,
736 version => \&_keep,
737};
738
73910smy $provides_spec_2 = {
740 file => \&_keep,
741 version => \&_keep,
742 ':custom' => \&_prefix_custom,
743};
744
745
# spent 0s within CPAN::Meta::Converter::_provides which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_convert at line 770, avg 0s/call
sub _provides {
746170s my ($element, $key, $meta, $to_version) = @_;
747170s return unless defined $element && ref $element eq 'HASH';
748 my $spec = $to_version == 2 ? $provides_spec_2 : $provides_spec;
749 my $new_data = {};
750 for my $k ( keys %$element ) {
751 $new_data->{$k} = _convert($element->{$k}, $spec, $to_version);
752 $new_data->{$k}{version} = _clean_version($element->{$k}{version})
753 if exists $element->{$k}{version};
754 }
755 return $new_data;
756}
757
758
# spent 0s within CPAN::Meta::Converter::_convert which was called 53 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_no_index_directory at line 357, avg 0s/call # 9 times (0s+0s) by CPAN::Meta::Converter::convert at line 1427, avg 0s/call # 6 times (0s+0s) by CPAN::Meta::Converter::_prereqs_rel at line 470, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::__ANON__[C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm:671] at line 671, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::_cleanup_resources_2 at line 678, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1411, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1444, avg 0s/call # 3 times (0s+0s) by CPAN::Meta::Converter::_downgrade_resources at line 719, avg 0s/call # 2 times (0s+0s) by CPAN::Meta::Converter::_cleanup_prereqs at line 464, avg 0s/call
sub _convert {
759530s my ($data, $spec, $to_version, $is_fragment) = @_;
760
761530s my $new_data = {};
762530s for my $key ( keys %$spec ) {
7635020s next if $key eq ':custom' || $key eq ':drop';
7644410s next unless my $fcn = $spec->{$key};
7654410s if ( $is_fragment && $key eq 'generated_by' ) {
766 $fcn = \&_keep;
767 }
7684410s die "spec for '$key' is not a coderef"
769 unless ref $fcn && ref $fcn eq 'CODE';
7704410s4410s my $new_value = $fcn->($data->{$key}, $key, $data, $to_version);
# spent 0s making 36 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:490], avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:670], avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:671], avg 0s/call # spent 0s making 3 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:709], avg 0s/call # spent 0s making 3 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:711], avg 0s/call # spent 0s making 3 calls to CPAN::Meta::Converter::__ANON__[CPAN/Meta/Converter.pm:712], avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_author_list, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_change_meta_spec, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_cleanup_optional_features_2, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_cleanup_prereqs, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_cleanup_resources_2, avg 0s/call # spent 0s making 9 calls to CPAN::Meta::Converter::_downgrade_license, avg 0s/call # spent 0s making 9 calls to CPAN::Meta::Converter::_downgrade_optional_features, avg 0s/call # spent 0s making 9 calls to CPAN::Meta::Converter::_downgrade_resources, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_generated_by, avg 0s/call # spent 0s making 9 calls to CPAN::Meta::Converter::_get_build_requires, avg 0s/call # spent 0s making 68 calls to CPAN::Meta::Converter::_keep, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_keep_or_one, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_keep_or_unknown, avg 0s/call # spent 0s making 8 calls to CPAN::Meta::Converter::_license_2, avg 0s/call # spent 0s making 68 calls to CPAN::Meta::Converter::_listify, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_no_index_directory, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_prereqs_from_1, avg 0s/call # spent 0s making 10 calls to CPAN::Meta::Converter::_prereqs_rel, avg 0s/call # spent 0s making 17 calls to CPAN::Meta::Converter::_provides, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_release_status, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_release_status_from_version, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_repo_type, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_upgrade_optional_features, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_upgrade_resources_2, avg 0s/call # spent 0s making 4 calls to CPAN::Meta::Converter::_url_list, avg 0s/call # spent 0s making 15 calls to CPAN::Meta::Converter::_url_or_drop, avg 0s/call # spent 0s making 24 calls to CPAN::Meta::Converter::_version_map, avg 0s/call
7714410s $new_data->{$key} = $new_value if defined $new_value;
772 }
773
774530s my $drop_list = $spec->{':drop'};
775530s my $customizer = $spec->{':custom'} || \&_keep;
776
777530s for my $key ( keys %$data ) {
7782510s next if $drop_list && grep { $key eq $_ } @$drop_list;
7792160s next if exists $spec->{$key}; # we handled it
780 $new_data->{ $customizer->($key) } = $data->{$key};
781 }
782
783530s return $new_data;
784}
785
786#--------------------------------------------------------------------------#
787# define converters for each conversion
788#--------------------------------------------------------------------------#
789
790# each converts from prior version
791# special ":custom" field is used for keys not recognized in spec
79210smy %up_convert = (
793 '2-from-1.4' => {
794 # PRIOR MANDATORY
795 'abstract' => \&_keep_or_unknown,
796 'author' => \&_author_list,
797 'generated_by' => \&_generated_by,
798 'license' => \&_license_2,
799 'meta-spec' => \&_change_meta_spec,
800 'name' => \&_keep,
801 'version' => \&_keep,
802 # CHANGED TO MANDATORY
803 'dynamic_config' => \&_keep_or_one,
804 # ADDED MANDATORY
805 'release_status' => \&_release_status_from_version,
806 # PRIOR OPTIONAL
807 'keywords' => \&_keep,
808 'no_index' => \&_no_index_directory,
809 'optional_features' => \&_upgrade_optional_features,
810 'provides' => \&_provides,
811 'resources' => \&_upgrade_resources_2,
812 # ADDED OPTIONAL
813 'description' => \&_keep,
814 'prereqs' => \&_prereqs_from_1,
815
816 # drop these deprecated fields, but only after we convert
817 ':drop' => [ qw(
818 build_requires
819 configure_requires
820 conflicts
821 distribution_type
822 license_url
823 private
824 recommends
825 requires
826 ) ],
827
828 # other random keys need x_ prefixing
829 ':custom' => \&_prefix_custom,
830 },
831 '1.4-from-1.3' => {
832 # PRIOR MANDATORY
833 'abstract' => \&_keep_or_unknown,
834 'author' => \&_author_list,
835 'generated_by' => \&_generated_by,
836 'license' => \&_license_1,
837 'meta-spec' => \&_change_meta_spec,
838 'name' => \&_keep,
839 'version' => \&_keep,
840 # PRIOR OPTIONAL
841 'build_requires' => \&_version_map,
842 'conflicts' => \&_version_map,
843 'distribution_type' => \&_keep,
844 'dynamic_config' => \&_keep_or_one,
845 'keywords' => \&_keep,
846 'no_index' => \&_no_index_directory,
847 'optional_features' => \&_optional_features_1_4,
848 'provides' => \&_provides,
849 'recommends' => \&_version_map,
850 'requires' => \&_version_map,
851 'resources' => \&_resources_1_4,
852 # ADDED OPTIONAL
853 'configure_requires' => \&_keep,
854
855 # drop these deprecated fields, but only after we convert
856 ':drop' => [ qw(
857 license_url
858 private
859 )],
860
861 # other random keys are OK if already valid
862 ':custom' => \&_keep
863 },
864 '1.3-from-1.2' => {
865 # PRIOR MANDATORY
866 'abstract' => \&_keep_or_unknown,
867 'author' => \&_author_list,
868 'generated_by' => \&_generated_by,
869 'license' => \&_license_1,
870 'meta-spec' => \&_change_meta_spec,
871 'name' => \&_keep,
872 'version' => \&_keep,
873 # PRIOR OPTIONAL
874 'build_requires' => \&_version_map,
875 'conflicts' => \&_version_map,
876 'distribution_type' => \&_keep,
877 'dynamic_config' => \&_keep_or_one,
878 'keywords' => \&_keep,
879 'no_index' => \&_no_index_directory,
880 'optional_features' => \&_optional_features_as_map,
881 'provides' => \&_provides,
882 'recommends' => \&_version_map,
883 'requires' => \&_version_map,
884 'resources' => \&_resources_1_3,
885
886 # drop these deprecated fields, but only after we convert
887 ':drop' => [ qw(
888 license_url
889 private
890 )],
891
892 # other random keys are OK if already valid
893 ':custom' => \&_keep
894 },
895 '1.2-from-1.1' => {
896 # PRIOR MANDATORY
897 'version' => \&_keep,
898 # CHANGED TO MANDATORY
899 'license' => \&_license_1,
900 'name' => \&_keep,
901 'generated_by' => \&_generated_by,
902 # ADDED MANDATORY
903 'abstract' => \&_keep_or_unknown,
904 'author' => \&_author_list,
905 'meta-spec' => \&_change_meta_spec,
906 # PRIOR OPTIONAL
907 'build_requires' => \&_version_map,
908 'conflicts' => \&_version_map,
909 'distribution_type' => \&_keep,
910 'dynamic_config' => \&_keep_or_one,
911 'recommends' => \&_version_map,
912 'requires' => \&_version_map,
913 # ADDED OPTIONAL
914 'keywords' => \&_keep,
915 'no_index' => \&_no_index_1_2,
916 'optional_features' => \&_optional_features_as_map,
917 'provides' => \&_provides,
918 'resources' => \&_resources_1_2,
919
920 # drop these deprecated fields, but only after we convert
921 ':drop' => [ qw(
922 license_url
923 private
924 )],
925
926 # other random keys are OK if already valid
927 ':custom' => \&_keep
928 },
929 '1.1-from-1.0' => {
930 # CHANGED TO MANDATORY
931 'version' => \&_keep,
932 # IMPLIED MANDATORY
933 'name' => \&_keep,
934 # PRIOR OPTIONAL
935 'build_requires' => \&_version_map,
936 'conflicts' => \&_version_map,
937 'distribution_type' => \&_keep,
938 'dynamic_config' => \&_keep_or_one,
939 'generated_by' => \&_generated_by,
940 'license' => \&_license_1,
941 'recommends' => \&_version_map,
942 'requires' => \&_version_map,
943 # ADDED OPTIONAL
944 'license_url' => \&_url_or_drop,
945 'private' => \&_keep,
946
947 # other random keys are OK if already valid
948 ':custom' => \&_keep
949 },
950);
951
95210smy %down_convert = (
953 '1.4-from-2' => {
954 # MANDATORY
955 'abstract' => \&_keep_or_unknown,
956 'author' => \&_author_list,
957 'generated_by' => \&_generated_by,
958 'license' => \&_downgrade_license,
959 'meta-spec' => \&_change_meta_spec,
960 'name' => \&_keep,
961 'version' => \&_keep,
962 # OPTIONAL
963 'build_requires' => \&_get_build_requires,
964 'configure_requires' => \&_get_configure_requires,
965 'conflicts' => \&_get_conflicts,
966 'distribution_type' => \&_keep,
967 'dynamic_config' => \&_keep_or_one,
968 'keywords' => \&_keep,
969 'no_index' => \&_no_index_directory,
970 'optional_features' => \&_downgrade_optional_features,
971 'provides' => \&_provides,
972 'recommends' => \&_get_recommends,
973 'requires' => \&_get_requires,
974 'resources' => \&_downgrade_resources,
975
976 # drop these unsupported fields (after conversion)
977 ':drop' => [ qw(
978 description
979 prereqs
980 release_status
981 )],
982
983 # custom keys will be left unchanged
984 ':custom' => \&_keep
985 },
986 '1.3-from-1.4' => {
987 # MANDATORY
988 'abstract' => \&_keep_or_unknown,
989 'author' => \&_author_list,
990 'generated_by' => \&_generated_by,
991 'license' => \&_license_1,
992 'meta-spec' => \&_change_meta_spec,
993 'name' => \&_keep,
994 'version' => \&_keep,
995 # OPTIONAL
996 'build_requires' => \&_version_map,
997 'conflicts' => \&_version_map,
998 'distribution_type' => \&_keep,
999 'dynamic_config' => \&_keep_or_one,
1000 'keywords' => \&_keep,
1001 'no_index' => \&_no_index_directory,
1002 'optional_features' => \&_optional_features_as_map,
1003 'provides' => \&_provides,
1004 'recommends' => \&_version_map,
1005 'requires' => \&_version_map,
1006 'resources' => \&_resources_1_3,
1007
1008 # drop these unsupported fields, but only after we convert
1009 ':drop' => [ qw(
1010 configure_requires
1011 )],
1012
1013 # other random keys are OK if already valid
1014 ':custom' => \&_keep,
1015 },
1016 '1.2-from-1.3' => {
1017 # MANDATORY
1018 'abstract' => \&_keep_or_unknown,
1019 'author' => \&_author_list,
1020 'generated_by' => \&_generated_by,
1021 'license' => \&_license_1,
1022 'meta-spec' => \&_change_meta_spec,
1023 'name' => \&_keep,
1024 'version' => \&_keep,
1025 # OPTIONAL
1026 'build_requires' => \&_version_map,
1027 'conflicts' => \&_version_map,
1028 'distribution_type' => \&_keep,
1029 'dynamic_config' => \&_keep_or_one,
1030 'keywords' => \&_keep,
1031 'no_index' => \&_no_index_1_2,
1032 'optional_features' => \&_optional_features_as_map,
1033 'provides' => \&_provides,
1034 'recommends' => \&_version_map,
1035 'requires' => \&_version_map,
1036 'resources' => \&_resources_1_3,
1037
1038 # other random keys are OK if already valid
1039 ':custom' => \&_keep,
1040 },
1041 '1.1-from-1.2' => {
1042 # MANDATORY
1043 'version' => \&_keep,
1044 # IMPLIED MANDATORY
1045 'name' => \&_keep,
1046 'meta-spec' => \&_change_meta_spec,
1047 # OPTIONAL
1048 'build_requires' => \&_version_map,
1049 'conflicts' => \&_version_map,
1050 'distribution_type' => \&_keep,
1051 'dynamic_config' => \&_keep_or_one,
1052 'generated_by' => \&_generated_by,
1053 'license' => \&_license_1,
1054 'private' => \&_keep,
1055 'recommends' => \&_version_map,
1056 'requires' => \&_version_map,
1057
1058 # drop unsupported fields
1059 ':drop' => [ qw(
1060 abstract
1061 author
1062 provides
1063 no_index
1064 keywords
1065 resources
1066 )],
1067
1068 # other random keys are OK if already valid
1069 ':custom' => \&_keep,
1070 },
1071 '1.0-from-1.1' => {
1072 # IMPLIED MANDATORY
1073 'name' => \&_keep,
1074 'meta-spec' => \&_change_meta_spec,
1075 'version' => \&_keep,
1076 # PRIOR OPTIONAL
1077 'build_requires' => \&_version_map,
1078 'conflicts' => \&_version_map,
1079 'distribution_type' => \&_keep,
1080 'dynamic_config' => \&_keep_or_one,
1081 'generated_by' => \&_generated_by,
1082 'license' => \&_license_1,
1083 'recommends' => \&_version_map,
1084 'requires' => \&_version_map,
1085
1086 # other random keys are OK if already valid
1087 ':custom' => \&_keep,
1088 },
1089);
1090
109110smy %cleanup = (
1092 '2' => {
1093 # PRIOR MANDATORY
1094 'abstract' => \&_keep_or_unknown,
1095 'author' => \&_author_list,
1096 'generated_by' => \&_generated_by,
1097 'license' => \&_license_2,
1098 'meta-spec' => \&_change_meta_spec,
1099 'name' => \&_keep,
1100 'version' => \&_keep,
1101 # CHANGED TO MANDATORY
1102 'dynamic_config' => \&_keep_or_one,
1103 # ADDED MANDATORY
1104 'release_status' => \&_release_status,
1105 # PRIOR OPTIONAL
1106 'keywords' => \&_keep,
1107 'no_index' => \&_no_index_directory,
1108 'optional_features' => \&_cleanup_optional_features_2,
1109 'provides' => \&_provides,
1110 'resources' => \&_cleanup_resources_2,
1111 # ADDED OPTIONAL
1112 'description' => \&_keep,
1113 'prereqs' => \&_cleanup_prereqs,
1114
1115 # drop these deprecated fields, but only after we convert
1116 ':drop' => [ qw(
1117 build_requires
1118 configure_requires
1119 conflicts
1120 distribution_type
1121 license_url
1122 private
1123 recommends
1124 requires
1125 ) ],
1126
1127 # other random keys need x_ prefixing
1128 ':custom' => \&_prefix_custom,
1129 },
1130 '1.4' => {
1131 # PRIOR MANDATORY
1132 'abstract' => \&_keep_or_unknown,
1133 'author' => \&_author_list,
1134 'generated_by' => \&_generated_by,
1135 'license' => \&_license_1,
1136 'meta-spec' => \&_change_meta_spec,
1137 'name' => \&_keep,
1138 'version' => \&_keep,
1139 # PRIOR OPTIONAL
1140 'build_requires' => \&_version_map,
1141 'conflicts' => \&_version_map,
1142 'distribution_type' => \&_keep,
1143 'dynamic_config' => \&_keep_or_one,
1144 'keywords' => \&_keep,
1145 'no_index' => \&_no_index_directory,
1146 'optional_features' => \&_optional_features_1_4,
1147 'provides' => \&_provides,
1148 'recommends' => \&_version_map,
1149 'requires' => \&_version_map,
1150 'resources' => \&_resources_1_4,
1151 # ADDED OPTIONAL
1152 'configure_requires' => \&_keep,
1153
1154 # other random keys are OK if already valid
1155 ':custom' => \&_keep
1156 },
1157 '1.3' => {
1158 # PRIOR MANDATORY
1159 'abstract' => \&_keep_or_unknown,
1160 'author' => \&_author_list,
1161 'generated_by' => \&_generated_by,
1162 'license' => \&_license_1,
1163 'meta-spec' => \&_change_meta_spec,
1164 'name' => \&_keep,
1165 'version' => \&_keep,
1166 # PRIOR OPTIONAL
1167 'build_requires' => \&_version_map,
1168 'conflicts' => \&_version_map,
1169 'distribution_type' => \&_keep,
1170 'dynamic_config' => \&_keep_or_one,
1171 'keywords' => \&_keep,
1172 'no_index' => \&_no_index_directory,
1173 'optional_features' => \&_optional_features_as_map,
1174 'provides' => \&_provides,
1175 'recommends' => \&_version_map,
1176 'requires' => \&_version_map,
1177 'resources' => \&_resources_1_3,
1178
1179 # other random keys are OK if already valid
1180 ':custom' => \&_keep
1181 },
1182 '1.2' => {
1183 # PRIOR MANDATORY
1184 'version' => \&_keep,
1185 # CHANGED TO MANDATORY
1186 'license' => \&_license_1,
1187 'name' => \&_keep,
1188 'generated_by' => \&_generated_by,
1189 # ADDED MANDATORY
1190 'abstract' => \&_keep_or_unknown,
1191 'author' => \&_author_list,
1192 'meta-spec' => \&_change_meta_spec,
1193 # PRIOR OPTIONAL
1194 'build_requires' => \&_version_map,
1195 'conflicts' => \&_version_map,
1196 'distribution_type' => \&_keep,
1197 'dynamic_config' => \&_keep_or_one,
1198 'recommends' => \&_version_map,
1199 'requires' => \&_version_map,
1200 # ADDED OPTIONAL
1201 'keywords' => \&_keep,
1202 'no_index' => \&_no_index_1_2,
1203 'optional_features' => \&_optional_features_as_map,
1204 'provides' => \&_provides,
1205 'resources' => \&_resources_1_2,
1206
1207 # other random keys are OK if already valid
1208 ':custom' => \&_keep
1209 },
1210 '1.1' => {
1211 # CHANGED TO MANDATORY
1212 'version' => \&_keep,
1213 # IMPLIED MANDATORY
1214 'name' => \&_keep,
1215 'meta-spec' => \&_change_meta_spec,
1216 # PRIOR OPTIONAL
1217 'build_requires' => \&_version_map,
1218 'conflicts' => \&_version_map,
1219 'distribution_type' => \&_keep,
1220 'dynamic_config' => \&_keep_or_one,
1221 'generated_by' => \&_generated_by,
1222 'license' => \&_license_1,
1223 'recommends' => \&_version_map,
1224 'requires' => \&_version_map,
1225 # ADDED OPTIONAL
1226 'license_url' => \&_url_or_drop,
1227 'private' => \&_keep,
1228
1229 # other random keys are OK if already valid
1230 ':custom' => \&_keep
1231 },
1232 '1.0' => {
1233 # IMPLIED MANDATORY
1234 'name' => \&_keep,
1235 'meta-spec' => \&_change_meta_spec,
1236 'version' => \&_keep,
1237 # IMPLIED OPTIONAL
1238 'build_requires' => \&_version_map,
1239 'conflicts' => \&_version_map,
1240 'distribution_type' => \&_keep,
1241 'dynamic_config' => \&_keep_or_one,
1242 'generated_by' => \&_generated_by,
1243 'license' => \&_license_1,
1244 'recommends' => \&_version_map,
1245 'requires' => \&_version_map,
1246
1247 # other random keys are OK if already valid
1248 ':custom' => \&_keep,
1249 },
1250);
1251
1252# for a given field in a spec version, what fields will it feed
1253# into in the *latest* spec (i.e. v2); meta-spec omitted because
1254# we always expect a meta-spec to be generated
125510smy %fragments_generate = (
1256 '2' => {
1257 'abstract' => 'abstract',
1258 'author' => 'author',
1259 'generated_by' => 'generated_by',
1260 'license' => 'license',
1261 'name' => 'name',
1262 'version' => 'version',
1263 'dynamic_config' => 'dynamic_config',
1264 'release_status' => 'release_status',
1265 'keywords' => 'keywords',
1266 'no_index' => 'no_index',
1267 'optional_features' => 'optional_features',
1268 'provides' => 'provides',
1269 'resources' => 'resources',
1270 'description' => 'description',
1271 'prereqs' => 'prereqs',
1272 },
1273 '1.4' => {
1274 'abstract' => 'abstract',
1275 'author' => 'author',
1276 'generated_by' => 'generated_by',
1277 'license' => 'license',
1278 'name' => 'name',
1279 'version' => 'version',
1280 'build_requires' => 'prereqs',
1281 'conflicts' => 'prereqs',
1282 'distribution_type' => 'distribution_type',
1283 'dynamic_config' => 'dynamic_config',
1284 'keywords' => 'keywords',
1285 'no_index' => 'no_index',
1286 'optional_features' => 'optional_features',
1287 'provides' => 'provides',
1288 'recommends' => 'prereqs',
1289 'requires' => 'prereqs',
1290 'resources' => 'resources',
1291 'configure_requires' => 'prereqs',
1292 },
1293);
1294# this is not quite true but will work well enough
1295# as 1.4 is a superset of earlier ones
129610s$fragments_generate{$_} = $fragments_generate{'1.4'} for qw/1.3 1.2 1.1 1.0/;
1297
1298#--------------------------------------------------------------------------#
1299# Code
1300#--------------------------------------------------------------------------#
1301
1302#pod =method new
1303#pod
1304#pod my $cmc = CPAN::Meta::Converter->new( $struct );
1305#pod
1306#pod The constructor should be passed a valid metadata structure but invalid
1307#pod structures are accepted. If no meta-spec version is provided, version 1.0 will
1308#pod be assumed.
1309#pod
1310#pod Optionally, you can provide a C<default_version> argument after C<$struct>:
1311#pod
1312#pod my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
1313#pod
1314#pod This is only needed when converting a metadata fragment that does not include a
1315#pod C<meta-spec> field.
1316#pod
1317#pod =cut
1318
1319
# spent 0s within CPAN::Meta::Converter::new which was called 17 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::as_string at line 602 of CPAN/Meta.pm, avg 0s/call # 7 times (0s+0s) by CPAN::Meta::_new at line 224 of CPAN/Meta.pm, avg 0s/call # once (0s+0s) by CPAN::Meta::as_struct at line 570 of CPAN/Meta.pm
sub new {
1320170s my ($class,$data,%args) = @_;
1321
1322 # create an attributes hash
1323170s170s my $self = {
# spent 0s making 17 calls to CPAN::Meta::Converter::_extract_spec_version, avg 0s/call
1324 'data' => $data,
1325 'spec' => _extract_spec_version($data, $args{default_version}),
1326 };
1327
1328 # create the object
1329170s return bless $self, $class;
1330}
1331
1332
# spent 0s within CPAN::Meta::Converter::_extract_spec_version which was called 17 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::new at line 1323, avg 0s/call
sub _extract_spec_version {
1333170s my ($data, $default) = @_;
1334170s my $spec = $data->{'meta-spec'};
1335
1336 # is meta-spec there and valid?
1337170s return( $default || "1.0" ) unless defined $spec && ref $spec eq 'HASH'; # before meta-spec?
1338
1339 # does the version key look like a valid version?
1340170s my $v = $spec->{version};
1341170s170s if ( defined $v && $v =~ /^\d+(?:\.\d+)?$/ ) {
# spent 0s making 17 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call
1342170s return $v if defined $v && grep { $v eq $_ } keys %known_specs; # known spec
1343 return $v+0 if defined $v && grep { $v == $_ } keys %known_specs; # 2.0 => 2
1344 }
1345
1346 # otherwise, use heuristics: look for 1.x vs 2.0 fields
1347 return "2" if exists $data->{prereqs};
1348 return "1.4" if exists $data->{configure_requires};
1349 return( $default || "1.2" ); # when meta-spec was first defined
1350}
1351
1352#pod =method convert
1353#pod
1354#pod my $new_struct = $cmc->convert( version => "2" );
1355#pod
1356#pod Returns a new hash reference with the metadata converted to a different form.
1357#pod C<convert> will die if any conversion/standardization still results in an
1358#pod invalid structure.
1359#pod
1360#pod Valid parameters include:
1361#pod
1362#pod =over
1363#pod
1364#pod =item *
1365#pod
1366#pod C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
1367#pod Defaults to the latest version of the CPAN Meta Spec.
1368#pod
1369#pod =back
1370#pod
1371#pod Conversion proceeds through each version in turn. For example, a version 1.2
1372#pod structure might be converted to 1.3 then 1.4 then finally to version 2. The
1373#pod conversion process attempts to clean-up simple errors and standardize data.
1374#pod For example, if C<author> is given as a scalar, it will converted to an array
1375#pod reference containing the item. (Converting a structure to its own version will
1376#pod also clean-up and standardize.)
1377#pod
1378#pod When data are cleaned and standardized, missing or invalid fields will be
1379#pod replaced with sensible defaults when possible. This may be lossy or imprecise.
1380#pod For example, some badly structured META.yml files on CPAN have prerequisite
1381#pod modules listed as both keys and values:
1382#pod
1383#pod requires => { 'Foo::Bar' => 'Bam::Baz' }
1384#pod
1385#pod These would be split and each converted to a prerequisite with a minimum
1386#pod version of zero.
1387#pod
1388#pod When some mandatory fields are missing or invalid, the conversion will attempt
1389#pod to provide a sensible default or will fill them with a value of 'unknown'. For
1390#pod example a missing or unrecognized C<license> field will result in a C<license>
1391#pod field of 'unknown'. Fields that may get an 'unknown' include:
1392#pod
1393#pod =for :list
1394#pod * abstract
1395#pod * author
1396#pod * license
1397#pod
1398#pod =cut
1399
1400
# spent 156ms (0s+156) within CPAN::Meta::Converter::convert which was called 17 times, avg 9.18ms/call: # 9 times (0s+46.8ms) by CPAN::Meta::as_string at line 603 of CPAN/Meta.pm, avg 5.20ms/call # 7 times (0s+109ms) by CPAN::Meta::_new at line 225 of CPAN/Meta.pm, avg 15.6ms/call # once (0s+0s) by CPAN::Meta::as_struct at line 571 of CPAN/Meta.pm
sub convert {
1401170s my ($self, %args) = @_;
1402170s my $args = { %args };
1403
1404170s my $new_version = $args->{version} || $HIGHEST;
1405170s my $is_fragment = $args->{is_fragment};
1406
1407170s my ($old_version) = $self->{spec};
1408170s17156ms my $converted = _dclone($self->{data});
# spent 156ms making 17 calls to CPAN::Meta::Converter::_dclone, avg 9.18ms/call
1409
1410170s if ( $old_version == $new_version ) {
141140s40s $converted = _convert( $converted, $cleanup{$old_version}, $old_version, $is_fragment );
# spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call
141240s unless ( $args->{is_fragment} ) {
141340s40s my $cmv = CPAN::Meta::Validator->new( $converted );
# spent 0s making 4 calls to CPAN::Meta::Validator::new, avg 0s/call
141440s40s unless ( $cmv->is_valid ) {
# spent 0s making 4 calls to CPAN::Meta::Validator::is_valid, avg 0s/call
1415 my $errs = join("\n", $cmv->errors);
1416 die "Failed to clean-up $old_version metadata. Errors:\n$errs\n";
1417 }
1418 }
141940s return $converted;
1420 }
1421 elsif ( $old_version > $new_version ) {
142290s90s my @vers = sort { $b <=> $a } keys %known_specs;
# spent 0s making 9 calls to CPAN::Meta::Converter::CORE:sort, avg 0s/call
142390s for my $i ( 0 .. $#vers-1 ) {
1424180s next if $vers[$i] > $old_version;
1425180s last if $vers[$i+1] < $new_version;
142690s my $spec_string = "$vers[$i+1]-from-$vers[$i]";
142790s90s $converted = _convert( $converted, $down_convert{$spec_string}, $vers[$i+1], $is_fragment );
# spent 0s making 9 calls to CPAN::Meta::Converter::_convert, avg 0s/call
142890s unless ( $args->{is_fragment} ) {
142990s90s my $cmv = CPAN::Meta::Validator->new( $converted );
# spent 0s making 9 calls to CPAN::Meta::Validator::new, avg 0s/call
143090s90s unless ( $cmv->is_valid ) {
# spent 0s making 9 calls to CPAN::Meta::Validator::is_valid, avg 0s/call
1431 my $errs = join("\n", $cmv->errors);
1432 die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
1433 }
1434 }
1435 }
143690s return $converted;
1437 }
1438 else {
143940s40s my @vers = sort { $a <=> $b } keys %known_specs;
# spent 0s making 4 calls to CPAN::Meta::Converter::CORE:sort, avg 0s/call
144040s for my $i ( 0 .. $#vers-1 ) {
1441200s next if $vers[$i] < $old_version;
144240s last if $vers[$i+1] > $new_version;
144340s my $spec_string = "$vers[$i+1]-from-$vers[$i]";
144440s40s $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1], $is_fragment );
# spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call
144540s unless ( $args->{is_fragment} ) {
144640s40s my $cmv = CPAN::Meta::Validator->new( $converted );
# spent 0s making 4 calls to CPAN::Meta::Validator::new, avg 0s/call
144740s40s unless ( $cmv->is_valid ) {
# spent 0s making 4 calls to CPAN::Meta::Validator::is_valid, avg 0s/call
1448 my $errs = join("\n", $cmv->errors);
1449 die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
1450 }
1451 }
1452 }
145340s return $converted;
1454 }
1455}
1456
1457#pod =method upgrade_fragment
1458#pod
1459#pod my $new_struct = $cmc->upgrade_fragment;
1460#pod
1461#pod Returns a new hash reference with the metadata converted to the latest version
1462#pod of the CPAN Meta Spec. No validation is done on the result -- you must
1463#pod validate after merging fragments into a complete metadata document.
1464#pod
1465#pod =cut
1466
1467sub upgrade_fragment {
1468 my ($self) = @_;
1469 my ($old_version) = $self->{spec};
1470 my %expected =
1471 map {; $_ => 1 }
1472 grep { defined }
1473 map { $fragments_generate{$old_version}{$_} }
1474 keys %{ $self->{data} };
1475 my $converted = $self->convert( version => $HIGHEST, is_fragment => 1 );
1476 for my $key ( keys %$converted ) {
1477 next if $key =~ /^x_/i || $key eq 'meta-spec';
1478 delete $converted->{$key} unless $expected{$key};
1479 }
1480 return $converted;
1481}
1482
148310s1;
1484
1485# ABSTRACT: Convert CPAN distribution metadata structures
1486
1487=pod
1488
1489=encoding UTF-8
1490
1491=head1 NAME
1492
1493CPAN::Meta::Converter - Convert CPAN distribution metadata structures
1494
1495=head1 VERSION
1496
1497version 2.143240
1498
1499=head1 SYNOPSIS
1500
1501 my $struct = decode_json_file('META.json');
1502
1503 my $cmc = CPAN::Meta::Converter->new( $struct );
1504
1505 my $new_struct = $cmc->convert( version => "2" );
1506
1507=head1 DESCRIPTION
1508
1509This module converts CPAN Meta structures from one form to another. The
1510primary use is to convert older structures to the most modern version of
1511the specification, but other transformations may be implemented in the
1512future as needed. (E.g. stripping all custom fields or stripping all
1513optional fields.)
1514
1515=head1 METHODS
1516
1517=head2 new
1518
1519 my $cmc = CPAN::Meta::Converter->new( $struct );
1520
1521The constructor should be passed a valid metadata structure but invalid
1522structures are accepted. If no meta-spec version is provided, version 1.0 will
1523be assumed.
1524
1525Optionally, you can provide a C<default_version> argument after C<$struct>:
1526
1527 my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
1528
1529This is only needed when converting a metadata fragment that does not include a
1530C<meta-spec> field.
1531
1532=head2 convert
1533
1534 my $new_struct = $cmc->convert( version => "2" );
1535
1536Returns a new hash reference with the metadata converted to a different form.
1537C<convert> will die if any conversion/standardization still results in an
1538invalid structure.
1539
1540Valid parameters include:
1541
1542=over
1543
1544=item *
1545
1546C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
1547Defaults to the latest version of the CPAN Meta Spec.
1548
1549=back
1550
1551Conversion proceeds through each version in turn. For example, a version 1.2
1552structure might be converted to 1.3 then 1.4 then finally to version 2. The
1553conversion process attempts to clean-up simple errors and standardize data.
1554For example, if C<author> is given as a scalar, it will converted to an array
1555reference containing the item. (Converting a structure to its own version will
1556also clean-up and standardize.)
1557
1558When data are cleaned and standardized, missing or invalid fields will be
1559replaced with sensible defaults when possible. This may be lossy or imprecise.
1560For example, some badly structured META.yml files on CPAN have prerequisite
1561modules listed as both keys and values:
1562
1563 requires => { 'Foo::Bar' => 'Bam::Baz' }
1564
1565These would be split and each converted to a prerequisite with a minimum
1566version of zero.
1567
1568When some mandatory fields are missing or invalid, the conversion will attempt
1569to provide a sensible default or will fill them with a value of 'unknown'. For
1570example a missing or unrecognized C<license> field will result in a C<license>
1571field of 'unknown'. Fields that may get an 'unknown' include:
1572
1573=over 4
1574
1575=item *
1576
1577abstract
1578
1579=item *
1580
1581author
1582
1583=item *
1584
1585license
1586
1587=back
1588
1589=head2 upgrade_fragment
1590
1591 my $new_struct = $cmc->upgrade_fragment;
1592
1593Returns a new hash reference with the metadata converted to the latest version
1594of the CPAN Meta Spec. No validation is done on the result -- you must
1595validate after merging fragments into a complete metadata document.
1596
1597=head1 BUGS
1598
1599Please report any bugs or feature using the CPAN Request Tracker.
1600Bugs can be submitted through the web interface at
1601L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
1602
1603When submitting a bug or request, please include a test-file or a patch to an
1604existing test-file that illustrates the bug or desired feature.
1605
1606=head1 AUTHORS
1607
1608=over 4
1609
1610=item *
1611
1612David Golden <dagolden@cpan.org>
1613
1614=item *
1615
1616Ricardo Signes <rjbs@cpan.org>
1617
1618=back
1619
1620=head1 COPYRIGHT AND LICENSE
1621
1622This software is copyright (c) 2010 by David Golden and Ricardo Signes.
1623
1624This is free software; you can redistribute it and/or modify it under
1625the same terms as the Perl 5 programming language system itself.
1626
1627=cut
1628
1629__END__
 
# spent 0s within CPAN::Meta::Converter::CORE:match which was called 110 times, avg 0s/call: # 60 times (0s+0s) by CPAN::Meta::Converter::_is_module_name at line 363, avg 0s/call # 17 times (0s+0s) by CPAN::Meta::Converter::_generated_by at line 97, avg 0s/call # 17 times (0s+0s) by CPAN::Meta::Converter::_extract_spec_version at line 1341, avg 0s/call # 8 times (0s+0s) by CPAN::Meta::Converter::_is_urlish at line 597, avg 0s/call # 5 times (0s+0s) by CPAN::Meta::Converter::_release_status_from_version at line 731, avg 0s/call # 3 times (0s+0s) by CPAN::Meta::Converter::_release_status at line 724, avg 0s/call
sub CPAN::Meta::Converter::CORE:match; # opcode
# spent 0s within CPAN::Meta::Converter::CORE:qr which was called 4 times, avg 0s/call: # 4 times (0s+0s) by CPAN::Meta::Converter::BEGIN@474 at line 484, avg 0s/call
sub CPAN::Meta::Converter::CORE:qr; # opcode
# spent 0s within CPAN::Meta::Converter::CORE:regcomp which was called 21 times, avg 0s/call: # 17 times (0s+0s) by CPAN::Meta::Converter::_generated_by at line 97, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::BEGIN@474 at line 484, avg 0s/call
sub CPAN::Meta::Converter::CORE:regcomp; # opcode
# spent 0s within CPAN::Meta::Converter::CORE:sort which was called 14 times, avg 0s/call: # 9 times (0s+0s) by CPAN::Meta::Converter::convert at line 1422, avg 0s/call # 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1439, avg 0s/call # once (0s+0s) by CPAN::Meta::BEGIN@58 at line 72
sub CPAN::Meta::Converter::CORE:sort; # opcode