Filename | C:/tmp64ng/perl/lib/CPAN/Meta/Converter.pm |
Statements | Executed 6133 statements in 15.6ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 0s | 0s | BEGIN@1.4 | CPAN::Meta::
1 | 1 | 1 | 0s | 0s | BEGIN@2.5 | CPAN::Meta::
1 | 1 | 1 | 0s | 0s | BEGIN@3.6 | CPAN::Meta::
1 | 1 | 1 | 0s | 0s | BEGIN@25 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@26 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@27 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@35 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@474 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@489 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@52 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@53 | CPAN::Meta::Converter::
110 | 6 | 1 | 0s | 0s | CORE:match (opcode) | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | CORE:qr (opcode) | CPAN::Meta::Converter::
21 | 2 | 1 | 0s | 0s | CORE:regcomp (opcode) | CPAN::Meta::Converter::
14 | 3 | 1 | 0s | 0s | CORE:sort (opcode) | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | __ANON__[:43] | CPAN::Meta::Converter::
36 | 1 | 1 | 0s | 0s | __ANON__[:490] | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | __ANON__[:54] | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | __ANON__[:624] | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | __ANON__[:632] | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | __ANON__[:633] | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | __ANON__[:670] | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | __ANON__[:671] | CPAN::Meta::Converter::
3 | 1 | 1 | 0s | 0s | __ANON__[:709] | CPAN::Meta::Converter::
3 | 1 | 1 | 0s | 0s | __ANON__[:711] | CPAN::Meta::Converter::
3 | 1 | 1 | 0s | 0s | __ANON__[:712] | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _author_list | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _bad_version_hook | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _change_meta_spec | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _clean_version | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _cleanup_optional_features_2 | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _cleanup_prereqs | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _cleanup_resources_2 | CPAN::Meta::Converter::
53 | 9 | 1 | 0s | 0s | _convert (recurses: max depth 2, inclusive time 0s) | CPAN::Meta::Converter::
54 | 3 | 2 | 0s | 218ms | _dclone | CPAN::Meta::Converter::
9 | 1 | 1 | 0s | 0s | _downgrade_license | CPAN::Meta::Converter::
9 | 1 | 1 | 0s | 0s | _downgrade_optional_features | CPAN::Meta::Converter::
9 | 1 | 1 | 0s | 0s | _downgrade_resources | CPAN::Meta::Converter::
54 | 3 | 1 | 0s | 0s | _extract_prereqs | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _extract_spec_version | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _feature_2 | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _generated_by | CPAN::Meta::Converter::
9 | 1 | 1 | 0s | 0s | _get_build_requires | CPAN::Meta::Converter::
60 | 2 | 1 | 0s | 0s | _is_module_name | CPAN::Meta::Converter::
15 | 1 | 1 | 0s | 0s | _is_urlish | CPAN::Meta::Converter::
68 | 1 | 1 | 0s | 0s | _keep | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _keep_or_one | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _keep_or_unknown | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _keep_or_zero | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _license_1 | CPAN::Meta::Converter::
8 | 1 | 1 | 0s | 0s | _license_2 | CPAN::Meta::Converter::
85 | 2 | 1 | 0s | 0s | _listify | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _no_index_1_2 | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _no_index_directory | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _no_prefix_ucfirst_custom | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _optional_features_1_4 | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _optional_features_as_map | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _prefix_custom | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _prereqs_from_1 | CPAN::Meta::Converter::
10 | 1 | 1 | 0s | 0s | _prereqs_rel | CPAN::Meta::Converter::
17 | 1 | 1 | 0s | 0s | _provides | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _release_status | CPAN::Meta::Converter::
5 | 2 | 1 | 0s | 0s | _release_status_from_version | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _repo_type | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _resources_1_2 | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _resources_1_3 | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | _ucfirst_custom | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _upgrade_optional_features | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _upgrade_resources_2 | CPAN::Meta::Converter::
4 | 1 | 1 | 0s | 0s | _url_list | CPAN::Meta::Converter::
15 | 1 | 1 | 0s | 0s | _url_or_drop | CPAN::Meta::Converter::
90 | 4 | 1 | 0s | 0s | _version_map | CPAN::Meta::Converter::
17 | 3 | 1 | 0s | 156ms | convert | CPAN::Meta::Converter::
17 | 3 | 1 | 0s | 0s | new | CPAN::Meta::Converter::
0 | 0 | 0 | 0s | 0s | upgrade_fragment | CPAN::Meta::Converter::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | 2 | 0s | 1 | 0s | # spent 0s within CPAN::Meta::BEGIN@1.4 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 1 # spent 0s making 1 call to CPAN::Meta::BEGIN@1.4 |
2 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::BEGIN@2.5 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 2 # spent 0s making 1 call to CPAN::Meta::BEGIN@2.5
# spent 0s making 1 call to strict::import |
3 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::BEGIN@3.6 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 3 # spent 0s making 1 call to CPAN::Meta::BEGIN@3.6
# spent 0s making 1 call to warnings::import |
4 | package CPAN::Meta::Converter; | ||||
5 | # VERSION | ||||
6 | 1 | 0s | $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 | |||||
25 | 2 | 0s | 1 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@25 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 25 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@25 |
26 | 2 | 0s | 1 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@26 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 26 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@26 |
27 | 3 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@27 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 27 # 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 | ||||
36 | 1 | 0s | eval "use version ()"; ## no critic # spent 0s executing statements in string eval # includes 0s spent executing 1 call to 1 sub defined therein. | ||
37 | 1 | 0s | if ( my $err = $@ ) { | ||
38 | eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic | ||||
39 | } | ||||
40 | 1 | 0s | 1 | 0s | } # 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 | ||||
43 | 1 | 0s | 1 | 0s | *_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 | ||||
46 | 54 | 0s | 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. | ||||
52 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@52 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 52 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@52
# spent 0s making 1 call to warnings::unimport |
53 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@53 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 53 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@53
# spent 0s making 1 call to warnings::unimport |
54 | 54 | 0s | local *UNIVERSAL::TO_JSON = sub { "$_[0]" }; | ||
55 | |||||
56 | 54 | 0s | 270 | 31.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; | ||||
60 | 54 | 0s | 108 | 187ms | $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 | |||||
63 | 1 | 0s | my %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 | |||||
72 | 1 | 0s | 1 | 0s | my @spec_list = sort { $a <=> $b } keys %known_specs; # spent 0s making 1 call to CPAN::Meta::Converter::CORE:sort |
73 | 1 | 0s | my ($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 | |||||
84 | 68 | 0s | # 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 | ||
85 | |||||
86 | 17 | 0s | # 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 | ||
87 | |||||
88 | sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 } | ||||
89 | |||||
90 | 17 | 0s | # 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 | ||
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 | ||||
93 | 17 | 0s | my $gen = shift; | ||
94 | 17 | 0s | 17 | 0s | my $sig = __PACKAGE__ . " version " . (__PACKAGE__->VERSION || "<dev>"); # spent 0s making 17 calls to version::vxs::_VERSION, avg 0s/call |
95 | |||||
96 | 17 | 0s | return $sig unless defined $gen and length $gen; | ||
97 | 17 | 0s | 34 | 0s | 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 |
98 | 6 | 0s | return "$gen, $sig"; | ||
99 | } | ||||
100 | |||||
101 | 85 | 0s | sub _listify { ! defined $_[0] ? undef : ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] } | ||
102 | |||||
103 | sub _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 | |||||
111 | sub _ucfirst_custom { | ||||
112 | my $key = shift; | ||||
113 | $key = ucfirst $key unless $key =~ /[A-Z]/; | ||||
114 | return $key; | ||||
115 | } | ||||
116 | |||||
117 | sub _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 | ||||
124 | 17 | 0s | my ($element, undef, undef, $version) = @_; | ||
125 | return { | ||||
126 | 17 | 0s | version => $version, | ||
127 | url => $known_specs{$version}, | ||||
128 | }; | ||||
129 | } | ||||
130 | |||||
131 | 1 | 0s | my @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 | |||||
145 | 1 | 0s | my %is_open_source = map {; $_ => 1 } @open_source; | ||
146 | |||||
147 | 1 | 0s | my @valid_licenses_1 = ( | ||
148 | @open_source, | ||||
149 | 'unrestricted', | ||||
150 | 'restrictive', | ||||
151 | 'unknown', | ||||
152 | ); | ||||
153 | |||||
154 | my %license_map_1 = ( | ||||
155 | 1 | 0s | ( map { $_ => $_ } @valid_licenses_1 ), | ||
156 | artistic2 => 'artistic_2', | ||||
157 | ); | ||||
158 | |||||
159 | sub _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 | |||||
170 | 1 | 0s | my @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. | ||||
203 | my %license_map_2 = ( | ||||
204 | 1 | 0s | (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 | ||||
216 | 8 | 0s | my ($element) = @_; | ||
217 | 8 | 0s | return [ 'unknown' ] unless defined $element; | ||
218 | 8 | 0s | $element = [ $element ] unless ref $element eq 'ARRAY'; | ||
219 | 8 | 0s | my @new_list; | ||
220 | 8 | 0s | for my $lic ( @$element ) { | ||
221 | 8 | 0s | next unless defined $lic; | ||
222 | 8 | 0s | if ( my $new = $license_map_2{lc $lic} ) { | ||
223 | push @new_list, $new; | ||||
224 | } | ||||
225 | } | ||||
226 | 8 | 0s | return @new_list ? \@new_list : [ 'unknown' ]; | ||
227 | } | ||||
228 | |||||
229 | 1 | 0s | my %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 | ||||
260 | 9 | 0s | my ($element) = @_; | ||
261 | 9 | 0s | if ( ! defined $element ) { | ||
262 | return "unknown"; | ||||
263 | } | ||||
264 | elsif( ref $element eq 'ARRAY' ) { | ||||
265 | 9 | 0s | 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 | |||||
283 | 1 | 0s | my $no_index_spec_1_2 = { | ||
284 | 'file' => \&_listify, | ||||
285 | 'dir' => \&_listify, | ||||
286 | 'package' => \&_listify, | ||||
287 | 'namespace' => \&_listify, | ||||
288 | }; | ||||
289 | |||||
290 | 1 | 0s | my $no_index_spec_1_3 = { | ||
291 | 'file' => \&_listify, | ||||
292 | 'directory' => \&_listify, | ||||
293 | 'package' => \&_listify, | ||||
294 | 'namespace' => \&_listify, | ||||
295 | }; | ||||
296 | |||||
297 | 1 | 0s | my $no_index_spec_2 = { | ||
298 | 'file' => \&_listify, | ||||
299 | 'directory' => \&_listify, | ||||
300 | 'package' => \&_listify, | ||||
301 | 'namespace' => \&_listify, | ||||
302 | ':custom' => \&_prefix_custom, | ||||
303 | }; | ||||
304 | |||||
305 | sub _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 | ||||
332 | 17 | 0s | my ($element, $key, $meta, $version) = @_; | ||
333 | 17 | 0s | return unless $element; | ||
334 | |||||
335 | # cleanup wrong format | ||||
336 | 17 | 0s | 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 | |||||
345 | 17 | 0s | if ( exists $element->{dir} ) { | ||
346 | $element->{directory} = delete $element->{dir}; | ||||
347 | } | ||||
348 | # common mistake: files -> file | ||||
349 | 17 | 0s | if ( exists $element->{files} ) { | ||
350 | $element->{file} = delete $element->{file}; | ||||
351 | } | ||||
352 | # common mistake: modules -> module | ||||
353 | 17 | 0s | if ( exists $element->{modules} ) { | ||
354 | $element->{module} = delete $element->{module}; | ||||
355 | } | ||||
356 | 17 | 0s | my $spec = $version == 2 ? $no_index_spec_2 : $no_index_spec_1_3; | ||
357 | 17 | 0s | 17 | 0s | 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 | sub _is_module_name { | ||||
361 | 60 | 0s | my $mod = shift; | ||
362 | 60 | 0s | return unless defined $mod && length $mod; | ||
363 | 60 | 0s | 60 | 0s | 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 | |||||
366 | sub _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 | |||||
388 | sub _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 | ||||
396 | 90 | 0s | my ($element) = @_; | ||
397 | 90 | 0s | return unless defined $element; | ||
398 | 45 | 0s | 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 | ||||
401 | 45 | 0s | 45 | 0s | 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 | ); | ||||
404 | 45 | 0s | while ( my ($k,$v) = each %$element ) { | ||
405 | 30 | 0s | 30 | 0s | next unless _is_module_name($k); # spent 0s making 30 calls to CPAN::Meta::Converter::_is_module_name, avg 0s/call |
406 | 30 | 0s | 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 | ||||
411 | 30 | 0s | 30 | 0s | 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 | } | ||||
415 | 30 | 0s | 30 | 0s | $new_map->add_string_requirement($k => $v); # spent 0s making 30 calls to CPAN::Meta::Requirements::add_string_requirement, avg 0s/call |
416 | } | ||||
417 | 45 | 0s | 45 | 0s | 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 | ||||
430 | 4 | 0s | my (undef, undef, $meta) = @_; | ||
431 | 4 | 0s | my $prereqs = {}; | ||
432 | 4 | 0s | for my $phase ( qw/build configure/ ) { | ||
433 | 8 | 0s | my $key = "${phase}_requires"; | ||
434 | 8 | 0s | 8 | 0s | $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 | } | ||||
437 | 4 | 0s | for my $rel ( qw/requires recommends conflicts/ ) { | ||
438 | 12 | 0s | 4 | 0s | $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 | } | ||||
441 | 4 | 0s | return $prereqs; | ||
442 | } | ||||
443 | |||||
444 | 1 | 0s | my $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 | |||||
453 | 1 | 0s | my $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 | ||||
462 | 4 | 0s | my ($prereqs, $key, $meta, $to_version) = @_; | ||
463 | 4 | 0s | return unless $prereqs && ref $prereqs eq 'HASH'; | ||
464 | 2 | 0s | 2 | 0s | 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 | ||||
468 | 10 | 0s | my ($relation, $key, $meta, $to_version) = @_; | ||
469 | 10 | 0s | return unless $relation && ref $relation eq 'HASH'; | ||
470 | 6 | 0s | 6 | 0s | 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 | ||||
475 | 1 | 0s | my @old_prereqs = qw( | ||
476 | requires | ||||
477 | configure_requires | ||||
478 | recommends | ||||
479 | conflicts | ||||
480 | ); | ||||
481 | |||||
482 | 1 | 0s | for ( @old_prereqs ) { | ||
483 | 4 | 0s | my $sub = "_get_$_"; | ||
484 | 4 | 0s | 8 | 0s | 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 |
485 | 4 | 0s | if ( ! defined $type ) { | ||
486 | 3 | 0s | $type = $phase; | ||
487 | 3 | 0s | $phase = 'runtime'; | ||
488 | } | ||||
489 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@489 which was called:
# once (0s+0s) by CPAN::Meta::BEGIN@58 at line 489 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@489
# spent 0s making 1 call to strict::unimport |
490 | 40 | 0s | 36 | 0s | # 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 # spent 0s making 36 calls to CPAN::Meta::Converter::_extract_prereqs, avg 0s/call |
491 | } | ||||
492 | 1 | 15.6ms | 1 | 0s | } # 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 | ||||
495 | 9 | 0s | my ($data, $key, $meta) = @_; | ||
496 | |||||
497 | 9 | 0s | 9 | 0s | my $test_h = _extract_prereqs($_[2]->{prereqs}, qw(test requires)) || {}; # spent 0s making 9 calls to CPAN::Meta::Converter::_extract_prereqs, avg 0s/call |
498 | 9 | 0s | 9 | 0s | 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 | |||||
500 | 9 | 0s | 9 | 0s | 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 |
501 | 9 | 0s | 9 | 0s | 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 | |||||
503 | 9 | 0s | 18 | 0s | $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 | ||||
507 | 54 | 0s | my ($prereqs, $phase, $type) = @_; | ||
508 | 54 | 0s | return unless ref $prereqs eq 'HASH'; | ||
509 | 54 | 0s | 54 | 0s | 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 | ||||
513 | 9 | 0s | my (undef, undef, $meta) = @_; | ||
514 | 9 | 0s | 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 | ||||
534 | 4 | 0s | my (undef, undef, $meta) = @_; | ||
535 | 4 | 0s | 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 | |||||
548 | 1 | 0s | my $optional_features_2_spec = { | ||
549 | description => \&_keep, | ||||
550 | prereqs => \&_cleanup_prereqs, | ||||
551 | ':custom' => \&_prefix_custom, | ||||
552 | }; | ||||
553 | |||||
554 | sub _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 | ||||
561 | 4 | 0s | my ($element, $key, $meta, $to_version) = @_; | ||
562 | 4 | 0s | 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 | |||||
571 | sub _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 | |||||
583 | sub _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 | |||||
597 | 15 | 0s | 8 | 0s | # 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 # 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 | ||||
600 | 15 | 0s | my ($element) = @_; | ||
601 | 15 | 0s | 15 | 0s | return $element if _is_urlish($element); # spent 0s making 15 calls to CPAN::Meta::Converter::_is_urlish, avg 0s/call |
602 | 7 | 0s | 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 | ||||
606 | 4 | 0s | my ($element) = @_; | ||
607 | 4 | 0s | 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 | ||||
615 | 17 | 0s | my ($element) = @_; | ||
616 | 17 | 0s | return [ 'unknown' ] unless $element; | ||
617 | 17 | 0s | 17 | 0s | $element = _listify( $element ); # spent 0s making 17 calls to CPAN::Meta::Converter::_listify, avg 0s/call |
618 | 17 | 0s | $element = [ map { defined $_ && length $_ ? $_ : 'unknown' } @$element ]; | ||
619 | 17 | 0s | return [ 'unknown' ] unless @$element; | ||
620 | 13 | 0s | return $element; | ||
621 | } | ||||
622 | |||||
623 | my $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 }, | ||||
634 | 1 | 0s | ':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 | ||||
638 | 4 | 0s | my (undef, undef, $meta, $version) = @_; | ||
639 | 4 | 0s | return unless exists $meta->{resources}; | ||
640 | return _convert($meta->{resources}, $resource2_upgrade); | ||||
641 | } | ||||
642 | |||||
643 | 1 | 0s | my $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 | ||||
650 | 4 | 0s | my ($element, $key, $meta, $to_version) = @_; | ||
651 | 4 | 0s | 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 | |||||
660 | 1 | 0s | my $repository2_spec = { | ||
661 | web => \&_url_or_drop, | ||||
662 | url => \&_url_or_drop, | ||||
663 | type => \&_repo_type, | ||||
664 | ':custom' => \&_prefix_custom, | ||||
665 | }; | ||||
666 | |||||
667 | my $resources2_cleanup = { | ||||
668 | license => \&_url_list, | ||||
669 | homepage => \&_url_or_drop, | ||||
670 | 4 | 0s | # 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 | ||
671 | 8 | 0s | 4 | 0s | # 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 # spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call, recursion: max depth 2, sum of overlapping time 0s |
672 | 1 | 0s | ':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 | ||||
676 | 4 | 0s | my ($resources, $key, $meta, $to_version) = @_; | ||
677 | 4 | 0s | return unless $resources && ref $resources eq 'HASH'; | ||
678 | 4 | 0s | 4 | 0s | 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 | |||||
681 | 1 | 0s | my $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 | |||||
689 | sub _resources_1_3 { | ||||
690 | my (undef, undef, $meta, $version) = @_; | ||||
691 | return unless exists $meta->{resources}; | ||||
692 | return _convert($meta->{resources}, $resource1_spec); | ||||
693 | } | ||||
694 | |||||
695 | 1 | 0s | *_resources_1_4 = *_resources_1_3; | ||
696 | |||||
697 | sub _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 | |||||
708 | my $resource_downgrade_spec = { | ||||
709 | 3 | 0s | # 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 | ||
710 | homepage => \&_url_or_drop, | ||||
711 | 3 | 0s | # 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 | ||
712 | 3 | 0s | # 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 | ||
713 | 1 | 0s | ':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 | ||||
717 | 9 | 0s | my (undef, undef, $meta, $version) = @_; | ||
718 | 9 | 0s | return unless exists $meta->{resources}; | ||
719 | 3 | 0s | 3 | 0s | 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 | ||||
723 | 4 | 0s | my ($element, undef, $meta) = @_; | ||
724 | 4 | 0s | 3 | 0s | 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 |
725 | 1 | 0s | 1 | 0s | return _release_status_from_version(undef, undef, $meta); # spent 0s making 1 call to CPAN::Meta::Converter::_release_status_from_version |
726 | } | ||||
727 | |||||
728 | sub _release_status_from_version { | ||||
729 | 5 | 0s | my (undef, undef, $meta) = @_; | ||
730 | 5 | 0s | my $version = $meta->{version} || ''; | ||
731 | 5 | 0s | 5 | 0s | return ( $version =~ /_/ ) ? 'testing' : 'stable'; # spent 0s making 5 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call |
732 | } | ||||
733 | |||||
734 | 1 | 0s | my $provides_spec = { | ||
735 | file => \&_keep, | ||||
736 | version => \&_keep, | ||||
737 | }; | ||||
738 | |||||
739 | 1 | 0s | my $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 | ||||
746 | 17 | 0s | my ($element, $key, $meta, $to_version) = @_; | ||
747 | 17 | 0s | 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 | ||||
759 | 53 | 0s | my ($data, $spec, $to_version, $is_fragment) = @_; | ||
760 | |||||
761 | 53 | 0s | my $new_data = {}; | ||
762 | 53 | 0s | for my $key ( keys %$spec ) { | ||
763 | 502 | 0s | next if $key eq ':custom' || $key eq ':drop'; | ||
764 | 441 | 0s | next unless my $fcn = $spec->{$key}; | ||
765 | 441 | 0s | if ( $is_fragment && $key eq 'generated_by' ) { | ||
766 | $fcn = \&_keep; | ||||
767 | } | ||||
768 | 441 | 0s | die "spec for '$key' is not a coderef" | ||
769 | unless ref $fcn && ref $fcn eq 'CODE'; | ||||
770 | 441 | 0s | 441 | 0s | 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 |
771 | 441 | 0s | $new_data->{$key} = $new_value if defined $new_value; | ||
772 | } | ||||
773 | |||||
774 | 53 | 0s | my $drop_list = $spec->{':drop'}; | ||
775 | 53 | 0s | my $customizer = $spec->{':custom'} || \&_keep; | ||
776 | |||||
777 | 53 | 0s | for my $key ( keys %$data ) { | ||
778 | 251 | 0s | next if $drop_list && grep { $key eq $_ } @$drop_list; | ||
779 | 216 | 0s | next if exists $spec->{$key}; # we handled it | ||
780 | $new_data->{ $customizer->($key) } = $data->{$key}; | ||||
781 | } | ||||
782 | |||||
783 | 53 | 0s | 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 | ||||
792 | 1 | 0s | my %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 | |||||
952 | 1 | 0s | my %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 | |||||
1091 | 1 | 0s | my %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 | ||||
1255 | 1 | 0s | my %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 | ||||
1296 | 1 | 0s | $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 | ||||
1320 | 17 | 0s | my ($class,$data,%args) = @_; | ||
1321 | |||||
1322 | # create an attributes hash | ||||
1323 | 17 | 0s | 17 | 0s | 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 | ||||
1329 | 17 | 0s | 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 | ||||
1333 | 17 | 0s | my ($data, $default) = @_; | ||
1334 | 17 | 0s | my $spec = $data->{'meta-spec'}; | ||
1335 | |||||
1336 | # is meta-spec there and valid? | ||||
1337 | 17 | 0s | 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? | ||||
1340 | 17 | 0s | my $v = $spec->{version}; | ||
1341 | 17 | 0s | 17 | 0s | if ( defined $v && $v =~ /^\d+(?:\.\d+)?$/ ) { # spent 0s making 17 calls to CPAN::Meta::Converter::CORE:match, avg 0s/call |
1342 | 17 | 0s | 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 | ||||
1401 | 17 | 0s | my ($self, %args) = @_; | ||
1402 | 17 | 0s | my $args = { %args }; | ||
1403 | |||||
1404 | 17 | 0s | my $new_version = $args->{version} || $HIGHEST; | ||
1405 | 17 | 0s | my $is_fragment = $args->{is_fragment}; | ||
1406 | |||||
1407 | 17 | 0s | my ($old_version) = $self->{spec}; | ||
1408 | 17 | 0s | 17 | 156ms | my $converted = _dclone($self->{data}); # spent 156ms making 17 calls to CPAN::Meta::Converter::_dclone, avg 9.18ms/call |
1409 | |||||
1410 | 17 | 0s | if ( $old_version == $new_version ) { | ||
1411 | 4 | 0s | 4 | 0s | $converted = _convert( $converted, $cleanup{$old_version}, $old_version, $is_fragment ); # spent 0s making 4 calls to CPAN::Meta::Converter::_convert, avg 0s/call |
1412 | 4 | 0s | unless ( $args->{is_fragment} ) { | ||
1413 | 4 | 0s | 4 | 0s | my $cmv = CPAN::Meta::Validator->new( $converted ); # spent 0s making 4 calls to CPAN::Meta::Validator::new, avg 0s/call |
1414 | 4 | 0s | 4 | 0s | 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 | } | ||||
1419 | 4 | 0s | return $converted; | ||
1420 | } | ||||
1421 | elsif ( $old_version > $new_version ) { | ||||
1422 | 9 | 0s | 9 | 0s | my @vers = sort { $b <=> $a } keys %known_specs; # spent 0s making 9 calls to CPAN::Meta::Converter::CORE:sort, avg 0s/call |
1423 | 9 | 0s | for my $i ( 0 .. $#vers-1 ) { | ||
1424 | 18 | 0s | next if $vers[$i] > $old_version; | ||
1425 | 18 | 0s | last if $vers[$i+1] < $new_version; | ||
1426 | 9 | 0s | my $spec_string = "$vers[$i+1]-from-$vers[$i]"; | ||
1427 | 9 | 0s | 9 | 0s | $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 |
1428 | 9 | 0s | unless ( $args->{is_fragment} ) { | ||
1429 | 9 | 0s | 9 | 0s | my $cmv = CPAN::Meta::Validator->new( $converted ); # spent 0s making 9 calls to CPAN::Meta::Validator::new, avg 0s/call |
1430 | 9 | 0s | 9 | 0s | 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 | } | ||||
1436 | 9 | 0s | return $converted; | ||
1437 | } | ||||
1438 | else { | ||||
1439 | 4 | 0s | 4 | 0s | my @vers = sort { $a <=> $b } keys %known_specs; # spent 0s making 4 calls to CPAN::Meta::Converter::CORE:sort, avg 0s/call |
1440 | 4 | 0s | for my $i ( 0 .. $#vers-1 ) { | ||
1441 | 20 | 0s | next if $vers[$i] < $old_version; | ||
1442 | 4 | 0s | last if $vers[$i+1] > $new_version; | ||
1443 | 4 | 0s | my $spec_string = "$vers[$i+1]-from-$vers[$i]"; | ||
1444 | 4 | 0s | 4 | 0s | $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 |
1445 | 4 | 0s | unless ( $args->{is_fragment} ) { | ||
1446 | 4 | 0s | 4 | 0s | my $cmv = CPAN::Meta::Validator->new( $converted ); # spent 0s making 4 calls to CPAN::Meta::Validator::new, avg 0s/call |
1447 | 4 | 0s | 4 | 0s | 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 | } | ||||
1453 | 4 | 0s | 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 | |||||
1467 | sub 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 | |||||
1483 | 1 | 0s | 1; | ||
1484 | |||||
1485 | # ABSTRACT: Convert CPAN distribution metadata structures | ||||
1486 | |||||
1487 | =pod | ||||
1488 | |||||
1489 | =encoding UTF-8 | ||||
1490 | |||||
1491 | =head1 NAME | ||||
1492 | |||||
1493 | CPAN::Meta::Converter - Convert CPAN distribution metadata structures | ||||
1494 | |||||
1495 | =head1 VERSION | ||||
1496 | |||||
1497 | version 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 | |||||
1509 | This module converts CPAN Meta structures from one form to another. The | ||||
1510 | primary use is to convert older structures to the most modern version of | ||||
1511 | the specification, but other transformations may be implemented in the | ||||
1512 | future as needed. (E.g. stripping all custom fields or stripping all | ||||
1513 | optional fields.) | ||||
1514 | |||||
1515 | =head1 METHODS | ||||
1516 | |||||
1517 | =head2 new | ||||
1518 | |||||
1519 | my $cmc = CPAN::Meta::Converter->new( $struct ); | ||||
1520 | |||||
1521 | The constructor should be passed a valid metadata structure but invalid | ||||
1522 | structures are accepted. If no meta-spec version is provided, version 1.0 will | ||||
1523 | be assumed. | ||||
1524 | |||||
1525 | Optionally, 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 | |||||
1529 | This is only needed when converting a metadata fragment that does not include a | ||||
1530 | C<meta-spec> field. | ||||
1531 | |||||
1532 | =head2 convert | ||||
1533 | |||||
1534 | my $new_struct = $cmc->convert( version => "2" ); | ||||
1535 | |||||
1536 | Returns a new hash reference with the metadata converted to a different form. | ||||
1537 | C<convert> will die if any conversion/standardization still results in an | ||||
1538 | invalid structure. | ||||
1539 | |||||
1540 | Valid parameters include: | ||||
1541 | |||||
1542 | =over | ||||
1543 | |||||
1544 | =item * | ||||
1545 | |||||
1546 | C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2"). | ||||
1547 | Defaults to the latest version of the CPAN Meta Spec. | ||||
1548 | |||||
1549 | =back | ||||
1550 | |||||
1551 | Conversion proceeds through each version in turn. For example, a version 1.2 | ||||
1552 | structure might be converted to 1.3 then 1.4 then finally to version 2. The | ||||
1553 | conversion process attempts to clean-up simple errors and standardize data. | ||||
1554 | For example, if C<author> is given as a scalar, it will converted to an array | ||||
1555 | reference containing the item. (Converting a structure to its own version will | ||||
1556 | also clean-up and standardize.) | ||||
1557 | |||||
1558 | When data are cleaned and standardized, missing or invalid fields will be | ||||
1559 | replaced with sensible defaults when possible. This may be lossy or imprecise. | ||||
1560 | For example, some badly structured META.yml files on CPAN have prerequisite | ||||
1561 | modules listed as both keys and values: | ||||
1562 | |||||
1563 | requires => { 'Foo::Bar' => 'Bam::Baz' } | ||||
1564 | |||||
1565 | These would be split and each converted to a prerequisite with a minimum | ||||
1566 | version of zero. | ||||
1567 | |||||
1568 | When some mandatory fields are missing or invalid, the conversion will attempt | ||||
1569 | to provide a sensible default or will fill them with a value of 'unknown'. For | ||||
1570 | example a missing or unrecognized C<license> field will result in a C<license> | ||||
1571 | field of 'unknown'. Fields that may get an 'unknown' include: | ||||
1572 | |||||
1573 | =over 4 | ||||
1574 | |||||
1575 | =item * | ||||
1576 | |||||
1577 | abstract | ||||
1578 | |||||
1579 | =item * | ||||
1580 | |||||
1581 | author | ||||
1582 | |||||
1583 | =item * | ||||
1584 | |||||
1585 | license | ||||
1586 | |||||
1587 | =back | ||||
1588 | |||||
1589 | =head2 upgrade_fragment | ||||
1590 | |||||
1591 | my $new_struct = $cmc->upgrade_fragment; | ||||
1592 | |||||
1593 | Returns a new hash reference with the metadata converted to the latest version | ||||
1594 | of the CPAN Meta Spec. No validation is done on the result -- you must | ||||
1595 | validate after merging fragments into a complete metadata document. | ||||
1596 | |||||
1597 | =head1 BUGS | ||||
1598 | |||||
1599 | Please report any bugs or feature using the CPAN Request Tracker. | ||||
1600 | Bugs can be submitted through the web interface at | ||||
1601 | L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta> | ||||
1602 | |||||
1603 | When submitting a bug or request, please include a test-file or a patch to an | ||||
1604 | existing test-file that illustrates the bug or desired feature. | ||||
1605 | |||||
1606 | =head1 AUTHORS | ||||
1607 | |||||
1608 | =over 4 | ||||
1609 | |||||
1610 | =item * | ||||
1611 | |||||
1612 | David Golden <dagolden@cpan.org> | ||||
1613 | |||||
1614 | =item * | ||||
1615 | |||||
1616 | Ricardo Signes <rjbs@cpan.org> | ||||
1617 | |||||
1618 | =back | ||||
1619 | |||||
1620 | =head1 COPYRIGHT AND LICENSE | ||||
1621 | |||||
1622 | This software is copyright (c) 2010 by David Golden and Ricardo Signes. | ||||
1623 | |||||
1624 | This is free software; you can redistribute it and/or modify it under | ||||
1625 | the 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 | |||||
# 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:regcomp; # opcode | |||||
sub CPAN::Meta::Converter::CORE:sort; # opcode |