| Filename | /home/leont/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/Parse/CPAN/Meta.pm |
| Statements | Executed 16 statements in 546µs |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 7µs | 7µs | CPAN::Meta::Converter::BEGIN@1.6 |
| 1 | 1 | 1 | 4µs | 9µs | Parse::CPAN::Meta::BEGIN@47 |
| 1 | 1 | 1 | 3µs | 13µs | Parse::CPAN::Meta::BEGIN@10 |
| 1 | 1 | 1 | 3µs | 11µs | Parse::CPAN::Meta::BEGIN@9 |
| 1 | 1 | 1 | 3µs | 4µs | CPAN::Meta::Converter::BEGIN@2.7 |
| 1 | 1 | 1 | 3µs | 10µs | CPAN::Meta::Converter::BEGIN@3.8 |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::Load |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::LoadFile |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::_can_load |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::_slurp |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::json_backend |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::json_decoder |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::load_file |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::load_json_string |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::load_string |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::load_yaml_string |
| 0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::yaml_backend |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | 2 | 20µs | 1 | 7µs | # spent 7µs within CPAN::Meta::Converter::BEGIN@1.6 which was called:
# once (7µs+0s) by CPAN::Meta::Converter::BEGIN@28 at line 1 # spent 7µs making 1 call to CPAN::Meta::Converter::BEGIN@1.6 |
| 2 | 2 | 9µs | 2 | 6µs | # spent 4µs (3+1) within CPAN::Meta::Converter::BEGIN@2.7 which was called:
# once (3µs+1µs) by CPAN::Meta::Converter::BEGIN@28 at line 2 # spent 4µs making 1 call to CPAN::Meta::Converter::BEGIN@2.7
# spent 1µs making 1 call to strict::import |
| 3 | 2 | 20µs | 2 | 18µs | # spent 10µs (3+8) within CPAN::Meta::Converter::BEGIN@3.8 which was called:
# once (3µs+8µs) by CPAN::Meta::Converter::BEGIN@28 at line 3 # spent 10µs making 1 call to CPAN::Meta::Converter::BEGIN@3.8
# spent 8µs making 1 call to warnings::import |
| 4 | package Parse::CPAN::Meta; | ||||
| 5 | # ABSTRACT: Parse META.yml and META.json CPAN metadata files | ||||
| 6 | |||||
| 7 | 1 | 200ns | our $VERSION = '2.150010'; | ||
| 8 | |||||
| 9 | 2 | 11µs | 2 | 19µs | # spent 11µs (3+8) within Parse::CPAN::Meta::BEGIN@9 which was called:
# once (3µs+8µs) by CPAN::Meta::Converter::BEGIN@28 at line 9 # spent 11µs making 1 call to Parse::CPAN::Meta::BEGIN@9
# spent 8µs making 1 call to Exporter::import |
| 10 | 2 | 132µs | 2 | 24µs | # spent 13µs (3+10) within Parse::CPAN::Meta::BEGIN@10 which was called:
# once (3µs+10µs) by CPAN::Meta::Converter::BEGIN@28 at line 10 # spent 13µs making 1 call to Parse::CPAN::Meta::BEGIN@10
# spent 10µs making 1 call to Exporter::import |
| 11 | |||||
| 12 | 1 | 3µs | our @ISA = qw/Exporter/; | ||
| 13 | 1 | 300ns | our @EXPORT_OK = qw/Load LoadFile/; | ||
| 14 | |||||
| 15 | sub load_file { | ||||
| 16 | my ($class, $filename) = @_; | ||||
| 17 | |||||
| 18 | my $meta = _slurp($filename); | ||||
| 19 | |||||
| 20 | if ($filename =~ /\.ya?ml$/) { | ||||
| 21 | return $class->load_yaml_string($meta); | ||||
| 22 | } | ||||
| 23 | elsif ($filename =~ /\.json$/) { | ||||
| 24 | return $class->load_json_string($meta); | ||||
| 25 | } | ||||
| 26 | else { | ||||
| 27 | $class->load_string($meta); # try to detect yaml/json | ||||
| 28 | } | ||||
| 29 | } | ||||
| 30 | |||||
| 31 | sub load_string { | ||||
| 32 | my ($class, $string) = @_; | ||||
| 33 | if ( $string =~ /^---/ ) { # looks like YAML | ||||
| 34 | return $class->load_yaml_string($string); | ||||
| 35 | } | ||||
| 36 | elsif ( $string =~ /^\s*\{/ ) { # looks like JSON | ||||
| 37 | return $class->load_json_string($string); | ||||
| 38 | } | ||||
| 39 | else { # maybe doc-marker-free YAML | ||||
| 40 | return $class->load_yaml_string($string); | ||||
| 41 | } | ||||
| 42 | } | ||||
| 43 | |||||
| 44 | sub load_yaml_string { | ||||
| 45 | my ($class, $string) = @_; | ||||
| 46 | my $backend = $class->yaml_backend(); | ||||
| 47 | 2 | 348µs | 2 | 14µs | # spent 9µs (4+5) within Parse::CPAN::Meta::BEGIN@47 which was called:
# once (4µs+5µs) by CPAN::Meta::Converter::BEGIN@28 at line 47 # spent 9µs making 1 call to Parse::CPAN::Meta::BEGIN@47
# spent 5µs making 1 call to strict::unimport |
| 48 | croak $@ if $@; | ||||
| 49 | return $data || {}; # in case document was valid but empty | ||||
| 50 | } | ||||
| 51 | |||||
| 52 | sub load_json_string { | ||||
| 53 | my ($class, $string) = @_; | ||||
| 54 | require Encode; | ||||
| 55 | # load_json_string takes characters, decode_json expects bytes | ||||
| 56 | my $encoded = Encode::encode('UTF-8', $string, Encode::PERLQQ()); | ||||
| 57 | my $data = eval { $class->json_decoder()->can('decode_json')->($encoded) }; | ||||
| 58 | croak $@ if $@; | ||||
| 59 | return $data || {}; | ||||
| 60 | } | ||||
| 61 | |||||
| 62 | sub yaml_backend { | ||||
| 63 | if ($ENV{PERL_CORE} or not defined $ENV{PERL_YAML_BACKEND} ) { | ||||
| 64 | _can_load( 'CPAN::Meta::YAML', 0.011 ) | ||||
| 65 | or croak "CPAN::Meta::YAML 0.011 is not available\n"; | ||||
| 66 | return "CPAN::Meta::YAML"; | ||||
| 67 | } | ||||
| 68 | else { | ||||
| 69 | my $backend = $ENV{PERL_YAML_BACKEND}; | ||||
| 70 | _can_load( $backend ) | ||||
| 71 | or croak "Could not load PERL_YAML_BACKEND '$backend'\n"; | ||||
| 72 | $backend->can("Load") | ||||
| 73 | or croak "PERL_YAML_BACKEND '$backend' does not implement Load()\n"; | ||||
| 74 | return $backend; | ||||
| 75 | } | ||||
| 76 | } | ||||
| 77 | |||||
| 78 | sub json_decoder { | ||||
| 79 | if ($ENV{PERL_CORE}) { | ||||
| 80 | _can_load( 'JSON::PP' => 2.27300 ) | ||||
| 81 | or croak "JSON::PP 2.27300 is not available\n"; | ||||
| 82 | return 'JSON::PP'; | ||||
| 83 | } | ||||
| 84 | if (my $decoder = $ENV{CPAN_META_JSON_DECODER}) { | ||||
| 85 | _can_load( $decoder ) | ||||
| 86 | or croak "Could not load CPAN_META_JSON_DECODER '$decoder'\n"; | ||||
| 87 | $decoder->can('decode_json') | ||||
| 88 | or croak "No decode_json sub provided by CPAN_META_JSON_DECODER '$decoder'\n"; | ||||
| 89 | return $decoder; | ||||
| 90 | } | ||||
| 91 | return $_[0]->json_backend; | ||||
| 92 | } | ||||
| 93 | |||||
| 94 | sub json_backend { | ||||
| 95 | if ($ENV{PERL_CORE}) { | ||||
| 96 | _can_load( 'JSON::PP' => 2.27300 ) | ||||
| 97 | or croak "JSON::PP 2.27300 is not available\n"; | ||||
| 98 | return 'JSON::PP'; | ||||
| 99 | } | ||||
| 100 | if (my $backend = $ENV{CPAN_META_JSON_BACKEND}) { | ||||
| 101 | _can_load( $backend ) | ||||
| 102 | or croak "Could not load CPAN_META_JSON_BACKEND '$backend'\n"; | ||||
| 103 | $backend->can('new') | ||||
| 104 | or croak "No constructor provided by CPAN_META_JSON_BACKEND '$backend'\n"; | ||||
| 105 | return $backend; | ||||
| 106 | } | ||||
| 107 | if (! $ENV{PERL_JSON_BACKEND} or $ENV{PERL_JSON_BACKEND} eq 'JSON::PP') { | ||||
| 108 | _can_load( 'JSON::PP' => 2.27300 ) | ||||
| 109 | or croak "JSON::PP 2.27300 is not available\n"; | ||||
| 110 | return 'JSON::PP'; | ||||
| 111 | } | ||||
| 112 | else { | ||||
| 113 | _can_load( 'JSON' => 2.5 ) | ||||
| 114 | or croak "JSON 2.5 is required for " . | ||||
| 115 | "\$ENV{PERL_JSON_BACKEND} = '$ENV{PERL_JSON_BACKEND}'\n"; | ||||
| 116 | return "JSON"; | ||||
| 117 | } | ||||
| 118 | } | ||||
| 119 | |||||
| 120 | sub _slurp { | ||||
| 121 | require Encode; | ||||
| 122 | open my $fh, "<:raw", "$_[0]" ## no critic | ||||
| 123 | or die "can't open $_[0] for reading: $!"; | ||||
| 124 | my $content = do { local $/; <$fh> }; | ||||
| 125 | $content = Encode::decode('UTF-8', $content, Encode::PERLQQ()); | ||||
| 126 | return $content; | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | sub _can_load { | ||||
| 130 | my ($module, $version) = @_; | ||||
| 131 | (my $file = $module) =~ s{::}{/}g; | ||||
| 132 | $file .= ".pm"; | ||||
| 133 | return 1 if $INC{$file}; | ||||
| 134 | return 0 if exists $INC{$file}; # prior load failed | ||||
| 135 | eval { require $file; 1 } | ||||
| 136 | or return 0; | ||||
| 137 | if ( defined $version ) { | ||||
| 138 | eval { $module->VERSION($version); 1 } | ||||
| 139 | or return 0; | ||||
| 140 | } | ||||
| 141 | return 1; | ||||
| 142 | } | ||||
| 143 | |||||
| 144 | # Kept for backwards compatibility only | ||||
| 145 | # Create an object from a file | ||||
| 146 | sub LoadFile ($) { ## no critic | ||||
| 147 | return Load(_slurp(shift)); | ||||
| 148 | } | ||||
| 149 | |||||
| 150 | # Parse a document from a string. | ||||
| 151 | sub Load ($) { ## no critic | ||||
| 152 | require CPAN::Meta::YAML; | ||||
| 153 | my $object = eval { CPAN::Meta::YAML::Load(shift) }; | ||||
| 154 | croak $@ if $@; | ||||
| 155 | return $object; | ||||
| 156 | } | ||||
| 157 | |||||
| 158 | 1 | 2µs | 1; | ||
| 159 | |||||
| 160 | __END__ |