This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Update Parse-CPAN-Meta to CPAN version 1.4409
[perl5.git] / cpan / Parse-CPAN-Meta / lib / Parse / CPAN / Meta.pm
CommitLineData
342e4710 1use strict;
35df902d 2package Parse::CPAN::Meta;
342e4710 3# ABSTRACT: Parse META.yml and META.json CPAN metadata files
7d7e3722 4our $VERSION = '1.4409'; # VERSION
35df902d 5
35df902d
DM
6use Carp 'croak';
7
8# UTF Support?
9sub HAVE_UTF8 () { $] >= 5.007003 }
a4a5e2bf 10sub IO_LAYER () { $] >= 5.008001 ? ":utf8" : "" }
34d5bd5d 11
35df902d
DM
12BEGIN {
13 if ( HAVE_UTF8 ) {
14 # The string eval helps hide this from Test::MinimumVersion
15 eval "require utf8;";
16 die "Failed to load UTF-8 support" if $@;
17 }
18
19 # Class structure
20 require 5.004;
21 require Exporter;
35df902d
DM
22 @Parse::CPAN::Meta::ISA = qw{ Exporter };
23 @Parse::CPAN::Meta::EXPORT_OK = qw{ Load LoadFile };
24}
25
34d5bd5d
DG
26sub load_file {
27 my ($class, $filename) = @_;
35df902d 28
34d5bd5d
DG
29 if ($filename =~ /\.ya?ml$/) {
30 return $class->load_yaml_string(_slurp($filename));
31 }
35df902d 32
34d5bd5d
DG
33 if ($filename =~ /\.json$/) {
34 return $class->load_json_string(_slurp($filename));
35 }
35df902d 36
34d5bd5d
DG
37 croak("file type cannot be determined by filename");
38}
35df902d 39
34d5bd5d
DG
40sub load_yaml_string {
41 my ($class, $string) = @_;
42 my $backend = $class->yaml_backend();
43 my $data = eval { no strict 'refs'; &{"$backend\::Load"}($string) };
a4a5e2bf 44 if ( $@ ) {
34d5bd5d
DG
45 croak $backend->can('errstr') ? $backend->errstr : $@
46 }
47 return $data || {}; # in case document was valid but empty
48}
49
50sub load_json_string {
51 my ($class, $string) = @_;
52 return $class->json_backend()->new->decode($string);
53}
54
55sub yaml_backend {
56 local $Module::Load::Conditional::CHECK_INC_HASH = 1;
57 if (! defined $ENV{PERL_YAML_BACKEND} ) {
58 _can_load( 'CPAN::Meta::YAML', 0.002 )
59 or croak "CPAN::Meta::YAML 0.002 is not available\n";
60 return "CPAN::Meta::YAML";
61 }
62 else {
63 my $backend = $ENV{PERL_YAML_BACKEND};
64 _can_load( $backend )
65 or croak "Could not load PERL_YAML_BACKEND '$backend'\n";
66 $backend->can("Load")
67 or croak "PERL_YAML_BACKEND '$backend' does not implement Load()\n";
68 return $backend;
69 }
70}
71
72sub json_backend {
73 local $Module::Load::Conditional::CHECK_INC_HASH = 1;
74 if (! $ENV{PERL_JSON_BACKEND} or $ENV{PERL_JSON_BACKEND} eq 'JSON::PP') {
75 _can_load( 'JSON::PP' => 2.27103 )
76 or croak "JSON::PP 2.27103 is not available\n";
77 return 'JSON::PP';
78 }
79 else {
80 _can_load( 'JSON' => 2.5 )
81 or croak "JSON 2.5 is required for " .
82 "\$ENV{PERL_JSON_BACKEND} = '$ENV{PERL_JSON_BACKEND}'\n";
83 return "JSON";
84 }
85}
35df902d 86
34d5bd5d
DG
87sub _slurp {
88 open my $fh, "<" . IO_LAYER, "$_[0]"
89 or die "can't open $_[0] for reading: $!";
90 return do { local $/; <$fh> };
91}
a4a5e2bf 92
34d5bd5d
DG
93sub _can_load {
94 my ($module, $version) = @_;
95 (my $file = $module) =~ s{::}{/}g;
96 $file .= ".pm";
97 return 1 if $INC{$file};
98 return 0 if exists $INC{$file}; # prior load failed
99 eval { require $file; 1 }
100 or return 0;
101 if ( defined $version ) {
102 eval { $module->VERSION($version); 1 }
103 or return 0;
104 }
105 return 1;
106}
35df902d 107
34d5bd5d 108# Kept for backwards compatibility only
35df902d
DM
109# Create an object from a file
110sub LoadFile ($) {
34d5bd5d 111 require CPAN::Meta::YAML;
342e4710 112 my $object = CPAN::Meta::YAML::LoadFile(shift)
34d5bd5d 113 or die CPAN::Meta::YAML->errstr;
342e4710 114 return $object;
35df902d
DM
115}
116
117# Parse a document from a string.
35df902d 118sub Load ($) {
34d5bd5d 119 require CPAN::Meta::YAML;
342e4710 120 my $object = CPAN::Meta::YAML::Load(shift)
34d5bd5d 121 or die CPAN::Meta::YAML->errstr;
342e4710 122 return $object;
34d5bd5d 123}
35df902d 124
34d5bd5d 1251;
35df902d 126
34d5bd5d 127__END__
35df902d 128
34d5bd5d 129=pod
35df902d 130
342e4710
CBW
131=encoding utf-8
132
34d5bd5d 133=head1 NAME
35df902d 134
34d5bd5d 135Parse::CPAN::Meta - Parse META.yml and META.json CPAN metadata files
35df902d 136
342e4710
CBW
137=head1 VERSION
138
7d7e3722 139version 1.4409
342e4710 140
34d5bd5d 141=head1 SYNOPSIS
35df902d 142
34d5bd5d
DG
143 #############################################
144 # In your file
a4a5e2bf 145
34d5bd5d
DG
146 ---
147 name: My-Distribution
148 version: 1.23
149 resources:
150 homepage: "http://example.com/dist/My-Distribution"
a4a5e2bf
CBW
151
152
34d5bd5d
DG
153 #############################################
154 # In your program
a4a5e2bf 155
34d5bd5d 156 use Parse::CPAN::Meta;
a4a5e2bf 157
34d5bd5d 158 my $distmeta = Parse::CPAN::Meta->load_file('META.yml');
a4a5e2bf 159
34d5bd5d
DG
160 # Reading properties
161 my $name = $distmeta->{name};
162 my $version = $distmeta->{version};
163 my $homepage = $distmeta->{resources}{homepage};
35df902d 164
34d5bd5d 165=head1 DESCRIPTION
35df902d 166
34d5bd5d
DG
167B<Parse::CPAN::Meta> is a parser for F<META.json> and F<META.yml> files, using
168L<JSON::PP> and/or L<CPAN::Meta::YAML>.
35df902d 169
34d5bd5d
DG
170B<Parse::CPAN::Meta> provides three methods: C<load_file>, C<load_json_string>,
171and C<load_yaml_string>. These will read and deserialize CPAN metafiles, and
172are described below in detail.
35df902d 173
34d5bd5d
DG
174B<Parse::CPAN::Meta> provides a legacy API of only two functions,
175based on the YAML functions of the same name. Wherever possible,
176identical calling semantics are used. These may only be used with YAML sources.
35df902d 177
34d5bd5d 178All error reporting is done with exceptions (die'ing).
35df902d 179
34d5bd5d
DG
180Note that META files are expected to be in UTF-8 encoding, only. When
181converted string data, it must first be decoded from UTF-8.
35df902d 182
342e4710
CBW
183=for Pod::Coverage HAVE_UTF8 IO_LAYER
184
34d5bd5d 185=head1 METHODS
35df902d 186
34d5bd5d 187=head2 load_file
35df902d 188
34d5bd5d 189 my $metadata_structure = Parse::CPAN::Meta->load_file('META.json');
35df902d 190
34d5bd5d 191 my $metadata_structure = Parse::CPAN::Meta->load_file('META.yml');
35df902d 192
34d5bd5d
DG
193This method will read the named file and deserialize it to a data structure,
194determining whether it should be JSON or YAML based on the filename. On
195Perl 5.8.1 or later, the file will be read using the ":utf8" IO layer.
35df902d 196
34d5bd5d 197=head2 load_yaml_string
35df902d 198
34d5bd5d 199 my $metadata_structure = Parse::CPAN::Meta->load_yaml_string($yaml_string);
35df902d 200
34d5bd5d
DG
201This method deserializes the given string of YAML and returns the first
202document in it. (CPAN metadata files should always have only one document.)
203If the source was UTF-8 encoded, the string must be decoded before calling
204C<load_yaml_string>.
35df902d 205
34d5bd5d 206=head2 load_json_string
35df902d 207
34d5bd5d 208 my $metadata_structure = Parse::CPAN::Meta->load_json_string($json_string);
35df902d 209
a4a5e2bf 210This method deserializes the given string of JSON and the result.
34d5bd5d
DG
211If the source was UTF-8 encoded, the string must be decoded before calling
212C<load_json_string>.
35df902d 213
34d5bd5d 214=head2 yaml_backend
35df902d 215
34d5bd5d
DG
216 my $backend = Parse::CPAN::Meta->yaml_backend;
217
218Returns the module name of the YAML serializer. See L</ENVIRONMENT>
219for details.
220
221=head2 json_backend
222
223 my $backend = Parse::CPAN::Meta->json_backend;
224
225Returns the module name of the JSON serializer. This will either
226be L<JSON::PP> or L<JSON>. Even if C<PERL_JSON_BACKEND> is set,
227this will return L<JSON> as further delegation is handled by
228the L<JSON> module. See L</ENVIRONMENT> for details.
35df902d
DM
229
230=head1 FUNCTIONS
231
34d5bd5d
DG
232For maintenance clarity, no functions are exported. These functions are
233available for backwards compatibility only and are best avoided in favor of
234C<load_file>.
35df902d
DM
235
236=head2 Load
237
34d5bd5d 238 my @yaml = Parse::CPAN::Meta::Load( $string );
35df902d
DM
239
240Parses a string containing a valid YAML stream into a list of Perl data
241structures.
242
243=head2 LoadFile
244
34d5bd5d 245 my @yaml = Parse::CPAN::Meta::LoadFile( 'META.yml' );
35df902d
DM
246
247Reads the YAML stream from a file instead of a string.
248
34d5bd5d
DG
249=head1 ENVIRONMENT
250
251=head2 PERL_JSON_BACKEND
252
253By default, L<JSON::PP> will be used for deserializing JSON data. If the
254C<PERL_JSON_BACKEND> environment variable exists, is true and is not
255"JSON::PP", then the L<JSON> module (version 2.5 or greater) will be loaded and
256used to interpret C<PERL_JSON_BACKEND>. If L<JSON> is not installed or is too
257old, an exception will be thrown.
258
259=head2 PERL_YAML_BACKEND
260
261By default, L<CPAN::Meta::YAML> will be used for deserializing YAML data. If
342e4710 262the C<PERL_YAML_BACKEND> environment variable is defined, then it is interpreted
34d5bd5d
DG
263as a module to use for deserialization. The given module must be installed,
264must load correctly and must implement the C<Load()> function or an exception
265will be thrown.
266
342e4710
CBW
267=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
268
35df902d
DM
269=head1 SUPPORT
270
342e4710
CBW
271=head2 Bugs / Feature Requests
272
273Please report any bugs or feature requests through the issue tracker
545c8cda 274at L<http://rt.cpan.org/Public/Dist/Display.html?Name=Parse-CPAN-Meta>.
342e4710
CBW
275You will be notified automatically of any progress on your issue.
276
277=head2 Source Code
278
279This is open source software. The code repository is available for
280public review and contribution under the terms of the license.
281
545c8cda 282L<https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta>
35df902d 283
545c8cda 284 git clone https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta.git
35df902d 285
545c8cda
SH
286=head1 AUTHORS
287
288=over 4
289
290=item *
35df902d 291
342e4710
CBW
292Adam Kennedy <adamk@cpan.org>
293
545c8cda
SH
294=item *
295
296David Golden <dagolden@cpan.org>
297
298=back
299
342e4710
CBW
300=head1 CONTRIBUTORS
301
302=over 4
303
304=item *
305
545c8cda 306Joshua ben Jore <jjore@cpan.org>
342e4710
CBW
307
308=item *
309
545c8cda 310Neil Bowers <neil@bowers.com>
342e4710
CBW
311
312=item *
313
7d7e3722 314Ricardo Signes <rjbs@cpan.org>
342e4710
CBW
315
316=item *
317
7d7e3722 318Steffen Mueller <smueller@cpan.org>
35df902d 319
342e4710 320=back
35df902d 321
342e4710 322=head1 COPYRIGHT AND LICENSE
35df902d 323
342e4710 324This software is copyright (c) 2013 by Adam Kennedy and Contributors.
35df902d 325
342e4710
CBW
326This is free software; you can redistribute it and/or modify it under
327the same terms as the Perl 5 programming language system itself.
35df902d
DM
328
329=cut