Filename | C:/tmp64ng/perl/lib/CPAN/Meta/Validator.pm |
Statements | Executed 6344 statements in 0s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 0s | 0s | BEGIN@1 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@2 | CPAN::Meta::Converter::
1 | 1 | 1 | 0s | 0s | BEGIN@3 | CPAN::Meta::Converter::
287 | 9 | 1 | 0s | 0s | CORE:match (opcode) | CPAN::Meta::Validator::
3 | 3 | 1 | 0s | 0s | _error | CPAN::Meta::Validator::
25 | 1 | 1 | 0s | 0s | _uri_split | CPAN::Meta::Validator::
1 | 1 | 1 | 0s | 0s | anything | CPAN::Meta::Validator::
23 | 1 | 1 | 0s | 0s | boolean | CPAN::Meta::Validator::
56 | 1 | 1 | 0s | 0s | check_list | CPAN::Meta::Validator::
179 | 3 | 1 | 0s | 0s | check_map (recurses: max depth 3, inclusive time 0s) | CPAN::Meta::Validator::
0 | 0 | 0 | 0s | 0s | custom_1 | CPAN::Meta::Validator::
1 | 1 | 1 | 0s | 0s | custom_2 | CPAN::Meta::Validator::
24 | 2 | 2 | 0s | 0s | errors | CPAN::Meta::Validator::
42 | 1 | 1 | 0s | 0s | exversion | CPAN::Meta::Validator::
0 | 0 | 0 | 0s | 0s | file | CPAN::Meta::Validator::
0 | 0 | 0 | 0s | 0s | header | CPAN::Meta::Validator::
0 | 0 | 0 | 0s | 0s | identifier | CPAN::Meta::Validator::
23 | 4 | 2 | 0s | 0s | is_valid | CPAN::Meta::Validator::
22 | 2 | 1 | 0s | 0s | license | CPAN::Meta::Validator::
42 | 1 | 1 | 0s | 0s | module | CPAN::Meta::Validator::
29 | 5 | 2 | 0s | 0s | new | CPAN::Meta::Validator::
24 | 1 | 1 | 0s | 0s | phase | CPAN::Meta::Validator::
24 | 1 | 1 | 0s | 0s | relation | CPAN::Meta::Validator::
9 | 1 | 1 | 0s | 0s | release_status | CPAN::Meta::Validator::
144 | 2 | 1 | 0s | 0s | string | CPAN::Meta::Validator::
0 | 0 | 0 | 0s | 0s | string_or_undef | CPAN::Meta::Validator::
25 | 1 | 1 | 0s | 0s | url | CPAN::Meta::Validator::
13 | 1 | 1 | 0s | 0s | urlspec | CPAN::Meta::Validator::
94 | 3 | 2 | 0s | 0s | version | CPAN::Meta::Validator::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | 2 | 0s | 1 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@1 which was called:
# once (0s+0s) by CPAN::Meta::Converter::BEGIN@25 at line 1 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@1 |
2 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@2 which was called:
# once (0s+0s) by CPAN::Meta::Converter::BEGIN@25 at line 2 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@2
# spent 0s making 1 call to strict::import |
3 | 2 | 0s | 2 | 0s | # spent 0s within CPAN::Meta::Converter::BEGIN@3 which was called:
# once (0s+0s) by CPAN::Meta::Converter::BEGIN@25 at line 3 # spent 0s making 1 call to CPAN::Meta::Converter::BEGIN@3
# spent 0s making 1 call to warnings::import |
4 | package CPAN::Meta::Validator; | ||||
5 | # VERSION | ||||
6 | 1 | 0s | $CPAN::Meta::Validator::VERSION = '2.143240'; | ||
7 | #pod =head1 SYNOPSIS | ||||
8 | #pod | ||||
9 | #pod my $struct = decode_json_file('META.json'); | ||||
10 | #pod | ||||
11 | #pod my $cmv = CPAN::Meta::Validator->new( $struct ); | ||||
12 | #pod | ||||
13 | #pod unless ( $cmv->is_valid ) { | ||||
14 | #pod my $msg = "Invalid META structure. Errors found:\n"; | ||||
15 | #pod $msg .= join( "\n", $cmv->errors ); | ||||
16 | #pod die $msg; | ||||
17 | #pod } | ||||
18 | #pod | ||||
19 | #pod =head1 DESCRIPTION | ||||
20 | #pod | ||||
21 | #pod This module validates a CPAN Meta structure against the version of the | ||||
22 | #pod the specification claimed in the C<meta-spec> field of the structure. | ||||
23 | #pod | ||||
24 | #pod =cut | ||||
25 | |||||
26 | #--------------------------------------------------------------------------# | ||||
27 | # This code copied and adapted from Test::CPAN::Meta | ||||
28 | # by Barbie, <barbie@cpan.org> for Miss Barbell Productions, | ||||
29 | # L<http://www.missbarbell.co.uk> | ||||
30 | #--------------------------------------------------------------------------# | ||||
31 | |||||
32 | #--------------------------------------------------------------------------# | ||||
33 | # Specification Definitions | ||||
34 | #--------------------------------------------------------------------------# | ||||
35 | |||||
36 | 1 | 0s | my %known_specs = ( | ||
37 | '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html', | ||||
38 | '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html', | ||||
39 | '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html', | ||||
40 | '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html', | ||||
41 | '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html' | ||||
42 | ); | ||||
43 | 1 | 0s | my %known_urls = map {$known_specs{$_} => $_} keys %known_specs; | ||
44 | |||||
45 | 1 | 0s | my $module_map1 = { 'map' => { ':key' => { name => \&module, value => \&exversion } } }; | ||
46 | |||||
47 | 1 | 0s | my $module_map2 = { 'map' => { ':key' => { name => \&module, value => \&version } } }; | ||
48 | |||||
49 | 1 | 0s | my $no_index_2 = { | ||
50 | 'map' => { file => { list => { value => \&string } }, | ||||
51 | directory => { list => { value => \&string } }, | ||||
52 | 'package' => { list => { value => \&string } }, | ||||
53 | namespace => { list => { value => \&string } }, | ||||
54 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
55 | } | ||||
56 | }; | ||||
57 | |||||
58 | 1 | 0s | my $no_index_1_3 = { | ||
59 | 'map' => { file => { list => { value => \&string } }, | ||||
60 | directory => { list => { value => \&string } }, | ||||
61 | 'package' => { list => { value => \&string } }, | ||||
62 | namespace => { list => { value => \&string } }, | ||||
63 | ':key' => { name => \&string, value => \&anything }, | ||||
64 | } | ||||
65 | }; | ||||
66 | |||||
67 | 1 | 0s | my $no_index_1_2 = { | ||
68 | 'map' => { file => { list => { value => \&string } }, | ||||
69 | dir => { list => { value => \&string } }, | ||||
70 | 'package' => { list => { value => \&string } }, | ||||
71 | namespace => { list => { value => \&string } }, | ||||
72 | ':key' => { name => \&string, value => \&anything }, | ||||
73 | } | ||||
74 | }; | ||||
75 | |||||
76 | 1 | 0s | my $no_index_1_1 = { | ||
77 | 'map' => { ':key' => { name => \&string, list => { value => \&string } }, | ||||
78 | } | ||||
79 | }; | ||||
80 | |||||
81 | 1 | 0s | my $prereq_map = { | ||
82 | map => { | ||||
83 | ':key' => { | ||||
84 | name => \&phase, | ||||
85 | 'map' => { | ||||
86 | ':key' => { | ||||
87 | name => \&relation, | ||||
88 | %$module_map1, | ||||
89 | }, | ||||
90 | }, | ||||
91 | } | ||||
92 | }, | ||||
93 | }; | ||||
94 | |||||
95 | 1 | 0s | my %definitions = ( | ||
96 | '2' => { | ||||
97 | # REQUIRED | ||||
98 | 'abstract' => { mandatory => 1, value => \&string }, | ||||
99 | 'author' => { mandatory => 1, list => { value => \&string } }, | ||||
100 | 'dynamic_config' => { mandatory => 1, value => \&boolean }, | ||||
101 | 'generated_by' => { mandatory => 1, value => \&string }, | ||||
102 | 'license' => { mandatory => 1, list => { value => \&license } }, | ||||
103 | 'meta-spec' => { | ||||
104 | mandatory => 1, | ||||
105 | 'map' => { | ||||
106 | version => { mandatory => 1, value => \&version}, | ||||
107 | url => { value => \&url }, | ||||
108 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
109 | } | ||||
110 | }, | ||||
111 | 'name' => { mandatory => 1, value => \&string }, | ||||
112 | 'release_status' => { mandatory => 1, value => \&release_status }, | ||||
113 | 'version' => { mandatory => 1, value => \&version }, | ||||
114 | |||||
115 | # OPTIONAL | ||||
116 | 'description' => { value => \&string }, | ||||
117 | 'keywords' => { list => { value => \&string } }, | ||||
118 | 'no_index' => $no_index_2, | ||||
119 | 'optional_features' => { | ||||
120 | 'map' => { | ||||
121 | ':key' => { | ||||
122 | name => \&string, | ||||
123 | 'map' => { | ||||
124 | description => { value => \&string }, | ||||
125 | prereqs => $prereq_map, | ||||
126 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
127 | } | ||||
128 | } | ||||
129 | } | ||||
130 | }, | ||||
131 | 'prereqs' => $prereq_map, | ||||
132 | 'provides' => { | ||||
133 | 'map' => { | ||||
134 | ':key' => { | ||||
135 | name => \&module, | ||||
136 | 'map' => { | ||||
137 | file => { mandatory => 1, value => \&file }, | ||||
138 | version => { value => \&version }, | ||||
139 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
140 | } | ||||
141 | } | ||||
142 | } | ||||
143 | }, | ||||
144 | 'resources' => { | ||||
145 | 'map' => { | ||||
146 | license => { list => { value => \&url } }, | ||||
147 | homepage => { value => \&url }, | ||||
148 | bugtracker => { | ||||
149 | 'map' => { | ||||
150 | web => { value => \&url }, | ||||
151 | mailto => { value => \&string}, | ||||
152 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
153 | } | ||||
154 | }, | ||||
155 | repository => { | ||||
156 | 'map' => { | ||||
157 | web => { value => \&url }, | ||||
158 | url => { value => \&url }, | ||||
159 | type => { value => \&string }, | ||||
160 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
161 | } | ||||
162 | }, | ||||
163 | ':key' => { value => \&string, name => \&custom_2 }, | ||||
164 | } | ||||
165 | }, | ||||
166 | |||||
167 | # CUSTOM -- additional user defined key/value pairs | ||||
168 | # note we can only validate the key name, as the structure is user defined | ||||
169 | ':key' => { name => \&custom_2, value => \&anything }, | ||||
170 | }, | ||||
171 | |||||
172 | '1.4' => { | ||||
173 | 'meta-spec' => { | ||||
174 | mandatory => 1, | ||||
175 | 'map' => { | ||||
176 | version => { mandatory => 1, value => \&version}, | ||||
177 | url => { mandatory => 1, value => \&urlspec }, | ||||
178 | ':key' => { name => \&string, value => \&anything }, | ||||
179 | }, | ||||
180 | }, | ||||
181 | |||||
182 | 'name' => { mandatory => 1, value => \&string }, | ||||
183 | 'version' => { mandatory => 1, value => \&version }, | ||||
184 | 'abstract' => { mandatory => 1, value => \&string }, | ||||
185 | 'author' => { mandatory => 1, list => { value => \&string } }, | ||||
186 | 'license' => { mandatory => 1, value => \&license }, | ||||
187 | 'generated_by' => { mandatory => 1, value => \&string }, | ||||
188 | |||||
189 | 'distribution_type' => { value => \&string }, | ||||
190 | 'dynamic_config' => { value => \&boolean }, | ||||
191 | |||||
192 | 'requires' => $module_map1, | ||||
193 | 'recommends' => $module_map1, | ||||
194 | 'build_requires' => $module_map1, | ||||
195 | 'configure_requires' => $module_map1, | ||||
196 | 'conflicts' => $module_map2, | ||||
197 | |||||
198 | 'optional_features' => { | ||||
199 | 'map' => { | ||||
200 | ':key' => { name => \&string, | ||||
201 | 'map' => { description => { value => \&string }, | ||||
202 | requires => $module_map1, | ||||
203 | recommends => $module_map1, | ||||
204 | build_requires => $module_map1, | ||||
205 | conflicts => $module_map2, | ||||
206 | ':key' => { name => \&string, value => \&anything }, | ||||
207 | } | ||||
208 | } | ||||
209 | } | ||||
210 | }, | ||||
211 | |||||
212 | 'provides' => { | ||||
213 | 'map' => { | ||||
214 | ':key' => { name => \&module, | ||||
215 | 'map' => { | ||||
216 | file => { mandatory => 1, value => \&file }, | ||||
217 | version => { value => \&version }, | ||||
218 | ':key' => { name => \&string, value => \&anything }, | ||||
219 | } | ||||
220 | } | ||||
221 | } | ||||
222 | }, | ||||
223 | |||||
224 | 'no_index' => $no_index_1_3, | ||||
225 | 'private' => $no_index_1_3, | ||||
226 | |||||
227 | 'keywords' => { list => { value => \&string } }, | ||||
228 | |||||
229 | 'resources' => { | ||||
230 | 'map' => { license => { value => \&url }, | ||||
231 | homepage => { value => \&url }, | ||||
232 | bugtracker => { value => \&url }, | ||||
233 | repository => { value => \&url }, | ||||
234 | ':key' => { value => \&string, name => \&custom_1 }, | ||||
235 | } | ||||
236 | }, | ||||
237 | |||||
238 | # additional user defined key/value pairs | ||||
239 | # note we can only validate the key name, as the structure is user defined | ||||
240 | ':key' => { name => \&string, value => \&anything }, | ||||
241 | }, | ||||
242 | |||||
243 | '1.3' => { | ||||
244 | 'meta-spec' => { | ||||
245 | mandatory => 1, | ||||
246 | 'map' => { | ||||
247 | version => { mandatory => 1, value => \&version}, | ||||
248 | url => { mandatory => 1, value => \&urlspec }, | ||||
249 | ':key' => { name => \&string, value => \&anything }, | ||||
250 | }, | ||||
251 | }, | ||||
252 | |||||
253 | 'name' => { mandatory => 1, value => \&string }, | ||||
254 | 'version' => { mandatory => 1, value => \&version }, | ||||
255 | 'abstract' => { mandatory => 1, value => \&string }, | ||||
256 | 'author' => { mandatory => 1, list => { value => \&string } }, | ||||
257 | 'license' => { mandatory => 1, value => \&license }, | ||||
258 | 'generated_by' => { mandatory => 1, value => \&string }, | ||||
259 | |||||
260 | 'distribution_type' => { value => \&string }, | ||||
261 | 'dynamic_config' => { value => \&boolean }, | ||||
262 | |||||
263 | 'requires' => $module_map1, | ||||
264 | 'recommends' => $module_map1, | ||||
265 | 'build_requires' => $module_map1, | ||||
266 | 'conflicts' => $module_map2, | ||||
267 | |||||
268 | 'optional_features' => { | ||||
269 | 'map' => { | ||||
270 | ':key' => { name => \&string, | ||||
271 | 'map' => { description => { value => \&string }, | ||||
272 | requires => $module_map1, | ||||
273 | recommends => $module_map1, | ||||
274 | build_requires => $module_map1, | ||||
275 | conflicts => $module_map2, | ||||
276 | ':key' => { name => \&string, value => \&anything }, | ||||
277 | } | ||||
278 | } | ||||
279 | } | ||||
280 | }, | ||||
281 | |||||
282 | 'provides' => { | ||||
283 | 'map' => { | ||||
284 | ':key' => { name => \&module, | ||||
285 | 'map' => { | ||||
286 | file => { mandatory => 1, value => \&file }, | ||||
287 | version => { value => \&version }, | ||||
288 | ':key' => { name => \&string, value => \&anything }, | ||||
289 | } | ||||
290 | } | ||||
291 | } | ||||
292 | }, | ||||
293 | |||||
294 | |||||
295 | 'no_index' => $no_index_1_3, | ||||
296 | 'private' => $no_index_1_3, | ||||
297 | |||||
298 | 'keywords' => { list => { value => \&string } }, | ||||
299 | |||||
300 | 'resources' => { | ||||
301 | 'map' => { license => { value => \&url }, | ||||
302 | homepage => { value => \&url }, | ||||
303 | bugtracker => { value => \&url }, | ||||
304 | repository => { value => \&url }, | ||||
305 | ':key' => { value => \&string, name => \&custom_1 }, | ||||
306 | } | ||||
307 | }, | ||||
308 | |||||
309 | # additional user defined key/value pairs | ||||
310 | # note we can only validate the key name, as the structure is user defined | ||||
311 | ':key' => { name => \&string, value => \&anything }, | ||||
312 | }, | ||||
313 | |||||
314 | # v1.2 is misleading, it seems to assume that a number of fields where created | ||||
315 | # within v1.1, when they were created within v1.2. This may have been an | ||||
316 | # original mistake, and that a v1.1 was retro fitted into the timeline, when | ||||
317 | # v1.2 was originally slated as v1.1. But I could be wrong ;) | ||||
318 | '1.2' => { | ||||
319 | 'meta-spec' => { | ||||
320 | mandatory => 1, | ||||
321 | 'map' => { | ||||
322 | version => { mandatory => 1, value => \&version}, | ||||
323 | url => { mandatory => 1, value => \&urlspec }, | ||||
324 | ':key' => { name => \&string, value => \&anything }, | ||||
325 | }, | ||||
326 | }, | ||||
327 | |||||
328 | |||||
329 | 'name' => { mandatory => 1, value => \&string }, | ||||
330 | 'version' => { mandatory => 1, value => \&version }, | ||||
331 | 'license' => { mandatory => 1, value => \&license }, | ||||
332 | 'generated_by' => { mandatory => 1, value => \&string }, | ||||
333 | 'author' => { mandatory => 1, list => { value => \&string } }, | ||||
334 | 'abstract' => { mandatory => 1, value => \&string }, | ||||
335 | |||||
336 | 'distribution_type' => { value => \&string }, | ||||
337 | 'dynamic_config' => { value => \&boolean }, | ||||
338 | |||||
339 | 'keywords' => { list => { value => \&string } }, | ||||
340 | |||||
341 | 'private' => $no_index_1_2, | ||||
342 | '$no_index' => $no_index_1_2, | ||||
343 | |||||
344 | 'requires' => $module_map1, | ||||
345 | 'recommends' => $module_map1, | ||||
346 | 'build_requires' => $module_map1, | ||||
347 | 'conflicts' => $module_map2, | ||||
348 | |||||
349 | 'optional_features' => { | ||||
350 | 'map' => { | ||||
351 | ':key' => { name => \&string, | ||||
352 | 'map' => { description => { value => \&string }, | ||||
353 | requires => $module_map1, | ||||
354 | recommends => $module_map1, | ||||
355 | build_requires => $module_map1, | ||||
356 | conflicts => $module_map2, | ||||
357 | ':key' => { name => \&string, value => \&anything }, | ||||
358 | } | ||||
359 | } | ||||
360 | } | ||||
361 | }, | ||||
362 | |||||
363 | 'provides' => { | ||||
364 | 'map' => { | ||||
365 | ':key' => { name => \&module, | ||||
366 | 'map' => { | ||||
367 | file => { mandatory => 1, value => \&file }, | ||||
368 | version => { value => \&version }, | ||||
369 | ':key' => { name => \&string, value => \&anything }, | ||||
370 | } | ||||
371 | } | ||||
372 | } | ||||
373 | }, | ||||
374 | |||||
375 | 'resources' => { | ||||
376 | 'map' => { license => { value => \&url }, | ||||
377 | homepage => { value => \&url }, | ||||
378 | bugtracker => { value => \&url }, | ||||
379 | repository => { value => \&url }, | ||||
380 | ':key' => { value => \&string, name => \&custom_1 }, | ||||
381 | } | ||||
382 | }, | ||||
383 | |||||
384 | # additional user defined key/value pairs | ||||
385 | # note we can only validate the key name, as the structure is user defined | ||||
386 | ':key' => { name => \&string, value => \&anything }, | ||||
387 | }, | ||||
388 | |||||
389 | # note that the 1.1 spec only specifies 'version' as mandatory | ||||
390 | '1.1' => { | ||||
391 | 'name' => { value => \&string }, | ||||
392 | 'version' => { mandatory => 1, value => \&version }, | ||||
393 | 'license' => { value => \&license }, | ||||
394 | 'generated_by' => { value => \&string }, | ||||
395 | |||||
396 | 'license_uri' => { value => \&url }, | ||||
397 | 'distribution_type' => { value => \&string }, | ||||
398 | 'dynamic_config' => { value => \&boolean }, | ||||
399 | |||||
400 | 'private' => $no_index_1_1, | ||||
401 | |||||
402 | 'requires' => $module_map1, | ||||
403 | 'recommends' => $module_map1, | ||||
404 | 'build_requires' => $module_map1, | ||||
405 | 'conflicts' => $module_map2, | ||||
406 | |||||
407 | # additional user defined key/value pairs | ||||
408 | # note we can only validate the key name, as the structure is user defined | ||||
409 | ':key' => { name => \&string, value => \&anything }, | ||||
410 | }, | ||||
411 | |||||
412 | # note that the 1.0 spec doesn't specify optional or mandatory fields | ||||
413 | # but we will treat version as mandatory since otherwise META 1.0 is | ||||
414 | # completely arbitrary and pointless | ||||
415 | '1.0' => { | ||||
416 | 'name' => { value => \&string }, | ||||
417 | 'version' => { mandatory => 1, value => \&version }, | ||||
418 | 'license' => { value => \&license }, | ||||
419 | 'generated_by' => { value => \&string }, | ||||
420 | |||||
421 | 'license_uri' => { value => \&url }, | ||||
422 | 'distribution_type' => { value => \&string }, | ||||
423 | 'dynamic_config' => { value => \&boolean }, | ||||
424 | |||||
425 | 'requires' => $module_map1, | ||||
426 | 'recommends' => $module_map1, | ||||
427 | 'build_requires' => $module_map1, | ||||
428 | 'conflicts' => $module_map2, | ||||
429 | |||||
430 | # additional user defined key/value pairs | ||||
431 | # note we can only validate the key name, as the structure is user defined | ||||
432 | ':key' => { name => \&string, value => \&anything }, | ||||
433 | }, | ||||
434 | ); | ||||
435 | |||||
436 | #--------------------------------------------------------------------------# | ||||
437 | # Code | ||||
438 | #--------------------------------------------------------------------------# | ||||
439 | |||||
440 | #pod =method new | ||||
441 | #pod | ||||
442 | #pod my $cmv = CPAN::Meta::Validator->new( $struct ) | ||||
443 | #pod | ||||
444 | #pod The constructor must be passed a metadata structure. | ||||
445 | #pod | ||||
446 | #pod =cut | ||||
447 | |||||
448 | # spent 0s within CPAN::Meta::Validator::new which was called 29 times, avg 0s/call:
# 9 times (0s+0s) by CPAN::Meta::Converter::convert at line 1429 of CPAN/Meta/Converter.pm, avg 0s/call
# 6 times (0s+0s) by ExtUtils::MM_Any::_fix_metadata_before_conversion at line 1026 of ExtUtils/MM_Any.pm, avg 0s/call
# 6 times (0s+0s) by ExtUtils::MM_Any::_fix_metadata_before_conversion at line 1035 of ExtUtils/MM_Any.pm, avg 0s/call
# 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1413 of CPAN/Meta/Converter.pm, avg 0s/call
# 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1446 of CPAN/Meta/Converter.pm, avg 0s/call | ||||
449 | 29 | 0s | my ($class,$data) = @_; | ||
450 | |||||
451 | # create an attributes hash | ||||
452 | my $self = { | ||||
453 | 'data' => $data, | ||||
454 | 58 | 0s | 'spec' => eval { $data->{'meta-spec'}{'version'} } || "1.0", | ||
455 | 'errors' => undef, | ||||
456 | }; | ||||
457 | |||||
458 | # create the object | ||||
459 | 29 | 0s | return bless $self, $class; | ||
460 | } | ||||
461 | |||||
462 | #pod =method is_valid | ||||
463 | #pod | ||||
464 | #pod if ( $cmv->is_valid ) { | ||||
465 | #pod ... | ||||
466 | #pod } | ||||
467 | #pod | ||||
468 | #pod Returns a boolean value indicating whether the metadata provided | ||||
469 | #pod is valid. | ||||
470 | #pod | ||||
471 | #pod =cut | ||||
472 | |||||
473 | # spent 0s within CPAN::Meta::Validator::is_valid which was called 23 times, avg 0s/call:
# 9 times (0s+0s) by CPAN::Meta::Converter::convert at line 1430 of CPAN/Meta/Converter.pm, avg 0s/call
# 6 times (0s+0s) by ExtUtils::MM_Any::_fix_metadata_before_conversion at line 1036 of ExtUtils/MM_Any.pm, avg 0s/call
# 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1447 of CPAN/Meta/Converter.pm, avg 0s/call
# 4 times (0s+0s) by CPAN::Meta::Converter::convert at line 1414 of CPAN/Meta/Converter.pm, avg 0s/call | ||||
474 | 23 | 0s | my $self = shift; | ||
475 | 23 | 0s | my $data = $self->{data}; | ||
476 | 23 | 0s | my $spec_version = $self->{spec}; | ||
477 | 23 | 0s | 23 | 0s | $self->check_map($definitions{$spec_version},$data); # spent 0s making 23 calls to CPAN::Meta::Validator::check_map, avg 0s/call |
478 | 23 | 0s | 23 | 0s | return ! $self->errors; # spent 0s making 23 calls to CPAN::Meta::Validator::errors, avg 0s/call |
479 | } | ||||
480 | |||||
481 | #pod =method errors | ||||
482 | #pod | ||||
483 | #pod warn( join "\n", $cmv->errors ); | ||||
484 | #pod | ||||
485 | #pod Returns a list of errors seen during validation. | ||||
486 | #pod | ||||
487 | #pod =cut | ||||
488 | |||||
489 | # spent 0s within CPAN::Meta::Validator::errors which was called 24 times, avg 0s/call:
# 23 times (0s+0s) by CPAN::Meta::Validator::is_valid at line 478, avg 0s/call
# once (0s+0s) by ExtUtils::MM_Any::_fix_metadata_before_conversion at line 1039 of ExtUtils/MM_Any.pm | ||||
490 | 24 | 0s | my $self = shift; | ||
491 | 24 | 0s | return () unless(defined $self->{errors}); | ||
492 | 2 | 0s | return @{$self->{errors}}; | ||
493 | } | ||||
494 | |||||
495 | #pod =begin :internals | ||||
496 | #pod | ||||
497 | #pod =head2 Check Methods | ||||
498 | #pod | ||||
499 | #pod =over | ||||
500 | #pod | ||||
501 | #pod =item * | ||||
502 | #pod | ||||
503 | #pod check_map($spec,$data) | ||||
504 | #pod | ||||
505 | #pod Checks whether a map (or hash) part of the data structure conforms to the | ||||
506 | #pod appropriate specification definition. | ||||
507 | #pod | ||||
508 | #pod =item * | ||||
509 | #pod | ||||
510 | #pod check_list($spec,$data) | ||||
511 | #pod | ||||
512 | #pod Checks whether a list (or array) part of the data structure conforms to | ||||
513 | #pod the appropriate specification definition. | ||||
514 | #pod | ||||
515 | #pod =item * | ||||
516 | #pod | ||||
517 | #pod =back | ||||
518 | #pod | ||||
519 | #pod =cut | ||||
520 | |||||
521 | 1 | 0s | my $spec_error = "Missing validation action in specification. " | ||
522 | . "Must be one of 'map', 'list', or 'value'"; | ||||
523 | |||||
524 | # spent 0s within CPAN::Meta::Validator::check_map which was called 179 times, avg 0s/call:
# 108 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call
# 48 times (0s+0s) by CPAN::Meta::Validator::check_map at line 560, avg 0s/call
# 23 times (0s+0s) by CPAN::Meta::Validator::is_valid at line 477, avg 0s/call | ||||
525 | 179 | 0s | my ($self,$spec,$data) = @_; | ||
526 | |||||
527 | 179 | 0s | if(ref($spec) ne 'HASH') { | ||
528 | $self->_error( "Unknown META specification, cannot validate." ); | ||||
529 | return; | ||||
530 | } | ||||
531 | |||||
532 | 179 | 0s | if(ref($data) ne 'HASH') { | ||
533 | $self->_error( "Expected a map structure from string or file." ); | ||||
534 | return; | ||||
535 | } | ||||
536 | |||||
537 | 179 | 0s | for my $key (keys %$spec) { | ||
538 | 791 | 0s | next unless($spec->{$key}->{mandatory}); | ||
539 | 217 | 0s | next if(defined $data->{$key}); | ||
540 | 1 | 0s | push @{$self->{stack}}, $key; | ||
541 | 1 | 0s | 1 | 0s | $self->_error( "Missing mandatory field, '$key'" ); # spent 0s making 1 call to CPAN::Meta::Validator::_error |
542 | 1 | 0s | pop @{$self->{stack}}; | ||
543 | } | ||||
544 | |||||
545 | 179 | 0s | for my $key (keys %$data) { | ||
546 | 463 | 0s | push @{$self->{stack}}, $key; | ||
547 | 463 | 0s | if($spec->{$key}) { | ||
548 | 372 | 0s | 372 | 0s | if($spec->{$key}{value}) { # spent 0s making 23 calls to CPAN::Meta::Validator::boolean, avg 0s/call
# spent 0s making 56 calls to CPAN::Meta::Validator::check_list, avg 0s/call
# spent 0s making 108 calls to CPAN::Meta::Validator::check_map, avg 0s/call, recursion: max depth 2, sum of overlapping time 0s
# spent 0s making 13 calls to CPAN::Meta::Validator::license, avg 0s/call
# spent 0s making 9 calls to CPAN::Meta::Validator::release_status, avg 0s/call
# spent 0s making 79 calls to CPAN::Meta::Validator::string, avg 0s/call
# spent 0s making 25 calls to CPAN::Meta::Validator::url, avg 0s/call
# spent 0s making 13 calls to CPAN::Meta::Validator::urlspec, avg 0s/call
# spent 0s making 46 calls to CPAN::Meta::Validator::version, avg 0s/call |
549 | $spec->{$key}{value}->($self,$key,$data->{$key}); | ||||
550 | } elsif($spec->{$key}{'map'}) { | ||||
551 | $self->check_map($spec->{$key}{'map'},$data->{$key}); | ||||
552 | } elsif($spec->{$key}{'list'}) { | ||||
553 | $self->check_list($spec->{$key}{'list'},$data->{$key}); | ||||
554 | } else { | ||||
555 | $self->_error( "$spec_error for '$key'" ); | ||||
556 | } | ||||
557 | |||||
558 | } elsif ($spec->{':key'}) { | ||||
559 | 91 | 0s | 91 | 0s | $spec->{':key'}{name}->($self,$key,$key); # spent 0s making 1 call to CPAN::Meta::Validator::custom_2
# spent 0s making 42 calls to CPAN::Meta::Validator::module, avg 0s/call
# spent 0s making 24 calls to CPAN::Meta::Validator::phase, avg 0s/call
# spent 0s making 24 calls to CPAN::Meta::Validator::relation, avg 0s/call |
560 | 91 | 0s | 91 | 0s | if($spec->{':key'}{value}) { # spent 0s making 1 call to CPAN::Meta::Validator::anything
# spent 0s making 48 calls to CPAN::Meta::Validator::check_map, avg 0s/call, recursion: max depth 3, sum of overlapping time 0s
# spent 0s making 42 calls to CPAN::Meta::Validator::exversion, avg 0s/call |
561 | $spec->{':key'}{value}->($self,$key,$data->{$key}); | ||||
562 | } elsif($spec->{':key'}{'map'}) { | ||||
563 | $self->check_map($spec->{':key'}{'map'},$data->{$key}); | ||||
564 | } elsif($spec->{':key'}{'list'}) { | ||||
565 | $self->check_list($spec->{':key'}{'list'},$data->{$key}); | ||||
566 | } else { | ||||
567 | $self->_error( "$spec_error for ':key'" ); | ||||
568 | } | ||||
569 | |||||
570 | |||||
571 | } else { | ||||
572 | $self->_error( "Unknown key, '$key', found in map structure" ); | ||||
573 | } | ||||
574 | 463 | 0s | pop @{$self->{stack}}; | ||
575 | } | ||||
576 | } | ||||
577 | |||||
578 | # spent 0s within CPAN::Meta::Validator::check_list which was called 56 times, avg 0s/call:
# 56 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call | ||||
579 | 56 | 0s | my ($self,$spec,$data) = @_; | ||
580 | |||||
581 | 56 | 0s | if(ref($data) ne 'ARRAY') { | ||
582 | 1 | 0s | 1 | 0s | $self->_error( "Expected a list structure" ); # spent 0s making 1 call to CPAN::Meta::Validator::_error |
583 | 1 | 0s | return; | ||
584 | } | ||||
585 | |||||
586 | 55 | 0s | if(defined $spec->{mandatory}) { | ||
587 | if(!defined $data->[0]) { | ||||
588 | $self->_error( "Missing entries from mandatory list" ); | ||||
589 | } | ||||
590 | } | ||||
591 | |||||
592 | 55 | 0s | for my $value (@$data) { | ||
593 | 74 | 0s | push @{$self->{stack}}, $value || "<undef>"; | ||
594 | 74 | 0s | 74 | 0s | if(defined $spec->{value}) { # spent 0s making 9 calls to CPAN::Meta::Validator::license, avg 0s/call
# spent 0s making 65 calls to CPAN::Meta::Validator::string, avg 0s/call |
595 | $spec->{value}->($self,'list',$value); | ||||
596 | } elsif(defined $spec->{'map'}) { | ||||
597 | $self->check_map($spec->{'map'},$value); | ||||
598 | } elsif(defined $spec->{'list'}) { | ||||
599 | $self->check_list($spec->{'list'},$value); | ||||
600 | } elsif ($spec->{':key'}) { | ||||
601 | $self->check_map($spec,$value); | ||||
602 | } else { | ||||
603 | $self->_error( "$spec_error associated with '$self->{stack}[-2]'" ); | ||||
604 | } | ||||
605 | 74 | 0s | pop @{$self->{stack}}; | ||
606 | } | ||||
607 | } | ||||
608 | |||||
609 | #pod =head2 Validator Methods | ||||
610 | #pod | ||||
611 | #pod =over | ||||
612 | #pod | ||||
613 | #pod =item * | ||||
614 | #pod | ||||
615 | #pod header($self,$key,$value) | ||||
616 | #pod | ||||
617 | #pod Validates that the header is valid. | ||||
618 | #pod | ||||
619 | #pod Note: No longer used as we now read the data structure, not the file. | ||||
620 | #pod | ||||
621 | #pod =item * | ||||
622 | #pod | ||||
623 | #pod url($self,$key,$value) | ||||
624 | #pod | ||||
625 | #pod Validates that a given value is in an acceptable URL format | ||||
626 | #pod | ||||
627 | #pod =item * | ||||
628 | #pod | ||||
629 | #pod urlspec($self,$key,$value) | ||||
630 | #pod | ||||
631 | #pod Validates that the URL to a META specification is a known one. | ||||
632 | #pod | ||||
633 | #pod =item * | ||||
634 | #pod | ||||
635 | #pod string_or_undef($self,$key,$value) | ||||
636 | #pod | ||||
637 | #pod Validates that the value is either a string or an undef value. Bit of a | ||||
638 | #pod catchall function for parts of the data structure that are completely user | ||||
639 | #pod defined. | ||||
640 | #pod | ||||
641 | #pod =item * | ||||
642 | #pod | ||||
643 | #pod string($self,$key,$value) | ||||
644 | #pod | ||||
645 | #pod Validates that a string exists for the given key. | ||||
646 | #pod | ||||
647 | #pod =item * | ||||
648 | #pod | ||||
649 | #pod file($self,$key,$value) | ||||
650 | #pod | ||||
651 | #pod Validate that a file is passed for the given key. This may be made more | ||||
652 | #pod thorough in the future. For now it acts like \&string. | ||||
653 | #pod | ||||
654 | #pod =item * | ||||
655 | #pod | ||||
656 | #pod exversion($self,$key,$value) | ||||
657 | #pod | ||||
658 | #pod Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'. | ||||
659 | #pod | ||||
660 | #pod =item * | ||||
661 | #pod | ||||
662 | #pod version($self,$key,$value) | ||||
663 | #pod | ||||
664 | #pod Validates a single version string. Versions of the type '5.8.8' and '0.00_00' | ||||
665 | #pod are both valid. A leading 'v' like 'v1.2.3' is also valid. | ||||
666 | #pod | ||||
667 | #pod =item * | ||||
668 | #pod | ||||
669 | #pod boolean($self,$key,$value) | ||||
670 | #pod | ||||
671 | #pod Validates for a boolean value. Currently these values are '1', '0', 'true', | ||||
672 | #pod 'false', however the latter 2 may be removed. | ||||
673 | #pod | ||||
674 | #pod =item * | ||||
675 | #pod | ||||
676 | #pod license($self,$key,$value) | ||||
677 | #pod | ||||
678 | #pod Validates that a value is given for the license. Returns 1 if an known license | ||||
679 | #pod type, or 2 if a value is given but the license type is not a recommended one. | ||||
680 | #pod | ||||
681 | #pod =item * | ||||
682 | #pod | ||||
683 | #pod custom_1($self,$key,$value) | ||||
684 | #pod | ||||
685 | #pod Validates that the given key is in CamelCase, to indicate a user defined | ||||
686 | #pod keyword and only has characters in the class [-_a-zA-Z]. In version 1.X | ||||
687 | #pod of the spec, this was only explicitly stated for 'resources'. | ||||
688 | #pod | ||||
689 | #pod =item * | ||||
690 | #pod | ||||
691 | #pod custom_2($self,$key,$value) | ||||
692 | #pod | ||||
693 | #pod Validates that the given key begins with 'x_' or 'X_', to indicate a user | ||||
694 | #pod defined keyword and only has characters in the class [-_a-zA-Z] | ||||
695 | #pod | ||||
696 | #pod =item * | ||||
697 | #pod | ||||
698 | #pod identifier($self,$key,$value) | ||||
699 | #pod | ||||
700 | #pod Validates that key is in an acceptable format for the META specification, | ||||
701 | #pod for an identifier, i.e. any that matches the regular expression | ||||
702 | #pod qr/[a-z][a-z_]/i. | ||||
703 | #pod | ||||
704 | #pod =item * | ||||
705 | #pod | ||||
706 | #pod module($self,$key,$value) | ||||
707 | #pod | ||||
708 | #pod Validates that a given key is in an acceptable module name format, e.g. | ||||
709 | #pod 'Test::CPAN::Meta::Version'. | ||||
710 | #pod | ||||
711 | #pod =back | ||||
712 | #pod | ||||
713 | #pod =end :internals | ||||
714 | #pod | ||||
715 | #pod =cut | ||||
716 | |||||
717 | sub header { | ||||
718 | my ($self,$key,$value) = @_; | ||||
719 | if(defined $value) { | ||||
720 | return 1 if($value && $value =~ /^--- #YAML:1.0/); | ||||
721 | } | ||||
722 | $self->_error( "file does not have a valid YAML header." ); | ||||
723 | return 0; | ||||
724 | } | ||||
725 | |||||
726 | # spent 0s within CPAN::Meta::Validator::release_status which was called 9 times, avg 0s/call:
# 9 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call | ||||
727 | 9 | 0s | my ($self,$key,$value) = @_; | ||
728 | 9 | 0s | if(defined $value) { | ||
729 | 9 | 0s | my $version = $self->{data}{version} || ''; | ||
730 | 9 | 0s | 9 | 0s | if ( $version =~ /_/ ) { # spent 0s making 9 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
731 | return 1 if ( $value =~ /\A(?:testing|unstable)\z/ ); | ||||
732 | $self->_error( "'$value' for '$key' is invalid for version '$version'" ); | ||||
733 | } | ||||
734 | else { | ||||
735 | 9 | 0s | 9 | 0s | return 1 if ( $value =~ /\A(?:stable|testing|unstable)\z/ ); # spent 0s making 9 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
736 | $self->_error( "'$value' for '$key' is invalid" ); | ||||
737 | } | ||||
738 | } | ||||
739 | else { | ||||
740 | $self->_error( "'$key' is not defined" ); | ||||
741 | } | ||||
742 | return 0; | ||||
743 | } | ||||
744 | |||||
745 | # _uri_split taken from URI::Split by Gisle Aas, Copyright 2003 | ||||
746 | # spent 0s within CPAN::Meta::Validator::_uri_split which was called 25 times, avg 0s/call:
# 25 times (0s+0s) by CPAN::Meta::Validator::url at line 753, avg 0s/call | ||||
747 | 25 | 0s | 25 | 0s | return $_[0] =~ m,(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?,; # spent 0s making 25 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
748 | } | ||||
749 | |||||
750 | # spent 0s within CPAN::Meta::Validator::url which was called 25 times, avg 0s/call:
# 25 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call | ||||
751 | 25 | 0s | my ($self,$key,$value) = @_; | ||
752 | 25 | 0s | if(defined $value) { | ||
753 | 25 | 0s | 25 | 0s | my ($scheme, $auth, $path, $query, $frag) = _uri_split($value); # spent 0s making 25 calls to CPAN::Meta::Validator::_uri_split, avg 0s/call |
754 | 25 | 0s | unless ( defined $scheme && length $scheme ) { | ||
755 | $self->_error( "'$value' for '$key' does not have a URL scheme" ); | ||||
756 | return 0; | ||||
757 | } | ||||
758 | 25 | 0s | unless ( defined $auth && length $auth ) { | ||
759 | $self->_error( "'$value' for '$key' does not have a URL authority" ); | ||||
760 | return 0; | ||||
761 | } | ||||
762 | 25 | 0s | return 1; | ||
763 | } | ||||
764 | $value ||= ''; | ||||
765 | $self->_error( "'$value' for '$key' is not a valid URL." ); | ||||
766 | return 0; | ||||
767 | } | ||||
768 | |||||
769 | # spent 0s within CPAN::Meta::Validator::urlspec which was called 13 times, avg 0s/call:
# 13 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call | ||||
770 | 13 | 0s | my ($self,$key,$value) = @_; | ||
771 | 13 | 0s | if(defined $value) { | ||
772 | 13 | 0s | return 1 if($value && $known_specs{$self->{spec}} eq $value); | ||
773 | if($value && $known_urls{$value}) { | ||||
774 | $self->_error( 'META specification URL does not match version' ); | ||||
775 | return 0; | ||||
776 | } | ||||
777 | } | ||||
778 | $self->_error( 'Unknown META specification' ); | ||||
779 | return 0; | ||||
780 | } | ||||
781 | |||||
782 | 1 | 0s | # spent 0s within CPAN::Meta::Validator::anything which was called:
# once (0s+0s) by CPAN::Meta::Validator::check_map at line 560 | ||
783 | |||||
784 | sub string { | ||||
785 | 144 | 0s | my ($self,$key,$value) = @_; | ||
786 | 144 | 0s | if(defined $value) { | ||
787 | 144 | 0s | return 1 if($value || $value =~ /^0$/); | ||
788 | } | ||||
789 | $self->_error( "value is an undefined string" ); | ||||
790 | return 0; | ||||
791 | } | ||||
792 | |||||
793 | sub string_or_undef { | ||||
794 | my ($self,$key,$value) = @_; | ||||
795 | return 1 unless(defined $value); | ||||
796 | return 1 if($value || $value =~ /^0$/); | ||||
797 | $self->_error( "No string defined for '$key'" ); | ||||
798 | return 0; | ||||
799 | } | ||||
800 | |||||
801 | sub file { | ||||
802 | my ($self,$key,$value) = @_; | ||||
803 | return 1 if(defined $value); | ||||
804 | $self->_error( "No file defined for '$key'" ); | ||||
805 | return 0; | ||||
806 | } | ||||
807 | |||||
808 | # spent 0s within CPAN::Meta::Validator::exversion which was called 42 times, avg 0s/call:
# 42 times (0s+0s) by CPAN::Meta::Validator::check_map at line 560, avg 0s/call | ||||
809 | 42 | 0s | my ($self,$key,$value) = @_; | ||
810 | 42 | 0s | 42 | 0s | if(defined $value && ($value || $value =~ /0/)) { # spent 0s making 42 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
811 | 42 | 0s | my $pass = 1; | ||
812 | 84 | 0s | 42 | 0s | for(split(",",$value)) { $self->version($key,$_) or ($pass = 0); } # spent 0s making 42 calls to CPAN::Meta::Validator::version, avg 0s/call |
813 | 42 | 0s | return $pass; | ||
814 | } | ||||
815 | $value = '<undef>' unless(defined $value); | ||||
816 | $self->_error( "'$value' for '$key' is not a valid version." ); | ||||
817 | return 0; | ||||
818 | } | ||||
819 | |||||
820 | # spent 0s within CPAN::Meta::Validator::version which was called 94 times, avg 0s/call:
# 46 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call
# 42 times (0s+0s) by CPAN::Meta::Validator::exversion at line 812, avg 0s/call
# 6 times (0s+0s) by ExtUtils::MM_Any::_fix_metadata_before_conversion at line 1026 of ExtUtils/MM_Any.pm, avg 0s/call | ||||
821 | 94 | 0s | my ($self,$key,$value) = @_; | ||
822 | 94 | 0s | if(defined $value) { | ||
823 | 94 | 0s | 42 | 0s | return 0 unless($value || $value =~ /0/); # spent 0s making 42 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
824 | 94 | 0s | 94 | 0s | return 1 if($value =~ /^\s*((<|<=|>=|>|!=|==)\s*)?v?\d+((\.\d+((_|\.)\d+)?)?)/); # spent 0s making 94 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
825 | } else { | ||||
826 | $value = '<undef>'; | ||||
827 | } | ||||
828 | $self->_error( "'$value' for '$key' is not a valid version." ); | ||||
829 | return 0; | ||||
830 | } | ||||
831 | |||||
832 | # spent 0s within CPAN::Meta::Validator::boolean which was called 23 times, avg 0s/call:
# 23 times (0s+0s) by CPAN::Meta::Validator::check_map at line 548, avg 0s/call | ||||
833 | 23 | 0s | my ($self,$key,$value) = @_; | ||
834 | 23 | 0s | if(defined $value) { | ||
835 | 23 | 0s | 23 | 0s | return 1 if($value =~ /^(0|1|true|false)$/); # spent 0s making 23 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
836 | } else { | ||||
837 | $value = '<undef>'; | ||||
838 | } | ||||
839 | $self->_error( "'$value' for '$key' is not a boolean value." ); | ||||
840 | return 0; | ||||
841 | } | ||||
842 | |||||
843 | 1 | 0s | my %v1_licenses = ( | ||
844 | 'perl' => 'http://dev.perl.org/licenses/', | ||||
845 | 'gpl' => 'http://www.opensource.org/licenses/gpl-license.php', | ||||
846 | 'apache' => 'http://apache.org/licenses/LICENSE-2.0', | ||||
847 | 'artistic' => 'http://opensource.org/licenses/artistic-license.php', | ||||
848 | 'artistic_2' => 'http://opensource.org/licenses/artistic-license-2.0.php', | ||||
849 | 'lgpl' => 'http://www.opensource.org/licenses/lgpl-license.php', | ||||
850 | 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', | ||||
851 | 'gpl' => 'http://www.opensource.org/licenses/gpl-license.php', | ||||
852 | 'mit' => 'http://opensource.org/licenses/mit-license.php', | ||||
853 | 'mozilla' => 'http://opensource.org/licenses/mozilla1.1.php', | ||||
854 | 'open_source' => undef, | ||||
855 | 'unrestricted' => undef, | ||||
856 | 'restrictive' => undef, | ||||
857 | 'unknown' => undef, | ||||
858 | ); | ||||
859 | |||||
860 | 1 | 0s | my %v2_licenses = map { $_ => 1 } qw( | ||
861 | agpl_3 | ||||
862 | apache_1_1 | ||||
863 | apache_2_0 | ||||
864 | artistic_1 | ||||
865 | artistic_2 | ||||
866 | bsd | ||||
867 | freebsd | ||||
868 | gfdl_1_2 | ||||
869 | gfdl_1_3 | ||||
870 | gpl_1 | ||||
871 | gpl_2 | ||||
872 | gpl_3 | ||||
873 | lgpl_2_1 | ||||
874 | lgpl_3_0 | ||||
875 | mit | ||||
876 | mozilla_1_0 | ||||
877 | mozilla_1_1 | ||||
878 | openssl | ||||
879 | perl_5 | ||||
880 | qpl_1_0 | ||||
881 | ssleay | ||||
882 | sun | ||||
883 | zlib | ||||
884 | open_source | ||||
885 | restricted | ||||
886 | unrestricted | ||||
887 | unknown | ||||
888 | ); | ||||
889 | |||||
890 | sub license { | ||||
891 | 22 | 0s | my ($self,$key,$value) = @_; | ||
892 | 22 | 0s | my $licenses = $self->{spec} < 2 ? \%v1_licenses : \%v2_licenses; | ||
893 | 22 | 0s | if(defined $value) { | ||
894 | return 1 if($value && exists $licenses->{$value}); | ||||
895 | } else { | ||||
896 | $value = '<undef>'; | ||||
897 | } | ||||
898 | $self->_error( "License '$value' is invalid" ); | ||||
899 | return 0; | ||||
900 | } | ||||
901 | |||||
902 | sub custom_1 { | ||||
903 | my ($self,$key) = @_; | ||||
904 | if(defined $key) { | ||||
905 | # a valid user defined key should be alphabetic | ||||
906 | # and contain at least one capital case letter. | ||||
907 | return 1 if($key && $key =~ /^[_a-z]+$/i && $key =~ /[A-Z]/); | ||||
908 | } else { | ||||
909 | $key = '<undef>'; | ||||
910 | } | ||||
911 | $self->_error( "Custom resource '$key' must be in CamelCase." ); | ||||
912 | return 0; | ||||
913 | } | ||||
914 | |||||
915 | # spent 0s within CPAN::Meta::Validator::custom_2 which was called:
# once (0s+0s) by CPAN::Meta::Validator::check_map at line 559 | ||||
916 | 1 | 0s | my ($self,$key) = @_; | ||
917 | 1 | 0s | if(defined $key) { | ||
918 | 1 | 0s | 1 | 0s | return 1 if($key && $key =~ /^x_/i); # user defined # spent 0s making 1 call to CPAN::Meta::Validator::CORE:match |
919 | } else { | ||||
920 | $key = '<undef>'; | ||||
921 | } | ||||
922 | 1 | 0s | 1 | 0s | $self->_error( "Custom key '$key' must begin with 'x_' or 'X_'." ); # spent 0s making 1 call to CPAN::Meta::Validator::_error |
923 | 1 | 0s | return 0; | ||
924 | } | ||||
925 | |||||
926 | sub identifier { | ||||
927 | my ($self,$key) = @_; | ||||
928 | if(defined $key) { | ||||
929 | return 1 if($key && $key =~ /^([a-z][_a-z]+)$/i); # spec 2.0 defined | ||||
930 | } else { | ||||
931 | $key = '<undef>'; | ||||
932 | } | ||||
933 | $self->_error( "Key '$key' is not a legal identifier." ); | ||||
934 | return 0; | ||||
935 | } | ||||
936 | |||||
937 | # spent 0s within CPAN::Meta::Validator::module which was called 42 times, avg 0s/call:
# 42 times (0s+0s) by CPAN::Meta::Validator::check_map at line 559, avg 0s/call | ||||
938 | 42 | 0s | my ($self,$key) = @_; | ||
939 | 42 | 0s | if(defined $key) { | ||
940 | 42 | 0s | 42 | 0s | return 1 if($key && $key =~ /^[A-Za-z0-9_]+(::[A-Za-z0-9_]+)*$/); # spent 0s making 42 calls to CPAN::Meta::Validator::CORE:match, avg 0s/call |
941 | } else { | ||||
942 | $key = '<undef>'; | ||||
943 | } | ||||
944 | $self->_error( "Key '$key' is not a legal module name." ); | ||||
945 | return 0; | ||||
946 | } | ||||
947 | |||||
948 | 1 | 0s | my @valid_phases = qw/ configure build test runtime develop /; | ||
949 | # spent 0s within CPAN::Meta::Validator::phase which was called 24 times, avg 0s/call:
# 24 times (0s+0s) by CPAN::Meta::Validator::check_map at line 559, avg 0s/call | ||||
950 | 24 | 0s | my ($self,$key) = @_; | ||
951 | 24 | 0s | if(defined $key) { | ||
952 | 24 | 0s | return 1 if( length $key && grep { $key eq $_ } @valid_phases ); | ||
953 | return 1 if $key =~ /x_/i; | ||||
954 | } else { | ||||
955 | $key = '<undef>'; | ||||
956 | } | ||||
957 | $self->_error( "Key '$key' is not a legal phase." ); | ||||
958 | return 0; | ||||
959 | } | ||||
960 | |||||
961 | 1 | 0s | my @valid_relations = qw/ requires recommends suggests conflicts /; | ||
962 | # spent 0s within CPAN::Meta::Validator::relation which was called 24 times, avg 0s/call:
# 24 times (0s+0s) by CPAN::Meta::Validator::check_map at line 559, avg 0s/call | ||||
963 | 24 | 0s | my ($self,$key) = @_; | ||
964 | 24 | 0s | if(defined $key) { | ||
965 | 24 | 0s | return 1 if( length $key && grep { $key eq $_ } @valid_relations ); | ||
966 | return 1 if $key =~ /x_/i; | ||||
967 | } else { | ||||
968 | $key = '<undef>'; | ||||
969 | } | ||||
970 | $self->_error( "Key '$key' is not a legal prereq relationship." ); | ||||
971 | return 0; | ||||
972 | } | ||||
973 | |||||
974 | sub _error { | ||||
975 | 3 | 0s | my $self = shift; | ||
976 | 3 | 0s | my $mess = shift; | ||
977 | |||||
978 | 3 | 0s | $mess .= ' ('.join(' -> ',@{$self->{stack}}).')' if($self->{stack}); | ||
979 | 3 | 0s | $mess .= " [Validation: $self->{spec}]"; | ||
980 | |||||
981 | 3 | 0s | push @{$self->{errors}}, $mess; | ||
982 | } | ||||
983 | |||||
984 | 1 | 0s | 1; | ||
985 | |||||
986 | # ABSTRACT: validate CPAN distribution metadata structures | ||||
987 | |||||
988 | __END__ | ||||
# spent 0s within CPAN::Meta::Validator::CORE:match which was called 287 times, avg 0s/call:
# 94 times (0s+0s) by CPAN::Meta::Validator::version at line 824, avg 0s/call
# 42 times (0s+0s) by CPAN::Meta::Validator::module at line 940, avg 0s/call
# 42 times (0s+0s) by CPAN::Meta::Validator::version at line 823, avg 0s/call
# 42 times (0s+0s) by CPAN::Meta::Validator::exversion at line 810, avg 0s/call
# 25 times (0s+0s) by CPAN::Meta::Validator::_uri_split at line 747, avg 0s/call
# 23 times (0s+0s) by CPAN::Meta::Validator::boolean at line 835, avg 0s/call
# 9 times (0s+0s) by CPAN::Meta::Validator::release_status at line 730, avg 0s/call
# 9 times (0s+0s) by CPAN::Meta::Validator::release_status at line 735, avg 0s/call
# once (0s+0s) by CPAN::Meta::Validator::custom_2 at line 918 |