| 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 | CPAN::Meta::BEGIN@1.4 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::BEGIN@2.5 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::BEGIN@3.6 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@25 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@26 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@27 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@35 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@474 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@489 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@52 | 
| 1 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::BEGIN@53 | 
| 110 | 6 | 1 | 0s | 0s | CPAN::Meta::Converter::CORE:match (opcode) | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::CORE:qr (opcode) | 
| 21 | 2 | 1 | 0s | 0s | CPAN::Meta::Converter::CORE:regcomp (opcode) | 
| 14 | 3 | 1 | 0s | 0s | CPAN::Meta::Converter::CORE:sort (opcode) | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:43] | 
| 36 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:490] | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:54] | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:624] | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:632] | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:633] | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:670] | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:671] | 
| 3 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:709] | 
| 3 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:711] | 
| 3 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::__ANON__[:712] | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_author_list | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_bad_version_hook | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_change_meta_spec | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_clean_version | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_cleanup_optional_features_2 | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_cleanup_prereqs | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_cleanup_resources_2 | 
| 53 | 9 | 1 | 0s | 0s | CPAN::Meta::Converter::_convert (recurses: max depth 2, inclusive time 0s) | 
| 54 | 3 | 2 | 0s | 218ms | CPAN::Meta::Converter::_dclone | 
| 9 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_downgrade_license | 
| 9 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_downgrade_optional_features | 
| 9 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_downgrade_resources | 
| 54 | 3 | 1 | 0s | 0s | CPAN::Meta::Converter::_extract_prereqs | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_extract_spec_version | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_feature_2 | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_generated_by | 
| 9 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_get_build_requires | 
| 60 | 2 | 1 | 0s | 0s | CPAN::Meta::Converter::_is_module_name | 
| 15 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_is_urlish | 
| 68 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_keep | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_keep_or_one | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_keep_or_unknown | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_keep_or_zero | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_license_1 | 
| 8 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_license_2 | 
| 85 | 2 | 1 | 0s | 0s | CPAN::Meta::Converter::_listify | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_no_index_1_2 | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_no_index_directory | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_no_prefix_ucfirst_custom | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_optional_features_1_4 | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_optional_features_as_map | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_prefix_custom | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_prereqs_from_1 | 
| 10 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_prereqs_rel | 
| 17 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_provides | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_release_status | 
| 5 | 2 | 1 | 0s | 0s | CPAN::Meta::Converter::_release_status_from_version | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_repo_type | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_resources_1_2 | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_resources_1_3 | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::_ucfirst_custom | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_upgrade_optional_features | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_upgrade_resources_2 | 
| 4 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_url_list | 
| 15 | 1 | 1 | 0s | 0s | CPAN::Meta::Converter::_url_or_drop | 
| 90 | 4 | 1 | 0s | 0s | CPAN::Meta::Converter::_version_map | 
| 17 | 3 | 1 | 0s | 156ms | CPAN::Meta::Converter::convert | 
| 17 | 3 | 1 | 0s | 0s | CPAN::Meta::Converter::new | 
| 0 | 0 | 0 | 0s | 0s | CPAN::Meta::Converter::upgrade_fragment | 
| 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  |