CPAN-Meta-2.150005/000755 000765 000024 00000000000 12535707053 013614 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/Changes000644 000765 000024 00000035715 12535707053 015122 0ustar00davidstaff000000 000000 Revision history for CPAN-Meta 2.150005 2015-06-09 19:08:44-06:00 America/Denver [TESTING] - Changed some test data from UTF-8 to ASCII 2.150004 2015-05-19 11:25:53-04:00 America/New_York (TRIAL RELEASE) [DOCUMENTED] - Noted explicitly that historical META spec files are licensed under the same terms as Perl [TESTING] - Added test for 'x_deprecated' field in "provides" [META] - declared extra developer prereq 2.150003 2015-04-21 19:41:15-04:00 America/New_York (TRIAL RELEASE) [CHANGED] - Serialized CPAN::Meta objects now include a x_serialization_backend entry 2.150002 2015-04-19 01:00:10+02:00 Europe/Berlin (TRIAL RELEASE) [CHANGED] - Metadata merging now does deep hash merging as long as keys don't conflict 2.150001 2015-03-09 14:41:39-04:00 America/New_York [DOCUMENTED] - Include allowed values for license field in 1.x historic licenses rather than linking to Module::Build - Documented when fragment merging became available 2.143240 2014-11-20 10:26:30-05:00 America/New_York [FIXED] - Give correct path in nested merges such as resources - Removed strings test that should have been removed when CPAN::Meta::Requirements was removed to a separate dist 2.142690 2014-09-26 11:06:34-04:00 America/New_York [FIXED] - Fixed use of incorrect method in CPAN::Meta::Merge implementation [DOCUMENTED] - Clarified that no_index is a list of exclusions, and that indexers should generally exclude 'inc', 'xt' and 't' as well. - CPAN::Meta::History::Meta_1_0 through 1_4 are added as a permanent record of 1.x versions of the metaspec 2.142060 2014-07-25 13:30:06-04:00 America/New_York [ADDED] - CPAN::Meta::Merge is a new class for merging two possibly overlapping instances of metadata. It will accept both CPAN::Meta objects and (possibly incomplete) hashrefs of metadata. 2.141520 2014-05-31 23:41:13-04:00 America/New_York [DOCUMENTED] - Clarified use of 'file' for the 'provides' field in the Spec 2.141170 2014-04-27 13:03:37-04:00 America/New_York [ADDED] - Added ability for CPAN::Meta::Converter to convert metadata fragments (incomplete portions of a metadata structure) [CHANGED] - Optimized internal use of JSON for datastructure cloning [FIXED] - Removed dependency on List::Util 1.33 [DOCUMENTED] - Clarified language around 'dynamic_config' in the Spec 2.140640 2014-03-05 09:07:05-05:00 America/New_York [FIXED] - A change to the default meta-spec URL in 2.140630 from search.cpan.org to metacpan.org broke Module::Build and ExtUtils::MakeMaker. This reverts that change. Also added the missing change note to the prior version. 2.140630 2014-03-04 15:23:40-05:00 America/New_York [CHANGED] - Default meta-spec URL points to metacpan.org instead of search.cpan.org [ADDED] - Added a 'load_string' method that guesses whether the string is YAML or JSON 2.133380 2013-12-03 23:01:07 America/New_York [FIXED] - Improved bad version handling during META conversion - When downgrading multiple licenses to version 1.x META formats, if all the licenses are open source, the downgraded license will be "open_source", not "unknown" 2.132830 2013-10-10 16:04:30 America/New_York [ADDED] - CPAN::Meta::Prereqs now has a 'merged_requirements' method for combining requirements across multiple phases and types [FIXED] - Invalid 'meta-spec' is no longer a fatal error: instead, it will usually be treated as spec version "1.0" (prior to formalization of the meta-spec field). Conversion has some heuristics for guessing a version depending on other fields if 'meta-spec' is missing or invalid. 2.132661 2013-09-23 13:27:46 America/New_York [FIXED] - updated Makefile.PL logic to support PERL_NO_HIGHLANDER [PREREQS] - Dropped ExtUtils::MakeMaker configure_requires dependency to 6.17 2.132660 2013-09-23 06:04:04 America/New_York [FIXED] - Installation on Perls < 5.12 will uninstall older versions installed due to being bundled with ExtUtils::MakeMaker 2.132620 2013-09-19 11:18:33 America/New_York [CHANGED] - META validation used to allow a scalar value when a list (i.e. array reference) was required for a field. This has been tightened and validation will now fail if a scalar value is given. Conversion will continue to turn scalars into an array reference as it previously did. 2.132510 2013-09-08 10:17:29 America/New_York [FIXED] - Fixed incorrectly encoded META.yml 2.132140 2013-08-02 11:54:17 America/New_York [DOCUMENTATION] - Fixed some typos in CPAN::Meta::Spec [OTHER] - migrated repository to Perl-Toolchain-Gang organization on Github and updated metadata accordingly 2.131560 2013-06-05 15:26:36 America/New_York [DOCUMENTATION] - Replaced CPAN::Meta SYNOPSIS with code that actually works 2.131490 2013-05-29 14:15:16 America/New_York [BUGFIX] - Downconversion of custom resources was not dropping the leading "x_". Now "x_MailingList" will downconvert correctly to "MailingList". [SPEC] - Per the Lancaster Consensus, the 'file' subkey of a package listed in 'provides' must refer to an actual file in the distribution, either the .pm file that provides the package or another file (*.PL) that generates it 2.130880 2013-03-29 09:51:00 America/New_York [BUGFIX] - Fix provides 'version' bug introduced in the 2.130870 fix 2.130870 2013-03-28 11:08:50 America/New_York [BUGFIX] - Don't add 'version' to 'provides' during conversion if one didn't exist in the original [Reported by Miyagawa; fixed by David Golden] 2.120921 2012-04-01 15:20:24 Europe/Paris [REMOVED] - CPAN::Meta::Requirements has been split out into its own distribution so it can be used by CPAN.pm without requiring all of CPAN::Meta 2.120920 2012-04-01 11:30:43 Europe/Paris [ADDED] - CPAN::Meta::Requirements now has a 'requirements_for_module' method to retrieve a version requirements string for a specific module [Leon Timmermans] [OTHER] - Parse::CPAN::Meta prerequisite bumped to 1.4403 - JSON::PP prerequisites bumped to 2.27200 - CPAN::Meta::YAML prerequisite bumped to 0.008 2.120900 2012-03-30 13:15:15 Europe/Paris [BUGFIX] - CPAN::Meta::Requirements now treats undef requirements given to from_string_hash() as '0' and warns about it; add_string_requirements() dies if it does not get a requirements string to parse 2.120630 2012-03-03 14:48:35 EST5EDT [BUGFIX] - CPAN::Meta::Requirements now ensures that dotted-decimal versions are represented in normalized form when stringified. This fixes a regression in META conversion in 2.120620. [Reported by Kent Fredric; fixed by David Golden] 2.120620 2012-03-02 12:28:59 EST5EDT [ADDED] - CPAN::Meta::Requirements::add_string_requirements allows building a requirements specification piecemeal [Cory G. Watson] [BUGFIX] - Version range handling fixed [rt.cpan.org #75424] - CPAN::Meta::Converter handles bad version strings more gracefully, truncating alphanumerics and otherwise falling back to "0". This is likely better than dropping a prerequisite or dying. [rt.cpan.org #75427] 2.120530 2012-02-22 16:15:31 EST5EDT [OTHER] - Dialed back perl prereq to 5.006 2.120351 2012-02-03 23:01:45 America/New_York [OTHER] - Fixed CPAN packaging errors 2.120350 2012-02-03 22:46:59 America/New_York [BUGFIX] - Work around a memory leak bug involving version objects in boolean context. 2.113640 2011-12-30 15:19:46 America/New_York [OTHER] - Version::Requirements has now been merged as CPAN::Meta::Requirements, rendering Version::Requirements itself redundant 2.112621 2011-09-19 12:15:16 America/New_York [BUGFIX] - Spell BACKEND environment variables correctly this time [noticed by Stevan Little] 2.112620 2011-09-18 20:56:06 America/New_York [BUGFIX] - Protect tests against PERL_(YAML|JSON)_BACKEND settings that could cause tests to fail. (RT #69979) 2.112600 2011-09-17 12:21:09 America/New_York [DOCUMENTATION] - Fixed spelling error in CPAN::Meta::Spec (RT #71036) [Gregor Hermann] 2.112580 2011-09-15 10:53:59 America/New_York [BUGFIX] - Use UTF-8 mode for internal structure cloning to avoid bugs in Perl <= 5.8.6 (RT #70936) [Dagfinn Ilmari Mannsåker] 2.112150 2011-08-02 22:25:41 America/New_York [BUGFIX] - Stringify any objects encountered during conversion. (RT #67295) - Fixed some broken URLs in documentation and for LGPL in legacy conversion (RT #68738) - Fixed invalid private Pod in CPAN::Meta::Validator (RT #65925) [SPEC] - Clarified that file paths in the 'provides' section must be in Unix-style (i.e. forward slashes) (RT #69045) - Replaced examples using Module::Build::ModuleInfo with Module::Metadata (RT #66135) 2.110930 2011-04-02 23:31:24 America/New_York [BUGFIX] - Fixed a bug in the 'as_string' method that checked the module version instead of the meta-spec version when conversion was requested (RT #67188) 2.110910 2011-04-01 08:55:30 America/New_York [ENHANCEMENTS] - The 1.x spec "gpl" and "lgpl" and "mozilla" license values now up-convert to "open_source" because they indicate too non-specific a license. 2.110580 2011-02-27 07:58:06 EST5EDT [OTHER] - Add explicit dependencies on JSON::PP and CPAN::Meta::YAML instead of relying on Parse::CPAN::Meta to provide them (as some CPAN Testers have had P::C::M installed without them somehow) - Removed dependency on Storable as it was not a core module until Perl 5.8 2.110550 2011-02-24 07:17:57 EST5EDT [OTHER] - Added required field 'release_status' to the synopsis of CPAN::Meta::Spec (RT#66118) [Oliver Mengué] 2.110540 2011-02-23 15:21:16 EST5EDT [BUGFIX] - Had two different Parse::CPAN::Meta requirements, one in 'requires' and the other in 'build_requires'. This confused some installers, so we only inlude the 'requires' now. 2.110440 2011-02-12 22:55:28 EST5EDT [BUGFIX] - Bump Parse::CPAN::Meta prereq to 1.44, as 1.43 was never released 2.110420 2011-02-11 15:40:36 EST5EDT [BUG FIXES] - The as_string() method now always returns a character string; previously, JSON strings were UTF-8 encoded. - The save() method now always saves with UTF-8 encoding for Perl 5.8.1 or greater; previously, YAML was not encoded 2.110390 2011-02-07 21:00:47 EST5EDT [BUG FIXES] - Release 2.110360 had a regression where the save() method would no longer return true on success. That has been fixed. 2.110360 2011-02-04 19:46:21 America/New_York [OTHER] - Remove autodie dependency so CPAN::Meta can be used on older Perls - Remove unused Data::Dumper dependency 2.110350 2011-02-03 19:57:32 America/New_York [ENHANCEMENTS] - Added "as_string" method similar to "as_struct" [OTHER] - Bumped Parse::CPAN::Meta prereq to 1.43 and uses that to determine proper YAML/JSON backends - Removed unused prereqs 2.110330 2011-02-02 09:42:57 EST5EDT [ENHANCEMENTS] - Saved META.json files are now sorted by key - as_struct() method takes an optional "version" argument to return a down-converted metadata hashref 2.110320 2011-01-31 23:14:30 EST5EDT [ENHANCEMENTS] - The 'save' method now allows an optional hashref argument, which can be used to set the desired meta spec version. Metadata is automatically converted to the specified output. 2.110240 2011-01-24 16:28:25 EST5EDT - Reading JSON/YAML is delegated entirely to Parse::CPAN::Meta (1.4200) - JSON.pm is dropped as a prerequisite and JSON::PP is added to prepare for CPAN::Meta to be added to the Perl core - JSON writing uses the same JSON backend selection as Parse::CPAN::Meta to allow "upgrading" to a non-core JSON backend module if desired 2.102400 2010-08-28 14:06:34 America/New_York - 'as_struct' method now returns unblessed data (reported by Chris Prather) 2.102160 2010-08-04 12:27:10 EST5EDT - Fix bugtracker conversion bug (RT#60017) 2.101670 2010-06-15 21:02:42 EST5EDT - converting 1.x 'repository' field now puts converted url into the 'url' sub-field of 'repository' instead of the 'web' sub-field 2.101610 2010-06-10 18:51:30 EST5EDT - fixed converter bug that output 'artistic2' instead of 'artistic_2' for license in 1.X specs - 'artistic2' is now converted to 'artistic_2' if it occurs - corrected validation for 'artistic_2' and disallowed 'artistic-2.0' 2.101600 2010-06-09 10:07:31 EST5EDT - improve conversion of restricted/restrictive license keys between spec versions 1.4 and 2 [reported by Alexander Hartmaier] 2.101591 2010-06-08 09:56:17 EST5EDT - added 'as_struct' method to CPAN::Meta to get a deep copy of the metadata hash_ref - won't add an optional_features 'description' field if missing - improved documentation of CPAN::Meta::Converter and how it deals with bad/missing data 2.101590 2010-06-07 21:49:36 EST5EDT - won't automatically add 'unknown' as repository type when converting; instead, will only add a repository type if a repository 'url' is present and it is of the 'svn:' or 'git:' scheme. - squelched some uninitialized value warnings [Graham Barr] 2.101580 2010-06-07 16:44:13 EST5EDT - add "lazy_validation" option to constructors - add ability to "convert" to same version and clean-up any fixable errors - fix validation bugs (adhere closer to the spec) - improve lots of heuristics during conversion 2.101461 2010-05-26 16:57:02 America/New_York - accessors deep clone list and map keys before returning them - add custom_keys() and custom() methods 2.101460 2010-05-25 23:12:27 America/New_York - loosen URL validation -- only a scheme and authority are required without restrictions on either 2.101450 2010-05-25 17:59:32 America/New_York - when downconverting from 2, leave custom keys unchanged (except in resources, where x_ is changed to X_) - when converting to 2, don't prepend x_ to custom keys that already matched qr{\Ax_}i 2.101410 2010-05-21 10:39:18 EST5EDT - when downconverting from 2, merge test requirements into build requirements 2.101390 2010-05-19 10:49:50 EST5EDT - do not clobber generated_by when converting 2.101380 2010-05-17 23:39:23 EST5EDT - added support for down-converting to older versions of the spec - improved test coverage for conversion and validation 2.101110 2010-04-21 11:06:52 EST5EDT - clarified that .XXXXXX versions of the CPAN-Meta distribution will not change the meaning of the CPAN::Meta::Spec, but may fix typos or clarify prose - fixed a typo regarding dotted-integer versions: keeping components in the range 0-999 was corrected to a "should" instead of a "must" - fixed validation bugs for certain types of nested data structures (based on a patch provided by Barbie) 2.101091 2010-04-19 06:32:13 EST5EDT - keep the old specs from getting indexed so as not to confuse people # vim: ts=2 sts=2 sw=2 et: CPAN-Meta-2.150005/CONTRIBUTING.mkdn000644 000765 000024 00000005751 12535707053 016406 0ustar00davidstaff000000 000000 ## HOW TO CONTRIBUTE Thank you for considering contributing to this distribution. This file contains instructions that will help you work with the source code. The distribution is managed with Dist::Zilla. This means than many of the usual files you might expect are not in the repository, but are generated at release time, as is much of the documentation. Some generated files are kept in the repository as a convenience (e.g. Makefile.PL or cpanfile). Generally, **you do not need Dist::Zilla to contribute patches**. You do need Dist::Zilla to create a tarball. See below for guidance. ### Getting dependencies If you have App::cpanminus 1.6 or later installed, you can use `cpanm` to satisfy dependencies like this: $ cpanm --installdeps . Otherwise, look for either a `Makefile.PL` or `cpanfile` file for a list of dependencies to satisfy. ### Running tests You can run tests directly using the `prove` tool: $ prove -l $ prove -lv t/some_test_file.t For most of my distributions, `prove` is entirely sufficient for you to test any patches you have. I use `prove` for 99% of my testing during development. ### Code style and tidying Please try to match any existing coding style. If there is a `.perltidyrc` file, please install Perl::Tidy and use perltidy before submitting patches. If there is a `tidyall.ini` file, you can also install Code::TidyAll and run `tidyall` on a file or `tidyall -a` to tidy all files. ### Patching documentation Much of the documentation Pod is generated at release time. Some is generated boilerplate; other documentation is built from pseudo-POD directives in the source like C<=method> or C<=func>. If you would like to submit a documentation edit, please limit yourself to the documentation you see. If you see typos or documentation issues in the generated docs, please email or open a bug ticket instead of patching. ### Installing and using Dist::Zilla Dist::Zilla is a very powerful authoring tool, optimized for maintaining a large number of distributions with a high degree of automation, but it has a large dependency chain, a bit of a learning curve and requires a number of author-specific plugins. To install it from CPAN, I recommend one of the following approaches for the quickest installation: # using CPAN.pm, but bypassing non-functional pod tests $ cpan TAP::Harness::Restricted $ PERL_MM_USE_DEFAULT=1 HARNESS_CLASS=TAP::Harness::Restricted cpan Dist::Zilla # using cpanm, bypassing *all* tests $ cpanm -n Dist::Zilla In either case, it's probably going to take about 10 minutes. Go for a walk, go get a cup of your favorite beverage, take a bathroom break, or whatever. When you get back, Dist::Zilla should be ready for you. Then you need to install any plugins specific to this distribution: $ cpan `dzil authordeps` $ dzil authordeps | cpanm Once installed, here are some dzil commands you might try: $ dzil build $ dzil test $ dzil xtest You can learn more about Dist::Zilla at http://dzil.org/ CPAN-Meta-2.150005/cpanfile000644 000765 000024 00000003356 12535707053 015327 0ustar00davidstaff000000 000000 requires "CPAN::Meta::Requirements" => "2.121"; requires "CPAN::Meta::YAML" => "0.008"; requires "Carp" => "0"; requires "JSON::PP" => "2.27200"; requires "Parse::CPAN::Meta" => "1.4414"; requires "Scalar::Util" => "0"; requires "perl" => "5.008"; requires "strict" => "0"; requires "version" => "0.88"; requires "warnings" => "0"; on 'test' => sub { requires "Data::Dumper" => "0"; requires "ExtUtils::MakeMaker" => "0"; requires "File::Basename" => "0"; requires "File::Spec" => "0"; requires "File::Temp" => "0.20"; requires "IO::Dir" => "0"; requires "Test::More" => "0.88"; requires "overload" => "0"; requires "perl" => "5.008"; requires "utf8" => "0"; }; on 'test' => sub { recommends "CPAN::Meta" => "2.120900"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "6.17"; requires "perl" => "5.006"; }; on 'develop' => sub { requires "Dist::Zilla" => "5"; requires "Dist::Zilla::Plugin::Encoding" => "0"; requires "Dist::Zilla::Plugin::MakeMaker::Highlander" => "0.003"; requires "Dist::Zilla::Plugin::OnlyCorePrereqs" => "0.014"; requires "Dist::Zilla::Plugin::Prereqs" => "0"; requires "Dist::Zilla::Plugin::SurgicalPodWeaver" => "0.0021"; requires "Dist::Zilla::PluginBundle::DAGOLDEN" => "0.070"; requires "File::Spec" => "0"; requires "File::Temp" => "0"; requires "IO::Handle" => "0"; requires "IPC::Open3" => "0"; requires "Pod::Coverage::TrustPod" => "0"; requires "Test::CPAN::Meta" => "0"; requires "Test::More" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Spelling" => "0.12"; requires "Test::Version" => "1"; }; on 'develop' => sub { recommends "Perl::Critic::Policy::Lax::ProhibitStringyEval::ExceptForRequire" => "0"; }; CPAN-Meta-2.150005/dist.ini000644 000765 000024 00000003121 12535707053 015255 0ustar00davidstaff000000 000000 name = CPAN-Meta author = David Golden author = Ricardo Signes license = Perl_5 copyright_holder = David Golden and Ricardo Signes copyright_year = 2010 ; set these to bytes to make MinimumPerl skip them [Encoding] encoding = bytes match = ^t/data- [@DAGOLDEN] :version = 0.070 -remove = PodWeaver authority = cpan:DAGOLDEN no_minimum_perl = 1 tag_format = %v version_regex = ^(\d+\.\d{6})$ ; AutoVersion style AutoVersion.major = 2 GithubMeta.user = Perl-Toolchain-Gang MetaNoIndex.directory[] = history MakeMaker.eumm_version = 6.17 ; as shipped with 5.8.1 stopwords = apache stopwords = bsd stopwords = dir stopwords = distmeta stopwords = dists stopwords = gpl stopwords = lgpl stopwords = mailto stopwords = metacpan stopwords = mit stopwords = mozilla stopwords = releaser stopwords = subkey stopwords = subkeys [SurgicalPodWeaver] :version = 0.0021 config_plugin = @DAGOLDEN replacer = replace_with_comment post_code_replacer = replace_with_nothing ; repeat these from Parse::CPAN::Meta to ensure we don't wind up ; with P::C::M installed but the backends not installed (as seen in ; some CPAN Testers FAILS) for some reason. Also, add in version.pm ; as we'd like 0.88, even though we'll try to cope with older versions ; in the code [Prereqs] perl = 5.006 JSON::PP = 2.27200 CPAN::Meta::YAML = 0.008 version = 0.88 [Prereqs / DevelopRecommends] Perl::Critic::Policy::Lax::ProhibitStringyEval::ExceptForRequire = 0 [OnlyCorePrereqs] :version = 0.014 check_dual_life_versions = 0 ; EU::MM bundled prereqs need this [MakeMaker::Highlander] :version = 0.003 CPAN-Meta-2.150005/history/000755 000765 000024 00000000000 12535707053 015315 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/lib/000755 000765 000024 00000000000 12535707053 014362 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/LICENSE000644 000765 000024 00000043746 12535707053 014637 0ustar00davidstaff000000 000000 This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2010 by David Golden and Ricardo Signes. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2010 by David Golden and Ricardo Signes. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End CPAN-Meta-2.150005/Makefile.PL000644 000765 000024 00000004232 12535707053 015567 0ustar00davidstaff000000 000000 # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.037. use strict; use warnings; use 5.008; use ExtUtils::MakeMaker 6.17; my %WriteMakefileArgs = ( "ABSTRACT" => "the distribution metadata for a CPAN dist", "AUTHOR" => "David Golden , Ricardo Signes ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => "6.17" }, "DISTNAME" => "CPAN-Meta", "EXE_FILES" => [], "LICENSE" => "perl", "MIN_PERL_VERSION" => "5.008", "NAME" => "CPAN::Meta", "PREREQ_PM" => { "CPAN::Meta::Requirements" => "2.121", "CPAN::Meta::YAML" => "0.008", "Carp" => 0, "JSON::PP" => "2.27200", "Parse::CPAN::Meta" => "1.4414", "Scalar::Util" => 0, "strict" => 0, "version" => "0.88", "warnings" => 0 }, "TEST_REQUIRES" => { "Data::Dumper" => 0, "ExtUtils::MakeMaker" => 0, "File::Basename" => 0, "File::Spec" => 0, "File::Temp" => "0.20", "IO::Dir" => 0, "Test::More" => "0.88", "overload" => 0, "utf8" => 0 }, "VERSION" => "2.150005", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "CPAN::Meta::Requirements" => "2.121", "CPAN::Meta::YAML" => "0.008", "Carp" => 0, "Data::Dumper" => 0, "ExtUtils::MakeMaker" => "6.17", "File::Basename" => 0, "File::Spec" => 0, "File::Temp" => "0.20", "IO::Dir" => 0, "JSON::PP" => "2.27200", "Parse::CPAN::Meta" => "1.4414", "Scalar::Util" => 0, "Test::More" => "0.88", "overload" => 0, "strict" => 0, "utf8" => 0, "version" => "0.88", "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; # Added by Dist::Zilla::Plugin::MakeMaker::Highlander if ( $] < 5.012 && ! $ENV{PERL_NO_HIGHLANDER} && ! ( $ENV{PERL_MM_OPT} && $ENV{PERL_MM_OPT} =~ /(?:INSTALL_BASE|PREFIX)/ ) && ! grep { /INSTALL_BASE/ || /PREFIX/ } @ARGV ) { $WriteMakefileArgs{UNINST} = 1; } WriteMakefile(%WriteMakefileArgs); CPAN-Meta-2.150005/MANIFEST000644 000765 000024 00000005372 12535707053 014754 0ustar00davidstaff000000 000000 # This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.037. CONTRIBUTING.mkdn Changes LICENSE MANIFEST META.json META.yml Makefile.PL README Todo cpanfile dist.ini history/META-spec-1_0.html history/META-spec-1_1.html history/META-spec-1_2.pod history/META-spec-1_3.pod history/META-spec-1_4.pod lib/CPAN/Meta.pm lib/CPAN/Meta/Converter.pm lib/CPAN/Meta/Feature.pm lib/CPAN/Meta/History.pm lib/CPAN/Meta/History/Meta_1_0.pod lib/CPAN/Meta/History/Meta_1_1.pod lib/CPAN/Meta/History/Meta_1_2.pod lib/CPAN/Meta/History/Meta_1_3.pod lib/CPAN/Meta/History/Meta_1_4.pod lib/CPAN/Meta/Merge.pm lib/CPAN/Meta/Prereqs.pm lib/CPAN/Meta/Spec.pm lib/CPAN/Meta/Validator.pm perlcritic.rc t/00-report-prereqs.dd t/00-report-prereqs.t t/README-data.txt t/converter-bad.t t/converter-fail.t t/converter-fragments.t t/converter.t t/data-fail/META-1_0.yml t/data-fail/META-1_1.yml t/data-fail/META-1_2.yml t/data-fail/META-1_3.yml t/data-fail/META-1_4.yml t/data-fail/META-2.json t/data-fixable/107650337-META.yml t/data-fixable/1598804075-META.yml t/data-fixable/1927486199-META.yml t/data-fixable/1985980974-META.yml t/data-fixable/2031017050-META.yml t/data-fixable/284247103-META.yml t/data-fixable/344981821-META.yml t/data-fixable/35478989-META.yml t/data-fixable/98042513-META.yml t/data-fixable/META-1_2.yml t/data-fixable/META-1_3.yml t/data-fixable/META-1_4.yml t/data-fixable/META-2.json t/data-fixable/invalid-meta-spec-version.json t/data-fixable/invalid-meta-spec-version.yml t/data-fixable/meta-spec-version-trailing-zeros.json t/data-fixable/meta-spec-version-trailing-zeros.yml t/data-fixable/restrictive-2.json t/data-fixable/version-ranges-2.json t/data-test/META-1_0.yml t/data-test/META-1_1.yml t/data-test/META-1_2.yml t/data-test/META-1_3.yml t/data-test/META-1_4.yml t/data-test/META-2.json t/data-test/META-2.meta t/data-test/gpl-1_4.yml t/data-test/preserve-release-status.yml t/data-test/provides-version-missing.json t/data-test/resources.yml t/data-test/restricted-2.json t/data-test/restrictive-1_4.yml t/data-test/unicode.yml t/data-test/version-not-normal.json t/data-test/version-ranges-1_4.yml t/data-test/version-ranges-2.json t/data-test/x_deprecated-META.json t/data-valid/1122575719-META.yml t/data-valid/1206545041-META.yml t/data-valid/1985684504-META.yml t/data-valid/476602558-META.yml t/data-valid/META-1_0.yml t/data-valid/META-1_1.yml t/data-valid/scalar-meta-spec.yml t/data-valid/x_deprecated-META.yml t/load-bad.t t/merge.t t/meta-obj.t t/no-index.t t/optional_feature-merge.t t/prereqs-finalize.t t/prereqs-merge.t t/prereqs.t t/repository.t t/save-load.t t/validator.t xt/author/00-compile.t xt/author/critic.t xt/author/pod-spell.t xt/release/distmeta.t xt/release/pod-coverage.t xt/release/pod-syntax.t xt/release/portability.t xt/release/test-version.t CPAN-Meta-2.150005/META.json000644 000765 000024 00000012125 12535707053 015236 0ustar00davidstaff000000 000000 { "abstract" : "the distribution metadata for a CPAN dist", "author" : [ "David Golden ", "Ricardo Signes " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.037, CPAN::Meta::Converter version 2.150001", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "CPAN-Meta", "no_index" : { "directory" : [ "t", "xt", "examples", "corpus", "history" ], "package" : [ "DB" ] }, "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.17", "perl" : "5.006" } }, "develop" : { "recommends" : { "Perl::Critic::Policy::Lax::ProhibitStringyEval::ExceptForRequire" : "0" }, "requires" : { "Dist::Zilla" : "5", "Dist::Zilla::Plugin::Encoding" : "0", "Dist::Zilla::Plugin::MakeMaker::Highlander" : "0.003", "Dist::Zilla::Plugin::OnlyCorePrereqs" : "0.014", "Dist::Zilla::Plugin::Prereqs" : "0", "Dist::Zilla::Plugin::SurgicalPodWeaver" : "0.0021", "Dist::Zilla::PluginBundle::DAGOLDEN" : "0.070", "File::Spec" : "0", "File::Temp" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "Pod::Coverage::TrustPod" : "0", "Test::CPAN::Meta" : "0", "Test::More" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", "Test::Spelling" : "0.12", "Test::Version" : "1" } }, "runtime" : { "requires" : { "CPAN::Meta::Requirements" : "2.121", "CPAN::Meta::YAML" : "0.008", "Carp" : "0", "JSON::PP" : "2.27200", "Parse::CPAN::Meta" : "1.4414", "Scalar::Util" : "0", "perl" : "5.008", "strict" : "0", "version" : "0.88", "warnings" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "Data::Dumper" : "0", "ExtUtils::MakeMaker" : "0", "File::Basename" : "0", "File::Spec" : "0", "File::Temp" : "0.20", "IO::Dir" : "0", "Test::More" : "0.88", "overload" : "0", "perl" : "5.008", "utf8" : "0" } } }, "provides" : { "CPAN::Meta" : { "file" : "lib/CPAN/Meta.pm", "version" : "2.150005" }, "CPAN::Meta::Converter" : { "file" : "lib/CPAN/Meta/Converter.pm", "version" : "2.150005" }, "CPAN::Meta::Feature" : { "file" : "lib/CPAN/Meta/Feature.pm", "version" : "2.150005" }, "CPAN::Meta::History" : { "file" : "lib/CPAN/Meta/History.pm", "version" : "2.150005" }, "CPAN::Meta::Merge" : { "file" : "lib/CPAN/Meta/Merge.pm", "version" : "2.150005" }, "CPAN::Meta::Prereqs" : { "file" : "lib/CPAN/Meta/Prereqs.pm", "version" : "2.150005" }, "CPAN::Meta::Spec" : { "file" : "lib/CPAN/Meta/Spec.pm", "version" : "2.150005" }, "CPAN::Meta::Validator" : { "file" : "lib/CPAN/Meta/Validator.pm", "version" : "2.150005" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues" }, "homepage" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta", "repository" : { "type" : "git", "url" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git", "web" : "https://github.com/Perl-Toolchain-Gang/CPAN-Meta" } }, "version" : "2.150005", "x_authority" : "cpan:DAGOLDEN", "x_contributors" : [ "Ansgar Burchardt ", "Avar Arnfjord Bjarmason ", "Christopher J. Madsen ", "Chuck Adams ", "Cory G Watson ", "Damyan Ivanov ", "Eric Wilhelm ", "Graham Knop ", "Gregor Hermann ", "Karen Etheridge ", "Kenichi Ishigaki ", "Ken Williams ", "Lars Dieckow ", "Leon Timmermans ", "majensen ", "Mark Fowler ", "Matt S Trout ", "Michael G. Schwern ", "mohawk2 ", "moznion ", "Niko Tyni ", "Olaf Alders ", "Olivier Mengué ", "Randy Sims ", "Tomohiro Hosaka " ] } CPAN-Meta-2.150005/META.yml000644 000765 000024 00000005473 12535707053 015076 0ustar00davidstaff000000 000000 --- abstract: 'the distribution metadata for a CPAN dist' author: - 'David Golden ' - 'Ricardo Signes ' build_requires: Data::Dumper: '0' ExtUtils::MakeMaker: '0' File::Basename: '0' File::Spec: '0' File::Temp: '0.20' IO::Dir: '0' Test::More: '0.88' overload: '0' perl: '5.008' utf8: '0' configure_requires: ExtUtils::MakeMaker: '6.17' perl: '5.006' dynamic_config: 0 generated_by: 'Dist::Zilla version 5.037, CPAN::Meta::Converter version 2.150001' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: CPAN-Meta no_index: directory: - t - xt - examples - corpus - history package: - DB provides: CPAN::Meta: file: lib/CPAN/Meta.pm version: '2.150005' CPAN::Meta::Converter: file: lib/CPAN/Meta/Converter.pm version: '2.150005' CPAN::Meta::Feature: file: lib/CPAN/Meta/Feature.pm version: '2.150005' CPAN::Meta::History: file: lib/CPAN/Meta/History.pm version: '2.150005' CPAN::Meta::Merge: file: lib/CPAN/Meta/Merge.pm version: '2.150005' CPAN::Meta::Prereqs: file: lib/CPAN/Meta/Prereqs.pm version: '2.150005' CPAN::Meta::Spec: file: lib/CPAN/Meta/Spec.pm version: '2.150005' CPAN::Meta::Validator: file: lib/CPAN/Meta/Validator.pm version: '2.150005' requires: CPAN::Meta::Requirements: '2.121' CPAN::Meta::YAML: '0.008' Carp: '0' JSON::PP: '2.27200' Parse::CPAN::Meta: '1.4414' Scalar::Util: '0' perl: '5.008' strict: '0' version: '0.88' warnings: '0' resources: bugtracker: https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues homepage: https://github.com/Perl-Toolchain-Gang/CPAN-Meta repository: https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git version: '2.150005' x_authority: cpan:DAGOLDEN x_contributors: - 'Ansgar Burchardt ' - 'Avar Arnfjord Bjarmason ' - 'Christopher J. Madsen ' - 'Chuck Adams ' - 'Cory G Watson ' - 'Damyan Ivanov ' - 'Eric Wilhelm ' - 'Graham Knop ' - 'Gregor Hermann ' - 'Karen Etheridge ' - 'Kenichi Ishigaki ' - 'Ken Williams ' - 'Lars Dieckow ' - 'Leon Timmermans ' - 'majensen ' - 'Mark Fowler ' - 'Matt S Trout ' - 'Michael G. Schwern ' - 'mohawk2 ' - 'moznion ' - 'Niko Tyni ' - 'Olaf Alders ' - 'Olivier Mengué ' - 'Randy Sims ' - 'Tomohiro Hosaka ' CPAN-Meta-2.150005/perlcritic.rc000644 000765 000024 00000001166 12535707053 016306 0ustar00davidstaff000000 000000 severity = 5 verbose = 8 [Variables::ProhibitPunctuationVars] allow = $@ $! [TestingAndDebugging::ProhibitNoStrict] allow = refs [Variables::ProhibitEvilVariables] variables = $DB::single # Turn these off [-BuiltinFunctions::ProhibitStringyEval] [-ControlStructures::ProhibitPostfixControls] [-ControlStructures::ProhibitUnlessBlocks] [-Documentation::RequirePodSections] [-InputOutput::ProhibitInteractiveTest] [-References::ProhibitDoubleSigils] [-RegularExpressions::RequireExtendedFormatting] [-InputOutput::ProhibitTwoArgOpen] [-Modules::ProhibitEvilModules] # Turn this on [Lax::ProhibitStringyEval::ExceptForRequire] CPAN-Meta-2.150005/README000644 000765 000024 00000026610 12535707053 014501 0ustar00davidstaff000000 000000 NAME CPAN::Meta - the distribution metadata for a CPAN dist VERSION version 2.150005 SYNOPSIS use v5.10; use strict; use warnings; use CPAN::Meta; use Module::Load; my $meta = CPAN::Meta->load_file('META.json'); printf "testing requirements for %s version %s\n", $meta->name, $meta->version; my $prereqs = $meta->effective_prereqs; for my $phase ( qw/configure runtime build test/ ) { say "Requirements for $phase:"; my $reqs = $prereqs->requirements_for($phase, "requires"); for my $module ( sort $reqs->required_modules ) { my $status; if ( eval { load $module unless $module eq 'perl'; 1 } ) { my $version = $module eq 'perl' ? $] : $module->VERSION; $status = $reqs->accepts_module($module, $version) ? "$version ok" : "$version not ok"; } else { $status = "missing" }; say " $module ($status)"; } } DESCRIPTION Software distributions released to the CPAN include a META.json or, for older distributions, META.yml, which describes the distribution, its contents, and the requirements for building and installing the distribution. The data structure stored in the META.json file is described in CPAN::Meta::Spec. CPAN::Meta provides a simple class to represent this distribution metadata (or *distmeta*), along with some helpful methods for interrogating that data. The documentation below is only for the methods of the CPAN::Meta object. For information on the meaning of individual fields, consult the spec. METHODS new my $meta = CPAN::Meta->new($distmeta_struct, \%options); Returns a valid CPAN::Meta object or dies if the supplied metadata hash reference fails to validate. Older-format metadata will be up-converted to version 2 if they validate against the original stated specification. It takes an optional hashref of options. Valid options include: * lazy_validation -- if true, new will attempt to convert the given metadata to version 2 before attempting to validate it. This means than any fixable errors will be handled by CPAN::Meta::Converter before validation. (Note that this might result in invalid optional data being silently dropped.) The default is false. create my $meta = CPAN::Meta->create($distmeta_struct, \%options); This is same as "new()", except that "generated_by" and "meta-spec" fields will be generated if not provided. This means the metadata structure is assumed to otherwise follow the latest CPAN::Meta::Spec. load_file my $meta = CPAN::Meta->load_file($distmeta_file, \%options); Given a pathname to a file containing metadata, this deserializes the file according to its file suffix and constructs a new "CPAN::Meta" object, just like "new()". It will die if the deserialized version fails to validate against its stated specification version. It takes the same options as "new()" but "lazy_validation" defaults to true. load_yaml_string my $meta = CPAN::Meta->load_yaml_string($yaml, \%options); This method returns a new CPAN::Meta object using the first document in the given YAML string. In other respects it is identical to "load_file()". load_json_string my $meta = CPAN::Meta->load_json_string($json, \%options); This method returns a new CPAN::Meta object using the structure represented by the given JSON string. In other respects it is identical to "load_file()". load_string my $meta = CPAN::Meta->load_string($string, \%options); If you don't know if a string contains YAML or JSON, this method will use Parse::CPAN::Meta to guess. In other respects it is identical to "load_file()". save $meta->save($distmeta_file, \%options); Serializes the object as JSON and writes it to the given file. The only valid option is "version", which defaults to '2'. On Perl 5.8.1 or later, the file is saved with UTF-8 encoding. For "version" 2 (or higher), the filename should end in '.json'. JSON::PP is the default JSON backend. Using another JSON backend requires JSON 2.5 or later and you must set the $ENV{PERL_JSON_BACKEND} to a supported alternate backend like JSON::XS. For "version" less than 2, the filename should end in '.yml'. CPAN::Meta::Converter is used to generate an older metadata structure, which is serialized to YAML. CPAN::Meta::YAML is the default YAML backend. You may set the $ENV{PERL_YAML_BACKEND} to a supported alternative backend, though this is not recommended due to subtle incompatibilities between YAML parsers on CPAN. meta_spec_version This method returns the version part of the "meta_spec" entry in the distmeta structure. It is equivalent to: $meta->meta_spec->{version}; effective_prereqs my $prereqs = $meta->effective_prereqs; my $prereqs = $meta->effective_prereqs( \@feature_identifiers ); This method returns a CPAN::Meta::Prereqs object describing all the prereqs for the distribution. If an arrayref of feature identifiers is given, the prereqs for the identified features are merged together with the distribution's core prereqs before the CPAN::Meta::Prereqs object is returned. should_index_file ... if $meta->should_index_file( $filename ); This method returns true if the given file should be indexed. It decides this by checking the "file" and "directory" keys in the "no_index" property of the distmeta structure. Note that neither the version format nor "release_status" are considered. $filename should be given in unix format. should_index_package ... if $meta->should_index_package( $package ); This method returns true if the given package should be indexed. It decides this by checking the "package" and "namespace" keys in the "no_index" property of the distmeta structure. Note that neither the version format nor "release_status" are considered. features my @feature_objects = $meta->features; This method returns a list of CPAN::Meta::Feature objects, one for each optional feature described by the distribution's metadata. feature my $feature_object = $meta->feature( $identifier ); This method returns a CPAN::Meta::Feature object for the optional feature with the given identifier. If no feature with that identifier exists, an exception will be raised. as_struct my $copy = $meta->as_struct( \%options ); This method returns a deep copy of the object's metadata as an unblessed hash reference. It takes an optional hashref of options. If the hashref contains a "version" argument, the copied metadata will be converted to the version of the specification and returned. For example: my $old_spec = $meta->as_struct( {version => "1.4"} ); as_string my $string = $meta->as_string( \%options ); This method returns a serialized copy of the object's metadata as a character string. (The strings are not UTF-8 encoded.) It takes an optional hashref of options. If the hashref contains a "version" argument, the copied metadata will be converted to the version of the specification and returned. For example: my $string = $meta->as_string( {version => "1.4"} ); For "version" greater than or equal to 2, the string will be serialized as JSON. For "version" less than 2, the string will be serialized as YAML. In both cases, the same rules are followed as in the "save()" method for choosing a serialization backend. The serialized structure will include a "x_serialization_backend" entry giving the package and version used to serialize. Any existing key in the given $meta object will be clobbered. STRING DATA The following methods return a single value, which is the value for the corresponding entry in the distmeta structure. Values should be either undef or strings. * abstract * description * dynamic_config * generated_by * name * release_status * version LIST DATA These methods return lists of string values, which might be represented in the distmeta structure as arrayrefs or scalars: * authors * keywords * licenses The "authors" and "licenses" methods may also be called as "author" and "license", respectively, to match the field name in the distmeta structure. MAP DATA These readers return hashrefs of arbitrary unblessed data structures, each described more fully in the specification: * meta_spec * resources * provides * no_index * prereqs * optional_features CUSTOM DATA A list of custom keys are available from the "custom_keys" method and particular keys may be retrieved with the "custom" method. say $meta->custom($_) for $meta->custom_keys; If a custom key refers to a data structure, a deep clone is returned. BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. SEE ALSO * CPAN::Meta::Converter * CPAN::Meta::Validator SUPPORT Bugs / Feature Requests Please report any bugs or feature requests through the issue tracker at . You will be notified automatically of any progress on your issue. Source Code This is open source software. The code repository is available for public review and contribution under the terms of the license. git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git AUTHORS * David Golden * Ricardo Signes CONTRIBUTORS * Ansgar Burchardt * Avar Arnfjord Bjarmason * Christopher J. Madsen * Chuck Adams * Cory G Watson * Damyan Ivanov * Eric Wilhelm * Graham Knop * Gregor Hermann * Karen Etheridge * Kenichi Ishigaki * Ken Williams * Lars Dieckow * Leon Timmermans * majensen * Mark Fowler * Matt S Trout * Michael G. Schwern * mohawk2 * moznion * Niko Tyni * Olaf Alders * Olivier Mengué * Randy Sims * Tomohiro Hosaka COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. CPAN-Meta-2.150005/t/000755 000765 000024 00000000000 12535707053 014057 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/Todo000644 000765 000024 00000000415 12535707053 014444 0ustar00davidstaff000000 000000 improve validation/conversion testing of valid/invalid specs move the distmeta struct to $self->{distmeta} or something rather than having it be the entire gits of the CPAN::Meta validate version numbers with version::is_lax use dclone more in converting structures CPAN-Meta-2.150005/xt/000755 000765 000024 00000000000 12535707053 014247 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/xt/author/000755 000765 000024 00000000000 12535707053 015551 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/xt/release/000755 000765 000024 00000000000 12535707053 015667 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/xt/release/distmeta.t000644 000765 000024 00000000172 12535707053 017666 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::MetaTests. use Test::CPAN::Meta; meta_yaml_ok(); CPAN-Meta-2.150005/xt/release/pod-coverage.t000644 000765 000024 00000000334 12535707053 020427 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests. use Test::Pod::Coverage 1.08; use Pod::Coverage::TrustPod; all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); CPAN-Meta-2.150005/xt/release/pod-syntax.t000644 000765 000024 00000000220 12535707053 020154 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use Test::More; use Test::Pod 1.41; all_pod_files_ok(); CPAN-Meta-2.150005/xt/release/portability.t000644 000765 000024 00000000332 12535707053 020414 0ustar00davidstaff000000 000000 #!perl use strict; use warnings; use Test::More; eval 'use Test::Portability::Files'; plan skip_all => 'Test::Portability::Files required for testing portability' if $@; options(test_one_dot => 0); run_tests(); CPAN-Meta-2.150005/xt/release/test-version.t000644 000765 000024 00000000607 12535707053 020521 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::Version 1.02 use Test::Version; my @imports = qw( version_all_ok ); my $params = { is_strict => 0, has_version => 1, }; push @imports, $params if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); Test::Version->import(@imports); version_all_ok; done_testing; CPAN-Meta-2.150005/xt/author/00-compile.t000644 000765 000024 00000002637 12535707053 017613 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.053 use Test::More; plan tests => 9; my @module_files = ( 'CPAN/Meta.pm', 'CPAN/Meta/Converter.pm', 'CPAN/Meta/Feature.pm', 'CPAN/Meta/History.pm', 'CPAN/Meta/Merge.pm', 'CPAN/Meta/Prereqs.pm', 'CPAN/Meta/Spec.pm', 'CPAN/Meta/Validator.pm' ); # fake home for cpan-testers use File::Temp; local $ENV{HOME} = File::Temp::tempdir( CLEANUP => 1 ); my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib'; use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ); CPAN-Meta-2.150005/xt/author/critic.t000644 000765 000024 00000000435 12535707053 017215 0ustar00davidstaff000000 000000 #!perl use strict; use warnings; use Test::More; use English qw(-no_match_vars); eval "use Test::Perl::Critic"; plan skip_all => 'Test::Perl::Critic required to criticise code' if $@; Test::Perl::Critic->import( -profile => "perlcritic.rc" ) if -e "perlcritic.rc"; all_critic_ok(); CPAN-Meta-2.150005/xt/author/pod-spell.t000644 000765 000024 00000001712 12535707053 017636 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006009 use Test::Spelling 0.12; use Pod::Wordlist; add_stopwords(); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ apache bsd dir distmeta dists gpl lgpl mailto metacpan mit mozilla releaser subkey subkeys David Golden dagolden Ricardo Signes rjbs and Ansgar Burchardt ansgar Avar Arnfjord Bjarmason avar Christopher Madsen cjm Chuck Adams cja987 Cory Watson gphat Damyan Ivanov dam Eric Wilhelm ewilhelm Graham Knop haarg Gregor Hermann gregoa Karen Etheridge ether Kenichi Ishigaki ishigaki Ken Williams kwilliams Lars Dieckow daxim Leon Timmermans leont majensen maj Mark Fowler markf Matt Trout mst Michael Schwern mschwern mohawk2 moznion Niko Tyni ntyni Olaf Alders olaf Olivier Mengué dolmen Randy Sims randys Tomohiro Hosaka bokutin lib CPAN Meta Converter Feature History Meta_1_0 Meta_1_1 Meta_1_2 Meta_1_3 Meta_1_4 Merge Prereqs Spec Validator CPAN-Meta-2.150005/t/00-report-prereqs.dd000644 000765 000024 00000006551 12535707053 017606 0ustar00davidstaff000000 000000 do { my $x = { 'configure' => { 'requires' => { 'ExtUtils::MakeMaker' => '6.17', 'perl' => '5.006' } }, 'develop' => { 'recommends' => { 'Perl::Critic::Policy::Lax::ProhibitStringyEval::ExceptForRequire' => '0' }, 'requires' => { 'Dist::Zilla' => '5', 'Dist::Zilla::Plugin::Encoding' => '0', 'Dist::Zilla::Plugin::MakeMaker::Highlander' => '0.003', 'Dist::Zilla::Plugin::OnlyCorePrereqs' => '0.014', 'Dist::Zilla::Plugin::Prereqs' => '0', 'Dist::Zilla::Plugin::SurgicalPodWeaver' => '0.0021', 'Dist::Zilla::PluginBundle::DAGOLDEN' => '0.070', 'File::Spec' => '0', 'File::Temp' => '0', 'IO::Handle' => '0', 'IPC::Open3' => '0', 'Pod::Coverage::TrustPod' => '0', 'Test::CPAN::Meta' => '0', 'Test::More' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Spelling' => '0.12', 'Test::Version' => '1' } }, 'runtime' => { 'requires' => { 'CPAN::Meta::Requirements' => '2.121', 'CPAN::Meta::YAML' => '0.008', 'Carp' => '0', 'JSON::PP' => '2.27200', 'Parse::CPAN::Meta' => '1.4414', 'Scalar::Util' => '0', 'perl' => '5.008', 'strict' => '0', 'version' => '0.88', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'Data::Dumper' => '0', 'ExtUtils::MakeMaker' => '0', 'File::Basename' => '0', 'File::Spec' => '0', 'File::Temp' => '0.20', 'IO::Dir' => '0', 'Test::More' => '0.88', 'overload' => '0', 'perl' => '5.008', 'utf8' => '0' } } }; $x; }CPAN-Meta-2.150005/t/00-report-prereqs.t000644 000765 000024 00000012731 12535707053 017457 0ustar00davidstaff000000 000000 #!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do 't/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; if ( $source && $HAS_CPAN_META ) { if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } } else { $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( @dep_errors ) { diag join("\n", "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", "The following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: CPAN-Meta-2.150005/t/converter-bad.t000644 000765 000024 00000005247 12535707053 017007 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use CPAN::Meta::Validator; use CPAN::Meta::Converter; use File::Spec; use IO::Dir; use Parse::CPAN::Meta 1.4400; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my @data_dirs = qw( t/data-valid t/data-fixable ); my @files = sort map { my $d = $_; map { "$d/$_" } grep { substr($_,0,1) ne '.' } IO::Dir->new($d)->read } @data_dirs; *_spec_version = \&CPAN::Meta::Converter::_extract_spec_version; #use Data::Dumper; for my $f ( reverse sort @files ) { my $path = File::Spec->catfile($f); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded $f" ); my $original_v = _spec_version($original); # UPCONVERSION if ( $original_v lt '2' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => 2 ); is ( _spec_version($converted), 2, "up converted spec version $original_v to spec version 2"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "up converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } # UPCONVERSION - partial if ( $original_v lt '1.4' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.4' ); is ( _spec_version($converted), 1.4, "up converted spec version $original_v to spec version 1.4"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "up converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } # DOWNCONVERSION - partial if ( $original_v gt '1.2' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.2' ); is ( _spec_version($converted), '1.2', "down converted spec version $original_v to spec version 1.2"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "down converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } # DOWNCONVERSION if ( $original_v gt '1.0' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.0' ); is ( _spec_version($converted), '1.0', "down converted spec version $original_v to spec version 1.0"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "down converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/converter-fail.t000644 000765 000024 00000002161 12535707053 017164 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use CPAN::Meta::Validator; use CPAN::Meta::Converter; use File::Spec; use IO::Dir; use Parse::CPAN::Meta 1.4400; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $data_dir = IO::Dir->new( 't/data-fail' ); my @files = sort grep { /^\w/ } $data_dir->read; *_spec_version = \&CPAN::Meta::Converter::_extract_spec_version; use Data::Dumper; for my $f ( reverse sort @files ) { my $path = File::Spec->catfile('t','data-fail',$f); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded invalid $f" ); my $original_v = _spec_version($original); # UPCONVERSION if ( $original_v lt '2' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $fixed = eval { $cmc->convert( version => 2 ) }; ok ( $@, "error thrown up converting" ); } # DOWNCONVERSION if ( $original_v gt '1.0' ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $fixed = eval { $cmc->convert( version => '1.0' ) }; ok ( $@, "error thrown down converting" ); } } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/converter-fragments.t000644 000765 000024 00000007701 12535707053 020244 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta::Converter; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $spec2 = { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', }; my @cases = ( #<<< No perltidy { label => "v1.4 requires -> v2 prereqs", from => "1.4", to => "2", input => { requires => { 'File::Spec' => "0.80", }, }, expect => { 'meta-spec' => $spec2, prereqs => { runtime => { requires => { 'File::Spec' => "0.80", }, } } }, }, { label => "v1.4 x_custom -> v2 x_custom", from => "1.4", to => "2", input => { x_authority => 'DAGOLDEN', }, expect => { 'meta-spec' => $spec2, x_authority => 'DAGOLDEN', }, }, { label => "meta-spec included", to => "2", input => { 'meta-spec' => { version => '1.0' }, requires => { 'File::Spec' => "0.80", }, }, expect => { 'meta-spec' => $spec2, prereqs => { runtime => { requires => { 'File::Spec' => "0.80", }, } } }, }, { # this is a test of default version and intentionally gives bad # data that will get dropped by the conversion label => "default version", from => "2", to => "2", input => { requires => { 'File::Spec' => "0.80", }, }, expect => { 'meta-spec' => $spec2, }, }, { # fields deprecated from older versions label => "v1.4 prereq stuff -> v2 prereqs", from => "1.4", to => "2", input => { configure_requires => { 'File::Spec' => "0.80", }, build_requires => { 'Scalar::Util' => '1.0', }, requires => { 'B' => '3.1', }, recommends => { 'Config' => '4.0', }, conflicts => { 'File::Temp' => "0.2", }, }, expect => { 'meta-spec' => $spec2, prereqs => { configure => { requires => { 'File::Spec' => "0.80", }, }, build => { requires => { 'Scalar::Util' => '1.0', }, }, runtime => { conflicts => { 'File::Temp' => "0.2", }, requires => { 'B' => '3.1', }, recommends => { 'Config' => '4.0', }, }, }, }, }, { label => "v1.1 license_url: -> v2 license", from => "1.1", to => "2", input => { license_url => 'http://opensource.org/licenses/Artistic-1.0', license => 'perl', }, expect => { 'meta-spec' => $spec2, license => [ 'perl_5' ], }, }, ); for my $c (@cases) { my $cmc = CPAN::Meta::Converter->new( $c->{input}, $c->{from} ? (default_version => $c->{from} ) : () ); my $got = $cmc->upgrade_fragment; my $exp = $c->{expect}; is_deeply( $got, $exp, $c->{label} ) or diag "GOT:\n", explain($got), "EXPECTED:\n", explain($exp); } done_testing; # vim: ts=8 sts=4 sw=4 et : CPAN-Meta-2.150005/t/converter.t000644 000765 000024 00000024570 12535707053 016263 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use utf8; use CPAN::Meta; use CPAN::Meta::Validator; use CPAN::Meta::Converter; use File::Spec; use File::Basename qw/basename/; use IO::Dir; use Parse::CPAN::Meta 1.4400; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults # mock file object package File::StringObject; use overload q{""} => sub { ${$_[0]} }, fallback => 1; sub new { my ($class, $file) = @_; bless \$file, $class; } package main; my $data_dir = IO::Dir->new( 't/data-test' ); my @files = sort grep { /^\w/ } $data_dir->read; *_spec_version = \&CPAN::Meta::Converter::_extract_spec_version; #use Data::Dumper; for my $f ( reverse sort @files ) { note ''; my $path = File::Spec->catfile('t','data-test',$f); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded $f" ); my $original_v = _spec_version($original); # UPCONVERSION { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => 2 ); is ( _spec_version($converted), 2, "up converted spec version $original_v to spec version 2"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "up converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } # UPCONVERSION - partial if ( _spec_version( $original ) < 2 ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.4' ); is ( _spec_version($converted), 1.4, "up converted spec version $original_v to spec version 1.4"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "up converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); } # DOWNCONVERSION - partial if ( _spec_version( $original ) >= 1.2 ) { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.2' ); is ( _spec_version($converted), '1.2', "down converted spec version $original_v to spec version 1.2"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "down converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); if (_spec_version( $original ) == 2) { is_deeply( $converted->{build_requires}, { 'Test::More' => '0.88', 'Build::Requires' => '1.1', 'Test::Requires' => '1.2', }, "downconversion from 2 merge test and build requirements", ); } } # DOWNCONVERSION { my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => '1.0' ); is ( _spec_version($converted), '1.0', "down converted spec version $original_v to spec version 1.0"); my $cmv = CPAN::Meta::Validator->new( $converted ); ok ( $cmv->is_valid, "down converted META is valid" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) # . "\nMETA:\n" . Dumper($converted) ); unless ($original_v eq '1.0') { like ( $converted->{generated_by}, qr(\Q$original->{generated_by}\E, CPAN::Meta::Converter version \S+$), "added converter mark to generated_by", ); } } } # specific test for custom key handling { my $path = File::Spec->catfile('t','data-test','META-1_4.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded META-1_4.yml" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $up_converted = $cmc->convert( version => 2 ); ok ( $up_converted->{x_whatever} && ! $up_converted->{'x-whatever'}, "up converted 'x-' to 'x_'" ); ok ( $up_converted->{x_whatelse}, "up converted 'x_' as 'x_'" ); ok ( $up_converted->{x_WhatNow} && ! $up_converted->{XWhatNow}, "up converted 'XFoo' to 'x_Foo'" ) or diag join("\n", keys %$up_converted); } # specific test for custom key handling { my $path = File::Spec->catfile('t','data-test','META-2.json'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded META-2.json" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $down_converted = $cmc->convert( version => 1.4 ); ok ( $down_converted->{x_whatever}, "down converted 'x_' as 'x_'" ); } # specific test for generalization of unclear licenses { my $path = File::Spec->catfile('t','data-test','gpl-1_4.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded gpl-1_4.yml" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $up_converted = $cmc->convert( version => 2 ); is_deeply ( $up_converted->{license}, [ "open_source" ], "up converted 'gpl' to 'open_source'" ); } # specific test for upconverting resources { my $path = File::Spec->catfile('t','data-test','resources.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded resources.yml" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => 2 ); is_deeply( $converted->{resources}, { x_MailingList => 'http://groups.google.com/group/www-mechanize-users', x_Repository => 'http://code.google.com/p/www-mechanize/source', homepage => 'http://code.google.com/p/www-mechanize/', bugtracker => {web => 'http://code.google.com/p/www-mechanize/issues/list',}, license => ['http://dev.perl.org/licenses/'], }, "upconversion of resources" ); } # specific test for round-tripping resources { my $path = File::Spec->catfile('t','data-test','resources.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded resources.yml" ); my $cmc1 = CPAN::Meta::Converter->new( $original ); my $converted = $cmc1->convert( version => 2 ); my $cmc2 = CPAN::Meta::Converter->new( $converted ); my $roundtrip = $cmc2->convert( version => 1.4 ); is_deeply( $roundtrip->{resources}, $original->{resources}, "round-trip of resources (1.4->2->1.4)" ); } # specific test for object conversion { my $path = File::Spec->catfile('t','data-test','resources.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded resources.yml" ); $original->{version} = version->new("1.64"); $original->{no_index}{file} = File::StringObject->new(".gitignore"); pass( "replaced some data fields with objects" ); my $cmc = CPAN::Meta::Converter->new( $original ); ok( my $converted = $cmc->convert( version => 2 ), "conversion successful" ); } # specific test for UTF-8 handling { my $path = File::Spec->catfile('t','data-test','unicode.yml'); my $original = CPAN::Meta->load_file( $path ) or die "Couldn't load $path"; ok( $original, "unicode.yml" ); my @authors = $original->authors; like( $authors[0], qr/Williåms/, "Unicode characters preserved in authors" ); } # specific test for version ranges { my @prereq_keys = qw( prereqs requires build_requires configure_requires recommends conflicts ); for my $case ( qw/ 2 1_4 / ) { my $suffix = $case eq 2 ? "$case.json" : "$case.yml"; my $version = $case; $version =~ tr[_][.]; my $path = File::Spec->catfile('t','data-test','version-ranges-' . $suffix); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded " . basename $path ); my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => $version ); for my $h ( $original, $converted ) { delete $h->{generated_by}; delete $h->{'meta-spec'}{url}; for my $k ( @prereq_keys ) { _normalize_reqs($h->{$k}) if exists $h->{$k}; } } is_deeply( $converted, $original, "version ranges preserved in conversion" ); } } # specific test for version numbers { my $path = File::Spec->catfile('t','data-test','version-not-normal.json'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded " . basename $path ); my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => 2 ); is( $converted->{prereqs}{runtime}{requires}{'File::Find'}, "v0.1.0", "normalize v0.1"); is( $converted->{prereqs}{runtime}{requires}{'File::Path'}, "v1.0.0", "normalize v1.0.0"); } # specific test for missing provides version { my $path = File::Spec->catfile('t','data-test','provides-version-missing.json'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded " . basename $path ); my $cmc = CPAN::Meta::Converter->new( $original ); my $converted = $cmc->convert( version => 2 ); is_deeply( $converted->{provides}{"Foo::Bar"}, { file => "lib/Foo/Bar.pm", version => "0.27_02" }, "Foo::Bar provides correct" ); is_deeply( $converted->{provides}{"Foo::Bar::Blah"}, { file => "lib/Foo/Bar/Blah.pm" }, "Foo::Bar::Blah provides correct" ); is_deeply( $converted->{provides}{"Foo::Bar::Baz"}, { file => "lib/Foo/Bar/Baz.pm", version => "0.3" }, "Foo::Bar provides correct" ); } # CMR standardizes stuff in a way that makes it hard to test original vs final # so we remove spaces and >= to make them compare the same sub _normalize_reqs { my $hr = shift; for my $k ( keys %$hr ) { if (ref $hr->{$k} eq 'HASH') { _normalize_reqs($hr->{$k}); } elsif ( ! ref $hr->{$k} ) { $hr->{$k} =~ s{\s+}{}g; $hr->{$k} =~ s{>=\s*}{}g; } } } # specific test for multiple licenses { my $path = File::Spec->catfile('t','data-test','META-2.json'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded META-2.json" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $cleaned_up = $cmc->convert( version => "2" ); is_deeply( $cleaned_up->{license}, [ 'perl_5', 'bsd' ], "multiple license preserved (v2)" ); $cleaned_up = $cmc->convert( version => "1.4" ); is( $cleaned_up->{license}, 'open_source', "multiple license converted to open_source (v1.4)" ); } # specific test for preserving release_status on upconversion { my $path = File::Spec->catfile('t','data-test','preserve-release-status.yml'); my $original = Parse::CPAN::Meta->load_file( $path ); ok( $original, "loaded META-2.json" ); my $cmc = CPAN::Meta::Converter->new( $original ); my $cleaned_up = $cmc->convert( version => "2" ); is( $cleaned_up->{release_status}, 'unstable', "release_status preserved" ); } done_testing; # vim: ts=2 sts=2 sw=2 et: CPAN-Meta-2.150005/t/data-fail/000755 000765 000024 00000000000 12535707053 015701 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/t/data-fixable/000755 000765 000024 00000000000 12535707053 016400 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/t/data-test/000755 000765 000024 00000000000 12535707053 015745 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/t/data-valid/000755 000765 000024 00000000000 12535707053 016065 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/t/load-bad.t000644 000765 000024 00000001347 12535707053 015714 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use File::Spec; use IO::Dir; sub _slurp { do { local(@ARGV,$/)=shift(@_); <> } } delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $data_dir = IO::Dir->new( 't/data-fixable' ); my @files = sort grep { /^\w/ } $data_dir->read; for my $f ( sort @files ) { my $path = File::Spec->catfile('t','data-fixable',$f); ok( eval { CPAN::Meta->load_file( $path ) }, "load_file('$f')" ) or diag $@; my $string = _slurp($path); my $method = $path =~ /\.json/ ? "load_json_string" : "load_yaml_string"; ok( eval { CPAN::Meta->$method( $string, { fix_errors => 1 } ) }, "$method(slurp('$f'))" ) or diag $@; } done_testing; # vim: ts=2 sts=2 sw=2 et: CPAN-Meta-2.150005/t/merge.t000644 000765 000024 00000010050 12535707053 015337 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; use CPAN::Meta; use CPAN::Meta::Merge; my %base = ( abstract => 'This is a test', author => ['A.U. Thor'], generated_by => 'Myself', license => [ 'perl_5' ], resources => { license => [ 'http://dev.perl.org/licenses/' ], bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' }, }, prereqs => { runtime => { requires => { Foo => '0', }, }, }, dynamic_config => 0, provides => { Baz => { file => 'lib/Baz.pm', }, }, 'meta-spec' => { url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", version => 2, }, ); my %first = ( author => [ 'I.M. Poster' ], generated_by => 'Some other guy', license => [ 'bsd' ], resources => { license => [ 'http://opensource.org/licenses/bsd-license.php' ], }, prereqs => { runtime => { requires => { Foo => '< 1', }, recommends => { Bar => '3.14', }, }, test => { requires => { 'Test::Bar' => 0, }, }, }, dynamic_config => 1, provides => { Quz => { file => 'lib/Quz.pm', }, }, ); my %first_expected = ( abstract => 'This is a test', author => [ 'A.U. Thor', 'I.M. Poster' ], generated_by => 'Myself, Some other guy', license => [ 'perl_5', 'bsd' ], resources => { license => [ 'http://dev.perl.org/licenses/', 'http://opensource.org/licenses/bsd-license.php' ], bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' }, }, prereqs => { runtime => { requires => { Foo => '>= 0, < 1', }, recommends => { Bar => '3.14', }, }, test => { requires => { 'Test::Bar' => 0, }, }, }, provides => { Baz => { file => 'lib/Baz.pm', }, Quz => { file => 'lib/Quz.pm', }, }, dynamic_config => 1, 'meta-spec' => { url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", version => 2, }, ); my %provides_merge_expected = ( abstract => 'This is a test', author => ['A.U. Thor'], generated_by => 'Myself', license => [ 'perl_5' ], resources => { license => [ 'http://dev.perl.org/licenses/' ], bugtracker => { web => 'https://rt.cpan.org/Dist/Display.html?Foo-Bar' }, }, prereqs => { runtime => { requires => { Foo => '0', }, }, }, dynamic_config => 0, provides => { Baz => { file => 'lib/Baz.pm', version => '0.001', # same as %base, but for this extra key }, }, 'meta-spec' => { url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", version => 2, }, ); my $merger = CPAN::Meta::Merge->new(default_version => '2'); my $first_result = $merger->merge(\%base, \%first); is_deeply($first_result, \%first_expected, 'First result is as expected'); is_deeply($merger->merge(\%base, { abstract => 'This is a test' }), \%base, 'Can merge in identical abstract'); is( eval { $merger->merge(\%base, { abstract => 'And now for something else' }) }, undef, 'Trying to merge different author gives an exception', ); like $@, qr/^Can't merge attribute abstract/, 'Exception looks right'; is( eval { $merger->merge(\%base, { resources => { bugtracker => { web => 'http://foo.com' } } } ) }, undef, 'Trying to merge a different bugtracker URL gives an exception', ); like $@, qr/^Duplication of element resources\.bugtracker\.web /, 'Exception looks right'; is( eval { $merger->merge(\%base, { provides => { Baz => { file => 'Baz.pm' } } }) }, undef, 'Trying to merge different provides.$module.file gives an exception', ); like $@, qr/^Duplication of element provides\.Baz\.file /, 'Exception looks right'; my $provides_result = $merger->merge(\%base, { provides => { Baz => { file => 'lib/Baz.pm', version => '0.001' } } }); is_deeply( $provides_result, \%provides_merge_expected, 'Trying to merge a new key for provides.$module is permitted; identical values are preserved', ); # issue 67 @base{qw/name version release_status/} = qw/Foo-Bar 0.01 testing/; my $base_obj = CPAN::Meta->create(\%base); ok my $first_result_obj = $merger->merge($base_obj, \%first), 'merging CPAN::Meta objects succeeds'; done_testing(); # vim: ts=4 sts=4 sw=4 tw=78 noet : CPAN-Meta-2.150005/t/meta-obj.t000644 000765 000024 00000013351 12535707053 015745 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use Scalar::Util qw(blessed); delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $distmeta = { name => 'Module-Build', abstract => 'Build and install Perl modules', description => "Module::Build is a system for building, testing, " . "and installing Perl modules. It is meant to be an " . "alternative to ExtUtils::MakeMaker... blah blah blah", version => '0.36', author => [ 'Ken Williams ', 'Module-Build List ', # additional contact ], release_status => 'stable', license => [ 'perl_5' ], prereqs => { runtime => { requires => { 'perl' => '5.006', 'Config' => '0', 'Cwd' => '0', 'Data::Dumper' => '0', 'ExtUtils::Install' => '0', 'File::Basename' => '0', 'File::Compare' => '0', 'File::Copy' => '0', 'File::Find' => '0', 'File::Path' => '0', 'File::Spec' => '0', 'IO::File' => '0', }, recommends => { 'Archive::Tar' => '1.00', 'ExtUtils::Install' => '0.3', 'ExtUtils::ParseXS' => '2.02', 'Pod::Text' => '0', 'YAML' => '0.35', }, }, build => { requires => { 'Test::More' => '0', }, } }, resources => { license => ['http://dev.perl.org/licenses/'], }, optional_features => { domination => { description => 'Take over the world', prereqs => { develop => { requires => { 'Genius::Evil' => '1.234' } }, runtime => { requires => { 'Machine::Weather' => '2.0' } }, }, }, }, dynamic_config => 1, keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', x_authority => 'cpan:FLORA', X_deep => { deep => 'structure' }, }; my $meta = CPAN::Meta->new($distmeta); is( blessed($meta->as_struct), undef, "the result of ->as_struct is unblessed", ); is_deeply( $meta->as_struct, $distmeta, "->as_struct (deep comparison)" ); isnt( $meta->as_struct, $distmeta, "->as_struct (is a deep clone)" ); my $old_copy = $meta->as_struct( {version => "1.4"} ); is( $old_copy->{'meta-spec'}{version}, "1.4", "->as_struct (downconversion)" ); isnt( $meta->resources, $meta->{resources}, "->resource (map values are deep cloned)"); is($meta->name, 'Module-Build', '->name'); is($meta->abstract, 'Build and install Perl modules', '->abstract'); like($meta->description, qr/Module::Build.+blah blah blah/, '->description'); is($meta->version, '0.36', '->version'); ok($meta->dynamic_config, "->dynamic_config"); is_deeply( [ $meta->author ], [ 'Ken Williams ', 'Module-Build List ', ], '->author', ); is_deeply( [ $meta->authors ], [ 'Ken Williams ', 'Module-Build List ', ], '->authors', ); is_deeply( [ $meta->license ], [ qw(perl_5) ], '->license', ); is_deeply( [ $meta->licenses ], [ qw(perl_5) ], '->licenses', ); is_deeply( [ $meta->keywords ], [ qw/ toolchain cpan dual-life / ], '->keywords', ); is_deeply( $meta->resources, { license => [ 'http://dev.perl.org/licenses/' ] }, '->resources', ); is_deeply( $meta->meta_spec, { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', }, '->meta_spec', ); is($meta->meta_spec_version, '2', '->meta_spec_version'); like($meta->generated_by, qr/Module::Build version 0.36/, '->generated_by'); my $basic = $meta->effective_prereqs; is_deeply( $basic->as_string_hash, $distmeta->{prereqs}, "->effective_prereqs()" ); is_deeply( [ sort $meta->custom_keys ] , [ 'X_deep', 'x_authority' ], "->custom_keys" ); is( $meta->custom('x_authority'), 'cpan:FLORA', "->custom(X)" ); is_deeply( $meta->custom('X_deep'), $distmeta->{'X_deep'}, "->custom(X) [is_deeply]" ); isnt( $meta->custom('X_deep'), $distmeta->{'X_deep'}, "->custom(x) [is a deep clone]" ); my $with_features = $meta->effective_prereqs([ qw(domination) ]); is_deeply( $with_features->as_string_hash, { develop => { requires => { 'Genius::Evil' => '1.234' } }, runtime => { requires => { 'perl' => '5.006', 'Config' => '0', 'Cwd' => '0', 'Data::Dumper' => '0', 'ExtUtils::Install' => '0', 'File::Basename' => '0', 'File::Compare' => '0', 'File::Copy' => '0', 'File::Find' => '0', 'File::Path' => '0', 'File::Spec' => '0', 'IO::File' => '0', 'Machine::Weather' => '2.0', }, recommends => { 'Archive::Tar' => '1.00', 'ExtUtils::Install' => '0.3', 'ExtUtils::ParseXS' => '2.02', 'Pod::Text' => '0', 'YAML' => '0.35', }, }, build => { requires => { 'Test::More' => '0', }, } }, "->effective_prereqs([ qw(domination) ])" ); my $chk_feature = sub { my $feature = shift; isa_ok($feature, 'CPAN::Meta::Feature'); is($feature->identifier, 'domination', '$feature->identifier'); is($feature->description, 'Take over the world', '$feature->description'); is_deeply( $feature->prereqs->as_string_hash, { develop => { requires => { 'Genius::Evil' => '1.234' } }, runtime => { requires => { 'Machine::Weather' => '2.0' } }, }, '$feature->prereqs', ); }; my @features = $meta->features; is(@features, 1, "we got one feature"); $chk_feature->($features[0]); $chk_feature->( $meta->feature('domination') ); done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/no-index.t000644 000765 000024 00000003406 12535707053 015770 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my %distmeta = ( name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => [ 'Joe' ], release_status => 'stable', license => [ 'perl_5' ], 'meta-spec' => { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', }, dynamic_config => 1, generated_by => 'Module::Build version 0.36', ); { my $meta = CPAN::Meta->new({ %distmeta }); ok( $meta->should_index_package('Foo::Bar::Baz'), 'we index any old package, without a no_index rule' ); ok( $meta->should_index_file('lib/Foo/Bar/Baz.pm'), 'we index any old file, without a no_index rule' ); } { my $meta = CPAN::Meta->new({ %distmeta, no_index => { package => [ 'Foo::Bar' ], namespace => [ 'Foo::Bar::Baz' ], } }); ok( ! $meta->should_index_package('Foo::Bar'), 'exclude a specific package' ); ok( $meta->should_index_package('Foo::Bar::Baz'), 'namespace X does not exclude package X' ); ok( ! $meta->should_index_package('Foo::Bar::Baz::Quux'), 'exclude something under a namespace' ); } { my $meta = CPAN::Meta->new({ %distmeta, no_index => { file => [ 'lib/Foo/Bar.pm' ], directory => [ 'lib/Foo/Bar/Baz' ], } }); ok( ! $meta->should_index_file('lib/Foo/Bar.pm'), 'exclude a specific file' ); ok( $meta->should_index_file('lib/Foo/Bar/Baz.pm'), 'do not exclude a file with a name like an excluded dir', ); ok( ! $meta->should_index_file('lib/Foo/Bar/Baz/Quux.pm'), 'exclude something under a directory' ); } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/optional_feature-merge.t000644 000765 000024 00000006075 12535707053 020711 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; use CPAN::Meta; use CPAN::Meta::Merge; my %base = ( abstract => 'This is a test', author => ['A.U. Thor'], generated_by => 'Myself', license => [ 'perl_5' ], resources => { license => [ 'http://dev.perl.org/licenses/' ], }, prereqs => { runtime => { requires => { Foo => '0', }, }, }, dynamic_config => 0, provides => { Baz => { file => 'lib/Baz.pm', }, }, 'meta-spec' => { url => "http://search.cpan.org/perldoc?CPAN::Meta::Spec", version => 2, }, ); my $fragment1 = { 'optional_features' => { 'FeatureName' => { 'description' => 'desc', 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } } } } }; my $fragment2 = { 'optional_features' => { 'FeatureName' => { 'description' => 'desc', 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } } } }; my $merger = CPAN::Meta::Merge->new(default_version => "2"); my $meta1 = $merger->merge(\%base, $fragment1); is_deeply( $meta1, { %base, %$fragment1, }, 'merged first optional_feature fragment into base', ); my $meta2 = $merger->merge($meta1, $fragment2); is_deeply( $meta2, { %base, 'optional_features' => { 'FeatureName' => { 'description' => 'desc', 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } }, 'test' => { 'requires' => { 'B' => '0' } }, } } } }, 'merged second optional_feature fragment into the first', ); my $fragment3 = { 'optional_features' => { 'FeatureName' => { 'description' => 'other desc', 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } } } }; is( eval { $merger->merge($meta1, $fragment3) }, undef, 'Trying to merge optional_features with same feature name and different descriptions gives an exception'); like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'description' values/, 'Exception looks right'; my $fragment4 = { 'optional_features' => { 'FeatureName' => { 'description' => 'desc', 'x_default' => 0, 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } } } }; is( eval { $merger->merge($meta1, $fragment4) }, undef, 'Trying to merge optional_features with same feature name and differences in other keys gives an exception'); like $@, qr/^Cannot merge two optional_features named 'FeatureName' with different 'x_default' values/, 'Exception looks right'; my $fragment5 = { 'optional_features' => { 'Another FeatureName' => { 'description' => 'desc', 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } } } } }; my $meta5 = $merger->merge($meta1, $fragment5); is_deeply( $meta5, { %base, 'optional_features' => { 'FeatureName' => { 'description' => 'desc', 'x_default' => 1, 'prereqs' => { 'runtime' => { 'requires' => { 'A' => '0' } } }, }, 'Another FeatureName' => { 'description' => 'desc', 'prereqs' => { 'test' => { 'requires' => { 'B' => '0' } } }, } } }, 'can merge optional_features with different names without collisions', ); done_testing; # vim: ts=4 sts=4 sw=4 noet : CPAN-Meta-2.150005/t/prereqs-finalize.t000644 000765 000024 00000004267 12535707053 017535 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta::Prereqs; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults sub dies_ok (&@) { my ($code, $qr, $comment) = @_; if (eval { $code->(); 1 }) { fail("$comment: did not die"); } else { like($@, $qr, $comment); } } my $prereqs_struct = { runtime => { requires => { 'Config' => '1.234', 'Cwd' => '876.5', 'IO::File' => 0, 'perl' => '5.005_03', }, recommends => { 'Pod::Text' => 0, 'YAML' => '0.35', }, }, build => { requires => { 'Test' => 0, }, } }; my $prereqs = CPAN::Meta::Prereqs->new($prereqs_struct); isa_ok($prereqs, 'CPAN::Meta::Prereqs'); $prereqs->finalize; ok($prereqs->is_finalized, 'cloned obj is not finalized'); is_deeply($prereqs->as_string_hash, $prereqs_struct, '...and still round-trip'); $prereqs->requirements_for(qw(runtime requires))->add_minimum(Cwd => 10); pass('...we can add a minimum if it has no effect'); dies_ok { $prereqs->requirements_for(qw(runtime requires))->add_minimum(Cwd => 1000) } qr{finalized req}, '...but we die if it would alter a finalized prereqs'; $prereqs->requirements_for(qw(develop suggests)); pass('...we can get a V:R object for a previously unconfigured phase'); dies_ok { $prereqs->requirements_for(qw(develop suggests))->add_minimum(Foo => 1) } qr{finalized req}, '...but we die if we try to put anything in it'; my $clone = $prereqs->clone; isa_ok($clone, 'CPAN::Meta::Prereqs', 'cloned prereqs obj'); ok(! $clone->is_finalized, 'cloned obj is not finalized'); is_deeply($clone->as_string_hash, $prereqs_struct, '...it still round-trips'); $clone->requirements_for(qw(runtime requires))->add_minimum(Cwd => 10); pass('...we can add minimum if it has no effect'); $clone->requirements_for(qw(runtime requires))->add_minimum(Cwd => 1000); pass('...or if it has an effect'); $clone->requirements_for(qw(develop suggests)); pass('...we can get a V:R object for a previously unconfigured phase'); $clone->requirements_for(qw(develop suggests))->add_minimum(Foo => 1); pass('...and we can add stuff to it'); done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/prereqs-merge.t000644 000765 000024 00000003733 12535707053 017030 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta::Prereqs; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $prereq_struct_1 = { runtime => { requires => { 'Config' => 0, 'Cwd' => 0, 'perl' => '5.005_03', }, recommends => { 'Pod::Text' => 0, 'YAML' => 0.35, }, }, build => { requires => { 'Test' => 0, }, } }; my $prereq_1 = CPAN::Meta::Prereqs->new($prereq_struct_1); isa_ok($prereq_1, 'CPAN::Meta::Prereqs', 'first prereq'); is_deeply($prereq_1->as_string_hash, $prereq_struct_1, '...and it round trips'); my $prereq_struct_2 = { develop => { requires => { 'Dist::Mothra' => '1.230', }, suggests => { 'Blort::Blortex' => '== 10.20', }, }, runtime => { requires => { 'Config' => 1, 'perl' => '< 6', }, }, build => { suggests => { 'Module::Build::Bob' => '20100101', }, } }; my $prereq_2 = CPAN::Meta::Prereqs->new($prereq_struct_2); isa_ok($prereq_2, 'CPAN::Meta::Prereqs', 'second prereq'); is_deeply($prereq_1->as_string_hash, $prereq_struct_1, '...and it round trips'); my $merged = $prereq_1->with_merged_prereqs($prereq_2); my $want = { develop => { requires => { 'Dist::Mothra' => '1.230', }, suggests => { 'Blort::Blortex' => '== 10.20', }, }, runtime => { requires => { 'Config' => 1, 'Cwd' => 0, 'perl' => '>= 5.005_03, < 6', }, recommends => { 'Pod::Text' => 0, 'YAML' => 0.35, }, }, build => { requires => { 'Test' => 0, }, suggests => { 'Module::Build::Bob' => '20100101', }, }, }; is_deeply( $merged->as_string_hash, $want, "we get the right result of merging two prereqs", ); is_deeply( $prereq_2->with_merged_prereqs($prereq_1)->as_string_hash, $want, "...and the merge works the same in reverse", ); done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/prereqs.t000644 000765 000024 00000006670 12535707053 015736 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta::Prereqs; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $prereq_struct = { runtime => { requires => { 'Config' => 0, 'Cwd' => 0, 'Data::Dumper' => 0, 'ExtUtils::Install' => 0, 'File::Basename' => 0, 'File::Compare' => 0, 'File::Copy' => 0, 'File::Find' => 0, 'File::Path' => 0, 'File::Spec' => 0, 'IO::File' => 0, 'perl' => '5.005_03', }, recommends => { 'Archive::Tar' => '1.00', 'ExtUtils::Install' => 0.3, 'ExtUtils::ParseXS' => 2.02, 'Pod::Text' => 0, 'YAML' => 0.35, }, }, build => { requires => { 'Test' => 0, }, } }; my $prereq = CPAN::Meta::Prereqs->new($prereq_struct); isa_ok($prereq, 'CPAN::Meta::Prereqs'); is_deeply($prereq->as_string_hash, $prereq_struct, "round-trip okay"); { my $req = $prereq->requirements_for(qw(runtime requires)); my @req_mod = $req->required_modules; ok( (grep { 'Cwd' eq $_ } @req_mod), "we got the runtime requirements", ); ok( (! grep { 'YAML' eq $_ } @req_mod), "...but not the runtime recommendations", ); ok( (! grep { 'Test' eq $_ } @req_mod), "...nor the build requirements", ); } { my $req = $prereq->requirements_for(qw(runtime requires)); my $rec = $prereq->requirements_for(qw(runtime recommends)); my $merged = $req->clone->add_requirements($rec); my @req_mod = $merged->required_modules; ok( (grep { 'Cwd' eq $_ } @req_mod), "we got the runtime requirements", ); ok( (grep { 'YAML' eq $_ } @req_mod), "...and the runtime recommendations", ); ok( (! grep { 'Test' eq $_ } @req_mod), "...but not the build requirements", ); } { my $req = $prereq->requirements_for(qw(runtime suggests)); my @req_mod = $req->required_modules; is(@req_mod, 0, "empty set of runtime/suggests requirements"); } { my $req = $prereq->requirements_for(qw(develop suggests)); my @req_mod = $req->required_modules; is(@req_mod, 0, "empty set of develop/suggests requirements"); } { my $new_prereq = CPAN::Meta::Prereqs->new; $new_prereq ->requirements_for(qw(runtime requires)) ->add_minimum(Foo => '1.000'); $new_prereq ->requirements_for(qw(runtime requires)) ->add_minimum(Bar => '2.976'); $new_prereq ->requirements_for(qw(test requires)) ->add_minimum(Baz => '3.1416'); $new_prereq ->requirements_for(qw(build recommends)) ->add_minimum(Bar => '3.000'); my $expect = { runtime => { requires => { Foo => '1.000', Bar => '2.976' } }, test => { requires => { Baz => '3.1416' } }, build => { recommends => { Bar => '3.000' } }, }; is_deeply( $new_prereq->as_string_hash, $expect, 'we can accumulate new requirements on a prereq object', ); my $merged_requires = { Foo => '1.000', Bar => '2.976', Baz => '3.1416', }; my $merged_all = { Foo => '1.000', Bar => '3.000', Baz => '3.1416', }; is_deeply( $new_prereq->merged_requirements( [qw/runtime test build/], [qw/requires/] )->as_string_hash, $merged_requires, "we can merge requirements for phases/types" ); is_deeply( $new_prereq->merged_requirements->as_string_hash, $merged_all, "default merging is runtime/build/test for requires/recommends" ); } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/README-data.txt000644 000765 000024 00000001156 12535707053 016467 0ustar00davidstaff000000 000000 There are three test data directories: - 'data-test': These files are valid META files that test *specific* conversions and are expected to have specific data in them during testing. Do not put new test data here unless you are sure it meets all requirements needed to pass. - 'data-valid': These files are valid META files. Some may be improved by the Converter (particularly upconverting from ancient specs). - 'data-fixable': These files are bad META files that fail validation, but can be fixed via the Converter. - 'data-fail': These files are bad META files that fail validation and can't be fixed. CPAN-Meta-2.150005/t/repository.t000644 000765 000024 00000010517 12535707053 016467 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults # 1.4 repository upgrade { my $label = "(version 1.4) old repository winds up in 'url'"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '1.4', url => 'http://module-build.sourceforge.net/META-spec-v1.4.html', }, resources => { repository => 'http://example.com/', }, }, { lazy_validation => 1 }, ); is_deeply( $meta->resources, { repository => { url => 'http://example.com/', }, }, $label, ); } { my $label = "(version 2 ) http in web passed through unchanged"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '2', }, resources => { repository => { web => 'http://example.com/', }, }, }, { lazy_validation => 1 }, ); is_deeply( $meta->{resources}, { repository => { web => 'http://example.com/', }, }, $label ); } { my $label = "(version 2 ) http in url passed through unchanged"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '2', }, resources => { repository => { url => 'http://example.com/', }, }, }, { lazy_validation => 1 }, ); is_deeply( $meta->{resources}, { repository => { url => 'http://example.com/', }, }, $label ); } { my $label = "(version 2 ) svn in url adds svn type"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '2', }, resources => { repository => { url => 'svn://example.com/', }, }, }, { lazy_validation => 1 }, ); is_deeply( $meta->{resources}, { repository => { url => 'svn://example.com/', type => 'svn', }, }, $label ); } { my $label = "(version 2 ) git in url adds svn type"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '2', }, resources => { repository => { url => 'git://example.com/', }, }, }, { lazy_validation => 1 }, ); is_deeply( $meta->{resources}, { repository => { url => 'git://example.com/', type => 'git', }, }, $label ); } { my $label = "(version 2 ) pre-existing type preserved"; my $meta = CPAN::Meta->new( { name => 'Module-Billed', abstract => 'inscrutable', version => '1', author => 'Joe', release_status => 'stable', license => 'perl_5', dynamic_config => 1, generated_by => 'hand', 'meta-spec' => { version => '2', }, resources => { repository => { url => 'git://example.com/', type => 'msysgit', }, }, }, { lazy_validation => 1 }, ); is_deeply( $meta->{resources}, { repository => { url => 'git://example.com/', type => 'msysgit', }, }, $label ); } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/save-load.t000644 000765 000024 00000007165 12535707053 016130 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use File::Temp 0.20 (); use Parse::CPAN::Meta 1.4400; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults my $distmeta = { name => 'Module-Build', abstract => 'Build and install Perl modules', description => "Module::Build is a system for building, testing, " . "and installing Perl modules. It is meant to be an " . "alternative to ExtUtils::MakeMaker... blah blah blah", version => '0.36', author => [ 'Ken Williams ', 'Module-Build List ', # additional contact ], release_status => 'stable', license => [ 'perl_5' ], prereqs => { runtime => { requires => { 'perl' => '5.006', 'Config' => '0', 'Cwd' => '0', 'Data::Dumper' => '0', 'ExtUtils::Install' => '0', 'File::Basename' => '0', 'File::Compare' => '0', 'File::Copy' => '0', 'File::Find' => '0', 'File::Path' => '0', 'File::Spec' => '0', 'IO::File' => '0', }, recommends => { 'Archive::Tar' => '1.00', 'ExtUtils::Install' => '0.3', 'ExtUtils::ParseXS' => '2.02', 'Pod::Text' => '0', 'YAML' => '0.35', }, }, build => { requires => { 'Test::More' => '0', }, } }, resources => { license => ['http://dev.perl.org/licenses/'], }, optional_features => { domination => { description => 'Take over the world', prereqs => { develop => { requires => { 'Genius::Evil' => '1.234' } }, runtime => { requires => { 'Machine::Weather' => '2.0' } }, }, }, }, dynamic_config => 1, keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', }; my $meta = CPAN::Meta->new( $distmeta ); my $tmpdir = File::Temp->newdir(); my $metafile = File::Spec->catfile( $tmpdir, 'META.json' ); ok( $meta->save($metafile), "save returns true" ); ok( -f $metafile, "save meta to file" ); ok( my $loaded = Parse::CPAN::Meta->load_file($metafile), 'load saved file' ); is($loaded->{name}, 'Module-Build', 'name correct'); like( $loaded->{x_serialization_backend}, qr/\AJSON::PP version [0-9]/, "x_serialization_backend", ); ok( ! exists $meta->{x_serialization_backend}, "we didn't leak x_serialization_backend up into the saved struct", ); ok( $loaded = Parse::CPAN::Meta->load_file('t/data-test/META-1_4.yml'), 'load META-1.4' ); is($loaded->{name}, 'Module-Build', 'name correct'); # Test saving with conversion my $metayml = File::Spec->catfile( $tmpdir, 'META.yml' ); $meta->save($metayml, {version => "1.4"}); ok( -f $metayml, "save meta to META.yml with conversion" ); ok( $loaded = Parse::CPAN::Meta->load_file($metayml), 'load saved file' ); is( $loaded->{name}, 'Module-Build', 'name correct'); is( $loaded->{requires}{perl}, "5.006", 'prereq correct' ); like( $loaded->{x_serialization_backend}, qr/\ACPAN::Meta::YAML version [0-9]/, "x_serialization_backend", ); ok( ! exists $meta->{x_serialization_backend}, "we didn't leak x_serialization_backend up into the saved struct", ); # file without suffix ok( $loaded = CPAN::Meta->load_file('t/data-test/META-2.meta'), 'load_file META-2.meta' ); my $string = do { open my $fh, '<', 't/data-test/META-2.meta'; local $/; <$fh> }; ok( $loaded = CPAN::Meta->load_string($string), 'load META-2.meta from string' ); done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/validator.t000644 000765 000024 00000002231 12535707053 016227 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More 0.88; use CPAN::Meta; use CPAN::Meta::Validator; use File::Spec; use IO::Dir; use Parse::CPAN::Meta 1.4400; delete $ENV{$_} for qw/PERL_JSON_BACKEND PERL_YAML_BACKEND/; # use defaults { my @data_dirs = qw( t/data-test t/data-valid ); my @files = sort map { my $d = $_; map { "$d/$_" } grep { substr($_,0,1) ne '.' } IO::Dir->new($d)->read } @data_dirs; for my $f ( @files ) { my $meta = Parse::CPAN::Meta->load_file( File::Spec->catfile($f) ); my $cmv = CPAN::Meta::Validator->new({%$meta}); ok( $cmv->is_valid, "$f validates" ) or diag( "ERRORS:\n" . join( "\n", $cmv->errors ) ); } } { my @data_dirs = qw( t/data-fail t/data-fixable ); my @files = sort map { my $d = $_; map { "$d/$_" } grep { substr($_,0,1) ne '.' } IO::Dir->new($d)->read } @data_dirs; for my $f ( @files ) { my $meta = Parse::CPAN::Meta->load_file( File::Spec->catfile($f) ); my $cmv = CPAN::Meta::Validator->new({%$meta}); ok( ! $cmv->is_valid, "$f shouldn't validate" ); note 'validation error: ', $_ foreach $cmv->errors; } } done_testing; # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/t/data-valid/1122575719-META.yml000644 000765 000024 00000001127 12535707053 020424 0ustar00davidstaff000000 000000 --- abstract: 'Generate Catalyst application menus' author: - 'David P.C. Wollmann ' build_requires: ExtUtils::MakeMaker: 6.42 Test::More: 0 configure_requires: ExtUtils::MakeMaker: 6.42 distribution_type: module generated_by: 'Module::Install version 0.87' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: CatalystX-Menu-Tree no_index: directory: - inc - t inc: [] requires: Catalyst::Runtime: 0 MRO::Compat: 0 perl: 5.8.0 resources: license: http://dev.perl.org/licenses/ version: 0.02 CPAN-Meta-2.150005/t/data-valid/1206545041-META.yml000644 000765 000024 00000005704 12535707053 020415 0ustar00davidstaff000000 000000 --- name: PDF-Template version: 0.29_02 author: ~ abstract: PDF::Template license: perl requires: Encode: 0.01 PDF::Writer: 0.05 perl: 5.6.0 build_requires: IO::Scalar: 0.01 Test::More: 0.47 provides: PDF::Template: file: lib/PDF/Template.pm version: 0.29_02 PDF::Template::Base: file: lib/PDF/Template/Base.pm version: ~ PDF::Template::Constants: file: lib/PDF/Template/Constants.pm version: ~ PDF::Template::Container: file: lib/PDF/Template/Container.pm version: ~ PDF::Template::Container::Always: file: lib/PDF/Template/Container/Always.pm version: ~ PDF::Template::Container::Conditional: file: lib/PDF/Template/Container/Conditional.pm version: ~ PDF::Template::Container::Font: file: lib/PDF/Template/Container/Font.pm version: ~ PDF::Template::Container::Footer: file: lib/PDF/Template/Container/Footer.pm version: ~ PDF::Template::Container::Header: file: lib/PDF/Template/Container/Header.pm version: ~ PDF::Template::Container::Loop: file: lib/PDF/Template/Container/Loop.pm version: ~ PDF::Template::Container::Margin: file: lib/PDF/Template/Container/Margin.pm version: ~ PDF::Template::Container::PageDef: file: lib/PDF/Template/Container/PageDef.pm version: ~ PDF::Template::Container::PdfTemplate: file: lib/PDF/Template/Container/PdfTemplate.pm version: ~ PDF::Template::Container::Row: file: lib/PDF/Template/Container/Row.pm version: ~ PDF::Template::Container::Scope: file: lib/PDF/Template/Container/Scope.pm version: ~ PDF::Template::Container::Section: file: lib/PDF/Template/Container/Section.pm version: ~ PDF::Template::Context: file: lib/PDF/Template/Context.pm version: ~ PDF::Template::Element: file: lib/PDF/Template/Element.pm version: ~ PDF::Template::Element::Bookmark: file: lib/PDF/Template/Element/Bookmark.pm version: ~ PDF::Template::Element::Circle: file: lib/PDF/Template/Element/Circle.pm version: ~ PDF::Template::Element::HorizontalRule: file: lib/PDF/Template/Element/HorizontalRule.pm version: ~ PDF::Template::Element::Image: file: lib/PDF/Template/Element/Image.pm version: ~ PDF::Template::Element::Line: file: lib/PDF/Template/Element/Line.pm version: ~ PDF::Template::Element::PageBreak: file: lib/PDF/Template/Element/PageBreak.pm version: ~ PDF::Template::Element::TextBox: file: lib/PDF/Template/Element/TextBox.pm version: ~ PDF::Template::Element::Var: file: lib/PDF/Template/Element/Var.pm version: ~ PDF::Template::Element::Weblink: file: lib/PDF/Template/Element/Weblink.pm version: ~ PDF::Template::Factory: file: lib/PDF/Template/Factory.pm version: ~ PDF::Template::Iterator: file: lib/PDF/Template/Iterator.pm version: ~ PDF::Template::TextObject: file: lib/PDF/Template/TextObject.pm version: ~ generated_by: Module::Build version 0.2701 CPAN-Meta-2.150005/t/data-valid/1985684504-META.yml000644 000765 000024 00000001150 12535707053 020432 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: Squatting version: 0.30 abstract: A Camping-inspired Web Microframework for Perl license: mit generated_by: ExtUtils::MakeMaker version 6.36 distribution_type: module requires: Continuity: 0.991 Data::Dump: 0 HTTP::Daemon: 0 JSON::XS: 0 Shell::Perl: 0 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 author: - John BEPPU no_index: - eg - t CPAN-Meta-2.150005/t/data-valid/476602558-META.yml000644 000765 000024 00000001133 12535707053 020344 0ustar00davidstaff000000 000000 --- abstract: 'Benchmarking with statistical confidence' author: - '-2001 Andrew Ho.' build_requires: ExtUtils::MakeMaker: 6.42 Test::More: 0 configure_requires: ExtUtils::MakeMaker: 6.42 distribution_type: module generated_by: 'Module::Install version 0.91' license: gpl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 module_name: Benchmark::Timer name: Benchmark-Timer no_index: delta.pl: [] directory: - inc - t requires: Time::HiRes: 0 perl: 5.005 resources: license: http://opensource.org/licenses/gpl-license.php version: 0.7102 CPAN-Meta-2.150005/t/data-valid/META-1_0.yml000644 000765 000024 00000000247 12535707053 017716 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Template-DBI version: 1.23 CPAN-Meta-2.150005/t/data-valid/META-1_1.yml000644 000765 000024 00000000250 12535707053 017711 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: Class-Virtual version: 1.23 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.1.html version: 1.1 CPAN-Meta-2.150005/t/data-valid/scalar-meta-spec.yml000644 000765 000024 00000001123 12535707053 021726 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec-new.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# meta-spec: 1.1 name: XML-Writer version: 0.600 abstract: Easily generate well-formed, namespace-aware XML. authored_by: - David Megginson - Ed Avis - Joseph Walton license: perl distribution_type: module installdirs: site build_requires: perl: 5.006_000 recommends: perl: 5.008_001 no_index: package: - XML::Writer::Namespaces dynamic_config: 0 generated_by: Hand CPAN-Meta-2.150005/t/data-valid/x_deprecated-META.yml000644 000765 000024 00000004652 12535707053 021772 0ustar00davidstaff000000 000000 --- abstract: 'Author tests making sure correct line endings are used' author: - 'Florian Ragwitz ' - 'Caleb Cushing ' - 'Karen Etheridge ' build_requires: Build::Requires: '1.1' Test::More: '0.88' Test::Requires: '1.2' configure_requires: Module::Build::Tiny: '0.039' perl: '5.006' dynamic_config: 0 generated_by: 'Dist::Zilla version 5.035, CPAN::Meta::Converter version 2.150002' keywords: - plugin - test - testing - author - development - whitespace - newline - linefeed - formatting license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Dist-Zilla-Plugin-Test-EOL no_index: directory: - t - xt provides: Dist::Zilla::Plugin::EOLTests: file: lib/Dist/Zilla/Plugin/EOLTests.pm version: '0.18' x_deprecated: 1 Dist::Zilla::Plugin::Test::EOL: file: lib/Dist/Zilla/Plugin/Test/EOL.pm version: '0.18' requires: Data::Section: '0.004' Dist::Zilla::File::InMemory: '0' Dist::Zilla::Role::FileFinderUser: '0' Dist::Zilla::Role::FileGatherer: '0' Dist::Zilla::Role::FileMunger: '0' Dist::Zilla::Role::PrereqSource: '0' Dist::Zilla::Role::TextTemplate: '0' Moose: '0' Moose::Util::TypeConstraints: '0' Path::Tiny: '0' Sub::Exporter::ForMethods: '0' namespace::autoclean: '0' perl: '5.006' strict: '0' warnings: '0' resources: IRC: irc://irc.perl.org/#distzilla MailingList: http://dzil.org/#mailing-list bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-Test-EOL homepage: https://github.com/karenetheridge/Dist-Zilla-Plugin-Test-EOL repository: https://github.com/karenetheridge/Dist-Zilla-Plugin-Test-EOL.git version: '0.18' x_Dist_Zilla: perl: version: '5.021010' plugins: - class: Dist::Zilla::Plugin::Bootstrap::lib config: Dist::Zilla::Role::Bootstrap: try_built: ~ name: Bootstrap::lib version: '1.001000' - class: Dist::Zilla::Plugin::VerifyPhases name: '@Author::ETHER/PHASE VERIFICATION' version: '0.010' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: '' version: '5.035' x_authority: cpan:FLORA x_authority_from_module: Dist::Zilla::Plugin::Test::EOL x_contributors: - 'Olivier Mengue ' - 'Shlomi Fish ' x_permissions_from_module: Dist::Zilla::Plugin::Test::EOL CPAN-Meta-2.150005/t/data-test/gpl-1_4.yml000644 000765 000024 00000001166 12535707053 017637 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: gpl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 3 CPAN-Meta-2.150005/t/data-test/META-1_0.yml000644 000765 000024 00000000625 12535707053 017576 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Template-DBI version: 2.64 version_from: lib/Template/Plugin/DBI.pm installdirs: site license: perl requires: DBI: 1 Template: 2.15 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 CPAN-Meta-2.150005/t/data-test/META-1_1.yml000644 000765 000024 00000000765 12535707053 017604 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: Class-Virtual version: 0.06 abstract: ~ license: unknown generated_by: ExtUtils::MakeMaker version 6.30_03 author: ~ distribution_type: module requires: Carp::Assert: 0.1 Class::Data::Inheritable: 0.02 Class::ISA: 0.31 Test::More: 0.5 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.1.html version: 1.1 CPAN-Meta-2.150005/t/data-test/META-1_2.yml000644 000765 000024 00000001635 12535707053 017602 0ustar00davidstaff000000 000000 --- name: Test-Harness-Straps version: 0.30 author: - 'Michael G Schwern ' abstract: detailed analysis of test results license: perl resources: license: http://dev.perl.org/licenses/ requires: File::Spec: 0.6 provides: Test::Harness::Assert: file: lib/Test/Harness/Assert.pm version: 0.02 Test::Harness::Iterator: file: lib/Test/Harness/Iterator.pm version: 0.02 Test::Harness::Iterator::ARRAY: file: lib/Test/Harness/Iterator.pm Test::Harness::Iterator::FH: file: lib/Test/Harness/Iterator.pm Test::Harness::Point: file: lib/Test/Harness/Point.pm version: 0.01 Test::Harness::Results: file: lib/Test/Harness/Results.pm version: 0.01 Test::Harness::Straps: file: lib/Test/Harness/Straps.pm version: 0.30 generated_by: Module::Build version 0.280801 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 CPAN-Meta-2.150005/t/data-test/META-1_3.yml000644 000765 000024 00000001207 12535707053 017576 0ustar00davidstaff000000 000000 --- abstract: a modern perl interactive shell author: - Matt S Trout - mst (at) shadowcatsystems.co.uk (L) build_requires: Test::More: 0 distribution_type: module generated_by: Module::Install version 0.67 license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 name: Devel-REPL no_index: directory: - inc - t requires: Data::Dump::Streamer: 0 File::HomeDir: 0 File::Spec: 0 Lexical::Persistence: 0 Moose: 0 MooseX::Getopt: 0 MooseX::Object::Pluggable: 0 Term::ReadLine: 0 namespace::clean: 0 perl: 5.8.1 version: 1.001000 CPAN-Meta-2.150005/t/data-test/META-1_4.yml000644 000765 000024 00000007202 12535707053 017600 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 x-whatever: this is a custom field x_whatelse: so is this XWhatNow: and this CPAN-Meta-2.150005/t/data-test/META-2.json000644 000765 000024 00000004467 12535707053 017540 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5", "bsd" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-test/META-2.meta000644 000765 000024 00000004461 12535707053 017507 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "https://metacpan.org/pod/CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5", "bsd" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-test/preserve-release-status.yml000644 000765 000024 00000000656 12535707053 023271 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Template-DBI version: 2.64 version_from: lib/Template/Plugin/DBI.pm installdirs: site license: perl requires: DBI: 1 Template: 2.15 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 release_status: unstable CPAN-Meta-2.150005/t/data-test/provides-version-missing.json000644 000765 000024 00000005153 12535707053 023631 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "provides" : { "Foo::Bar" : { "file" : "lib/Foo/Bar.pm", "version" : "0.27_02" }, "Foo::Bar::Blah" : { "file" : "lib/Foo/Bar/Blah.pm" }, "Foo::Bar::Baz" : { "file" : "lib/Foo/Bar/Baz.pm", "version" : 0.3 } }, "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-test/resources.yml000644 000765 000024 00000002746 12535707053 020513 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: WWW-Mechanize version: 1.64 abstract: Handy web browsing in a Perl object author: - Andy Lester license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: Carp: 0 File::Temp: 0 FindBin: 0 Getopt::Long: 0 HTML::Form: 1.038 HTML::HeadParser: 0 HTML::Parser: 3.33 HTML::TokeParser: 2.28 HTTP::Daemon: 0 HTTP::Request: 1.3 HTTP::Server::Simple: 0.35 HTTP::Server::Simple::CGI: 0 HTTP::Status: 0 LWP: 5.829 LWP::UserAgent: 5.829 perl: 5.008 Pod::Usage: 0 Test::More: 0.34 Test::Warn: 0.11 URI: 1.36 URI::file: 0 URI::URL: 0 resources: bugtracker: http://code.google.com/p/www-mechanize/issues/list homepage: http://code.google.com/p/www-mechanize/ license: http://dev.perl.org/licenses/ MailingList: http://groups.google.com/group/www-mechanize-users Repository: http://code.google.com/p/www-mechanize/source no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.56 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 CPAN-Meta-2.150005/t/data-test/restricted-2.json000644 000765 000024 00000004456 12535707053 021160 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "restricted" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-test/restrictive-1_4.yml000644 000765 000024 00000007211 12535707053 021415 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: restrictive meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 x-whatever: this is a custom field x_whatelse: so is this XWhatNow: and this CPAN-Meta-2.150005/t/data-test/unicode.yml000644 000765 000024 00000007203 12535707053 020120 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williåms ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 x-whatever: this is a custom field x_whatelse: so is this XWhatNow: and this CPAN-Meta-2.150005/t/data-test/version-not-normal.json000644 000765 000024 00000002340 12535707053 022410 0ustar00davidstaff000000 000000 { "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "== 2.21", "IO::File" : "> 1.12", "Data::Dumper" : ">= 1", "File::Spec" : "< 5", "File::Find" : "v0.1", "File::Path" : "1.0.0", "Module::Metadata" : ">= v1.0.2, <= v1.0.10" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } } } CPAN-Meta-2.150005/t/data-test/version-ranges-1_4.yml000644 000765 000024 00000001322 12535707053 022011 0ustar00davidstaff000000 000000 --- abstract: stuff author: - 'Ken Williams ' - 'Module-Build List ' description: 'Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah' dynamic_config: 1 generated_by: 'Module::Build version 0.36' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build build_requires: Build::Requires: 1.1 Test::More: 0 requires: Data::Dumper: '>= 1' File::Copy: '== 2.21' File::Find: '>1, != 1.19' File::Path: 0 File::Spec: '< 5' IO::File: '> 1.12' Module::Metadata: '>= v1.0.2, <= v1.0.10' version: 0.36 CPAN-Meta-2.150005/t/data-test/version-ranges-2.json000644 000765 000024 00000002343 12535707053 021743 0ustar00davidstaff000000 000000 { "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "== 2.21", "IO::File" : "> 1.12", "Data::Dumper" : ">= 1", "File::Spec" : "< 5", "File::Find" : ">1, != 1.19", "File::Path" : "0", "Module::Metadata" : ">= v1.0.2, <= v1.0.10" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } } } CPAN-Meta-2.150005/t/data-test/x_deprecated-META.json000644 000765 000024 00000010224 12535707053 022012 0ustar00davidstaff000000 000000 { "abstract" : "Author tests making sure correct line endings are used", "author" : [ "Florian Ragwitz ", "Caleb Cushing ", "Karen Etheridge " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.035, CPAN::Meta::Converter version 2.150002", "keywords" : [ "plugin", "test", "testing", "author", "development", "whitespace", "newline", "linefeed", "formatting" ], "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Dist-Zilla-Plugin-Test-EOL", "no_index" : { "directory" : [ "t", "xt" ] }, "prereqs" : { "configure" : { "requires" : { "Module::Build::Tiny" : "0.039", "perl" : "5.006" } }, "develop" : { "recommends" : { "Dist::Zilla::PluginBundle::Author::ETHER" : "0.092" }, "requires" : { "Dist::Zilla" : "5" } }, "runtime" : { "requires" : { "Data::Section" : "0.004", "Dist::Zilla::File::InMemory" : "0", "Dist::Zilla::Role::FileFinderUser" : "0", "Dist::Zilla::Role::FileGatherer" : "0", "Dist::Zilla::Role::FileMunger" : "0", "Dist::Zilla::Role::PrereqSource" : "0", "Dist::Zilla::Role::TextTemplate" : "0", "Moose" : "0", "Moose::Util::TypeConstraints" : "0", "Path::Tiny" : "0", "Sub::Exporter::ForMethods" : "0", "namespace::autoclean" : "0", "perl" : "5.006", "strict" : "0", "warnings" : "0" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "provides" : { "Dist::Zilla::Plugin::EOLTests" : { "file" : "lib/Dist/Zilla/Plugin/EOLTests.pm", "version" : "0.18", "x_deprecated" : 1 }, "Dist::Zilla::Plugin::Test::EOL" : { "file" : "lib/Dist/Zilla/Plugin/Test/EOL.pm", "version" : "0.18" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "mailto" : "bug-Dist-Zilla-Plugin-Test-EOL@rt.cpan.org", "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Zilla-Plugin-Test-EOL" }, "homepage" : "https://github.com/karenetheridge/Dist-Zilla-Plugin-Test-EOL", "repository" : { "type" : "git", "url" : "https://github.com/karenetheridge/Dist-Zilla-Plugin-Test-EOL.git", "web" : "https://github.com/karenetheridge/Dist-Zilla-Plugin-Test-EOL" }, "x_IRC" : "irc://irc.perl.org/#distzilla", "x_MailingList" : "http://dzil.org/#mailing-list" }, "version" : "0.18", "x_Dist_Zilla" : { "perl" : { "version" : "5.021010" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::Bootstrap::lib", "config" : { "Dist::Zilla::Role::Bootstrap" : { "try_built" : null } }, "name" : "Bootstrap::lib", "version" : "1.001000" }, { "class" : "Dist::Zilla::Plugin::VerifyPhases", "name" : "@Author::ETHER/PHASE VERIFICATION", "version" : "0.010" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : "" }, "version" : "5.035" } }, "x_authority" : "cpan:FLORA", "x_authority_from_module" : "Dist::Zilla::Plugin::Test::EOL", "x_contributors" : [ "Olivier Mengue ", "Shlomi Fish " ], "x_permissions_from_module" : "Dist::Zilla::Plugin::Test::EOL" } CPAN-Meta-2.150005/t/data-fixable/107650337-META.yml000644 000765 000024 00000001121 12535707053 020641 0ustar00davidstaff000000 000000 --- name: FabForce-DBDesigner4-DBIC version: 0.0802 author: - 'Renee Baecker ' abstract: create DBIC scheme for DBDesigner4 xml file license: artistic2 requires: FabForce::DBDesigner4: 0.3 File::Spec: 3.12 build_requires: Carp: 0 Test::CheckManifest: 1 Test::More: 0 generated_by: Module::Build version 0.2808 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 provides: FabForce::DBDesigner4::DBIC: file: lib/FabForce/DBDesigner4/DBIC.pm version: 0.0802 resources: license: http://dev.perl.org/licenses/ CPAN-Meta-2.150005/t/data-fixable/1598804075-META.yml000644 000765 000024 00000001200 12535707053 020736 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: XML-RDB version: 1.3 version_from: RDB.pm installdirs: site requires: Data::Dumper: 0 DBI: 1.35 DBIx::DBSchema: .16 DBIx::Recordset: .23 DBIx::Sequence: .04 Getopt::Std: 0 IO::File: 1.08 URI::Escape: 3.16 XML::DOM: 1.29 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.30 CPAN-Meta-2.150005/t/data-fixable/1927486199-META.yml000644 000765 000024 00000000716 12535707053 020762 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: WWW-phpBB-Mod-Installer version: 0.03 version_from: lib/WWW/phpBB/Mod/Installer.pm installdirs: site requires: DBD::mysql: 3.0002 DBI: 1.5 XML::Xerces: -4 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.30 CPAN-Meta-2.150005/t/data-fixable/1985980974-META.yml000644 000765 000024 00000001021 12535707053 020754 0ustar00davidstaff000000 000000 --- abstract: 'A Form::Sensible::Form::Reflector subclass to reflect off of DBIC schema classes' author: - 'Devin Austin ' generated_by: 'Dist::Zilla version 1.100160' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Form-Sensible-Reflector-DBIC requires: DBIx::Class: "\"\"" Data::Dumper: "\"\"" DateTime: "\"\"" ExtUtils::MakeMaker: 6.11 Form::Sensible: "\"\"" Moose: 0.93 SQL::Translator: 0.11002 Test::Simple: 0.88 version: 0.0341 CPAN-Meta-2.150005/t/data-fixable/2031017050-META.yml000644 000765 000024 00000001235 12535707053 020712 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: Forks-Super version: 0.16 abstract: extensions and convenience methods for managing background processes. author: - Marty O'Brien license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: Test::More: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.55_02 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 recommends: - Time::HiRes - 0 - YAML - 0 - Win32::Process - 0 CPAN-Meta-2.150005/t/data-fixable/284247103-META.yml000644 000765 000024 00000002454 12535707053 020652 0ustar00davidstaff000000 000000 --- #YAML:1.0 meta-spec: version: 1.2 url: http://module-build.sourceforge.net/META-spec-v1.2.html name: Daizu version: 0.3 abstract: Web publishing system built on Subversion license: gpl resources: homepage: http://www.daizucms.org/ license: http://www.gnu.org/licenses/gpl.html author: - 'Geoff Richards ' requires: Carp::Assert: 0 Compress::Zlib: 0 DBD::Pg: 0 DateTime: 0 DateTime::Format::Pg: 0.08 Digest::SHA1: 0 File::MMagic: 0 HTML::Entities: 1.32 HTML::Parser: 0 HTML::Tagset: 0 Image::Size: 0 Math::Round: 0.03 Path::Class: 0.02 SVN::Ra: 0 Template: 2.15 URI: 0 XML::LibXML: 1.59 build_requires: Module::Build: 0 optional_features: - syntax-highlight: description: Automatically syntax-highlight example code in articles requires: Text::VimColor: 0.09 - picture-article: description: Publish pictures as articles, with automatic thumbnails requires: Image::Magick: 0 - related-links: description: Add a Related Links box to pages for articles requires: Template::Plugin::Class: 0 no_index: file: - test-repos.dump dynamic_config: 0 generated_by: Geoff Richards # vi:ts=4 sw=4 expandtab CPAN-Meta-2.150005/t/data-fixable/344981821-META.yml000644 000765 000024 00000001014 12535707053 020652 0ustar00davidstaff000000 000000 --- abstract: '' author: - 'Tokuhiro Matsuno C<< >>' build_requires: Class::DBI: 0 Class::DBI::Pager: 0 Sledge::TestPages: 0 Test::Base: 0 Test::More: 0 YAML: 0 distribution_type: module generated_by: 'Module::Install version 0.75' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 name: Sledge-Plugin-Pager no_index: directory: - inc - t requires: Lingua::EN::Inflect: 0 String::CamelCase: 0 version: 0.02 CPAN-Meta-2.150005/t/data-fixable/35478989-META.yml000644 000765 000024 00000001025 12535707053 020611 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: oEdtk version: 0.42 abstract: ~ license: ~ author: ~ generated_by: ExtUtils::MakeMaker version 6.44 distribution_type: module requires: Config::IniFiles: 2.3 DBI: 1.6 Spreadsheet::WriteExcel: 1 Sys::Hostname: Digest::MD5 Term::ReadKey: POSIX meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 CPAN-Meta-2.150005/t/data-fixable/98042513-META.yml000644 000765 000024 00000001047 12535707053 020570 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Apache-ErrorControl version: 1.026 version_from: ErrorControl.pm installdirs: site requires: Apache::Constants: 1.09 Apache::File: 1.01 Apache::Request: 1.1 Class::Date:  HTML::Template::Set: 1.01 MIME::Entity: 5.404 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 CPAN-Meta-2.150005/t/data-fixable/invalid-meta-spec-version.json000644 000765 000024 00000004453 12535707053 024266 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "99", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-fixable/invalid-meta-spec-version.yml000644 000765 000024 00000007200 12535707053 024107 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: X name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 x-whatever: this is a custom field x_whatelse: so is this XWhatNow: and this CPAN-Meta-2.150005/t/data-fixable/META-1_2.yml000644 000765 000024 00000001561 12535707053 020233 0ustar00davidstaff000000 000000 --- name: Test-Harness-Straps version: 0.30 author: - 'Michael G Schwern ' license: perl resources: license: http://dev.perl.org/licenses/ requires: File::Spec: 0.6 provides: Test::Harness::Assert: file: lib/Test/Harness/Assert.pm version: 0.02 Test::Harness::Iterator: file: lib/Test/Harness/Iterator.pm version: 0.02 Test::Harness::Iterator::ARRAY: file: lib/Test/Harness/Iterator.pm Test::Harness::Iterator::FH: file: lib/Test/Harness/Iterator.pm Test::Harness::Point: file: lib/Test/Harness/Point.pm version: 0.01 Test::Harness::Results: file: lib/Test/Harness/Results.pm version: 0.01 Test::Harness::Straps: file: lib/Test/Harness/Straps.pm version: 0.30 generated_by: Module::Build version 0.280801 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 CPAN-Meta-2.150005/t/data-fixable/META-1_3.yml000644 000765 000024 00000001202 12535707053 020224 0ustar00davidstaff000000 000000 --- abstract: a modern perl interactive shell author: Matt S Trout - mst (at) shadowcatsystems.co.uk (L) build_requires: Test::More: 0 distribution_type: module generated_by: Module::Install version 0.67 license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 name: Devel-REPL no_index: directory: - inc - t requires: Data::Dump::Streamer: 0 File::HomeDir: 0 File::Spec: 0 Lexical::Persistence: 0 Moose: 0 MooseX::Getopt: 0 MooseX::Object::Pluggable: 0 Term::ReadLine: 0 namespace::clean: 0 perl: 5.8.1 version: 1.001000 CPAN-Meta-2.150005/t/data-fixable/META-1_4.yml000644 000765 000024 00000007012 12535707053 020232 0ustar00davidstaff000000 000000 --- author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 CPAN-Meta-2.150005/t/data-fixable/META-2.json000644 000765 000024 00000003700 12535707053 020160 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ] }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Test::More" : "0" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules" } CPAN-Meta-2.150005/t/data-fixable/meta-spec-version-trailing-zeros.json000644 000765 000024 00000004454 12535707053 025612 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2.0", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-fixable/meta-spec-version-trailing-zeros.yml000644 000765 000024 00000007204 12535707053 025436 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.400 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ version: 0.36_08 x-whatever: this is a custom field x_whatelse: so is this XWhatNow: and this CPAN-Meta-2.150005/t/data-fixable/restrictive-2.json000644 000765 000024 00000004457 12535707053 022007 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "svn://repo.example.com/foo-bar#fakeanchor", "web" : "http://www.example.com" } }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "restrictive" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Build::Requires": "1.1", "Test::More" : "0" } }, "test" : { "requires" : { "Test::More" : "0.88", "Test::Requires" : "1.2" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules", "x_whatever" : "Custom key" } CPAN-Meta-2.150005/t/data-fixable/version-ranges-2.json000644 000765 000024 00000001474 12535707053 022402 0ustar00davidstaff000000 000000 { "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "abstract" : "stuff", "version" : "0.36", "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "prereqs" : { "runtime" : { "requires" : { "IO::File" : "1.23beta", "Data::Dumper" : "<= v1.2.a.3", "File::Spec" : "== mu" } } } } CPAN-Meta-2.150005/t/data-fail/META-1_0.yml000644 000765 000024 00000000602 12535707053 017525 0ustar00davidstaff000000 000000 # http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Template-DBI version_from: lib/Template/Plugin/DBI.pm installdirs: site license: perl requires: DBI: 1 Template: 2.15 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 CPAN-Meta-2.150005/t/data-fail/META-1_1.yml000644 000765 000024 00000000733 12535707053 017533 0ustar00davidstaff000000 000000 --- #YAML:1.0 name: Class-Virtual abstract: ~ license: unknown generated_by: ExtUtils::MakeMaker version 6.30_03 author: ~ distribution_type: module requires: Carp::Assert: 0.1 Class::Data::Inheritable: 0.02 Class::ISA: 0.31 Test::More: 0.5 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.1.html version: 1.1 CPAN-Meta-2.150005/t/data-fail/META-1_2.yml000644 000765 000024 00000001617 12535707053 017536 0ustar00davidstaff000000 000000 --- name: Test-Harness-Straps author: - 'Michael G Schwern ' abstract: detailed analysis of test results license: perl resources: license: http://dev.perl.org/licenses/ requires: File::Spec: 0.6 provides: Test::Harness::Assert: file: lib/Test/Harness/Assert.pm version: 0.02 Test::Harness::Iterator: file: lib/Test/Harness/Iterator.pm version: 0.02 Test::Harness::Iterator::ARRAY: file: lib/Test/Harness/Iterator.pm Test::Harness::Iterator::FH: file: lib/Test/Harness/Iterator.pm Test::Harness::Point: file: lib/Test/Harness/Point.pm version: 0.01 Test::Harness::Results: file: lib/Test/Harness/Results.pm version: 0.01 Test::Harness::Straps: file: lib/Test/Harness/Straps.pm version: 0.30 generated_by: Module::Build version 0.280801 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 CPAN-Meta-2.150005/t/data-fail/META-1_3.yml000644 000765 000024 00000001165 12535707053 017535 0ustar00davidstaff000000 000000 --- abstract: a modern perl interactive shell author: - Matt S Trout - mst (at) shadowcatsystems.co.uk (L) build_requires: Test::More: 0 distribution_type: module generated_by: Module::Install version 0.67 license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 name: Devel-REPL no_index: directory: - inc - t requires: Data::Dump::Streamer: 0 File::HomeDir: 0 File::Spec: 0 Lexical::Persistence: 0 Moose: 0 MooseX::Getopt: 0 MooseX::Object::Pluggable: 0 Term::ReadLine: 0 namespace::clean: 0 perl: 5.8.1 CPAN-Meta-2.150005/t/data-fail/META-1_4.yml000644 000765 000024 00000007045 12535707053 017541 0ustar00davidstaff000000 000000 --- abstract: 'Build and install Perl modules' author: - 'Ken Williams ' - "Development questions, bug reports, and patches should be sent to the\nModule-Build mailing list at ." build_requires: File::Temp: 0.15 Test::Harness: 3.16 Test::More: 0.49 generated_by: 'Module::Build version 0.3608' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Build provides: Module::Build: file: lib/Module/Build.pm version: 0.36_08 Module::Build::Base: file: lib/Module/Build/Base.pm version: 0.36_08 Module::Build::Compat: file: lib/Module/Build/Compat.pm version: 0.36_08 Module::Build::Config: file: lib/Module/Build/Config.pm version: 0.36_08 Module::Build::Cookbook: file: lib/Module/Build/Cookbook.pm version: 0.36_08 Module::Build::Dumper: file: lib/Module/Build/Dumper.pm version: 0.36_08 Module::Build::ModuleInfo: file: lib/Module/Build/ModuleInfo.pm version: 0.36_08 Module::Build::Notes: file: lib/Module/Build/Notes.pm version: 0.36_08 Module::Build::PPMMaker: file: lib/Module/Build/PPMMaker.pm version: 0.36_08 Module::Build::Platform::Amiga: file: lib/Module/Build/Platform/Amiga.pm version: 0.36_08 Module::Build::Platform::Default: file: lib/Module/Build/Platform/Default.pm version: 0.36_08 Module::Build::Platform::EBCDIC: file: lib/Module/Build/Platform/EBCDIC.pm version: 0.36_08 Module::Build::Platform::MPEiX: file: lib/Module/Build/Platform/MPEiX.pm version: 0.36_08 Module::Build::Platform::MacOS: file: lib/Module/Build/Platform/MacOS.pm version: 0.36_08 Module::Build::Platform::RiscOS: file: lib/Module/Build/Platform/RiscOS.pm version: 0.36_08 Module::Build::Platform::Unix: file: lib/Module/Build/Platform/Unix.pm version: 0.36_08 Module::Build::Platform::VMS: file: lib/Module/Build/Platform/VMS.pm version: 0.36_08 Module::Build::Platform::VOS: file: lib/Module/Build/Platform/VOS.pm version: 0.36_08 Module::Build::Platform::Windows: file: lib/Module/Build/Platform/Windows.pm version: 0.36_08 Module::Build::Platform::aix: file: lib/Module/Build/Platform/aix.pm version: 0.36_08 Module::Build::Platform::cygwin: file: lib/Module/Build/Platform/cygwin.pm version: 0.36_08 Module::Build::Platform::darwin: file: lib/Module/Build/Platform/darwin.pm version: 0.36_08 Module::Build::Platform::os2: file: lib/Module/Build/Platform/os2.pm version: 0.36_08 Module::Build::PodParser: file: lib/Module/Build/PodParser.pm version: 0.36_08 Module::Build::Version: file: lib/Module/Build/Version.pm version: 0.77 Module::Build::YAML: file: lib/Module/Build/YAML.pm version: 1.40 inc::latest: file: lib/inc/latest.pm version: 0.36_08 inc::latest::private: file: lib/inc/latest/private.pm version: 0.36_08 recommends: ExtUtils::Install: 0.3 ExtUtils::Manifest: 1.54 version: 0.74 requires: Cwd: 0 Data::Dumper: 0 ExtUtils::CBuilder: 0.27 ExtUtils::Install: 0 ExtUtils::Manifest: 0 ExtUtils::Mkbootstrap: 0 ExtUtils::ParseXS: 2.21 File::Basename: 0 File::Compare: 0 File::Copy: 0 File::Find: 0 File::Path: 0 File::Spec: 0.82 Getopt::Long: 0 IO::File: 0 Test::Harness: 0 Text::Abbrev: 0 Text::ParseWords: 0 perl: 5.006001 resources: MailingList: mailto:module-build@perl.org license: http://dev.perl.org/licenses/ repository: http://github.com/dagolden/module-build/ CPAN-Meta-2.150005/t/data-fail/META-2.json000644 000765 000024 00000003702 12535707053 017463 0ustar00davidstaff000000 000000 { "resources" : { "license" : [ "http://dev.perl.org/licenses/" ] }, "generated_by" : "Module::Build version 0.36", "meta-spec" : { "version" : "2", "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" }, "name" : "Module-Build", "dynamic_config" : 1, "author" : [ "Ken Williams ", "Module-Build List " ], "release_status" : "stable", "license" : [ "perl_5" ], "description" : "Module::Build is a system for building, testing, and installing Perl modules. It is meant to be an alternative to ExtUtils::MakeMaker... blah blah blah", "keywords" : [ "toolchain", "cpan", "dual-life" ], "prereqs" : { "runtime" : { "requires" : { "File::Copy" : "0", "IO::File" : "0", "Data::Dumper" : "0", "File::Spec" : "0", "Config" : "0", "ExtUtils::Install" : "0", "perl" : "5.006", "File::Compare" : "0", "File::Find" : "0", "File::Path" : "0", "File::Basename" : "0", "Cwd" : "0" }, "recommends" : { "YAML" : "0.35", "ExtUtils::ParseXS" : "2.02", "Pod::Text" : "0", "ExtUtils::Install" : "0.3", "Archive::Tar" : "1.00" } }, "build" : { "requires" : { "Test::More" : "0" } } }, "optional_features" : { "domination" : { "prereqs" : { "develop" : { "requires" : { "Genius::Evil" : "1.234" } }, "runtime" : { "requires" : { "Machine::Weather" : "2.0" } } }, "description" : "Take over the world" } }, "abstract" : "Build and install Perl modules" } CPAN-Meta-2.150005/lib/CPAN/000755 000765 000024 00000000000 12535707053 015103 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/lib/CPAN/Meta/000755 000765 000024 00000000000 12535707053 015771 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/lib/CPAN/Meta.pm000644 000765 000024 00000072376 12535707053 016346 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; package CPAN::Meta; our $VERSION = '2.150005'; #pod =head1 SYNOPSIS #pod #pod use v5.10; #pod use strict; #pod use warnings; #pod use CPAN::Meta; #pod use Module::Load; #pod #pod my $meta = CPAN::Meta->load_file('META.json'); #pod #pod printf "testing requirements for %s version %s\n", #pod $meta->name, #pod $meta->version; #pod #pod my $prereqs = $meta->effective_prereqs; #pod #pod for my $phase ( qw/configure runtime build test/ ) { #pod say "Requirements for $phase:"; #pod my $reqs = $prereqs->requirements_for($phase, "requires"); #pod for my $module ( sort $reqs->required_modules ) { #pod my $status; #pod if ( eval { load $module unless $module eq 'perl'; 1 } ) { #pod my $version = $module eq 'perl' ? $] : $module->VERSION; #pod $status = $reqs->accepts_module($module, $version) #pod ? "$version ok" : "$version not ok"; #pod } else { #pod $status = "missing" #pod }; #pod say " $module ($status)"; #pod } #pod } #pod #pod =head1 DESCRIPTION #pod #pod Software distributions released to the CPAN include a F or, for #pod older distributions, F, which describes the distribution, its #pod contents, and the requirements for building and installing the distribution. #pod The data structure stored in the F file is described in #pod L. #pod #pod CPAN::Meta provides a simple class to represent this distribution metadata (or #pod I), along with some helpful methods for interrogating that data. #pod #pod The documentation below is only for the methods of the CPAN::Meta object. For #pod information on the meaning of individual fields, consult the spec. #pod #pod =cut use Carp qw(carp croak); use CPAN::Meta::Feature; use CPAN::Meta::Prereqs; use CPAN::Meta::Converter; use CPAN::Meta::Validator; use Parse::CPAN::Meta 1.4414 (); BEGIN { *_dclone = \&CPAN::Meta::Converter::_dclone } #pod =head1 STRING DATA #pod #pod The following methods return a single value, which is the value for the #pod corresponding entry in the distmeta structure. Values should be either undef #pod or strings. #pod #pod =for :list #pod * abstract #pod * description #pod * dynamic_config #pod * generated_by #pod * name #pod * release_status #pod * version #pod #pod =cut BEGIN { my @STRING_READERS = qw( abstract description dynamic_config generated_by name release_status version ); no strict 'refs'; for my $attr (@STRING_READERS) { *$attr = sub { $_[0]{ $attr } }; } } #pod =head1 LIST DATA #pod #pod These methods return lists of string values, which might be represented in the #pod distmeta structure as arrayrefs or scalars: #pod #pod =for :list #pod * authors #pod * keywords #pod * licenses #pod #pod The C and C methods may also be called as C and #pod C, respectively, to match the field name in the distmeta structure. #pod #pod =cut BEGIN { my @LIST_READERS = qw( author keywords license ); no strict 'refs'; for my $attr (@LIST_READERS) { *$attr = sub { my $value = $_[0]{ $attr }; croak "$attr must be called in list context" unless wantarray; return @{ _dclone($value) } if ref $value; return $value; }; } } sub authors { $_[0]->author } sub licenses { $_[0]->license } #pod =head1 MAP DATA #pod #pod These readers return hashrefs of arbitrary unblessed data structures, each #pod described more fully in the specification: #pod #pod =for :list #pod * meta_spec #pod * resources #pod * provides #pod * no_index #pod * prereqs #pod * optional_features #pod #pod =cut BEGIN { my @MAP_READERS = qw( meta-spec resources provides no_index prereqs optional_features ); no strict 'refs'; for my $attr (@MAP_READERS) { (my $subname = $attr) =~ s/-/_/; *$subname = sub { my $value = $_[0]{ $attr }; return _dclone($value) if $value; return {}; }; } } #pod =head1 CUSTOM DATA #pod #pod A list of custom keys are available from the C method and #pod particular keys may be retrieved with the C method. #pod #pod say $meta->custom($_) for $meta->custom_keys; #pod #pod If a custom key refers to a data structure, a deep clone is returned. #pod #pod =cut sub custom_keys { return grep { /^x_/i } keys %{$_[0]}; } sub custom { my ($self, $attr) = @_; my $value = $self->{$attr}; return _dclone($value) if ref $value; return $value; } #pod =method new #pod #pod my $meta = CPAN::Meta->new($distmeta_struct, \%options); #pod #pod Returns a valid CPAN::Meta object or dies if the supplied metadata hash #pod reference fails to validate. Older-format metadata will be up-converted to #pod version 2 if they validate against the original stated specification. #pod #pod It takes an optional hashref of options. Valid options include: #pod #pod =over #pod #pod =item * #pod #pod lazy_validation -- if true, new will attempt to convert the given metadata #pod to version 2 before attempting to validate it. This means than any #pod fixable errors will be handled by CPAN::Meta::Converter before validation. #pod (Note that this might result in invalid optional data being silently #pod dropped.) The default is false. #pod #pod =back #pod #pod =cut sub _new { my ($class, $struct, $options) = @_; my $self; if ( $options->{lazy_validation} ) { # try to convert to a valid structure; if succeeds, then return it my $cmc = CPAN::Meta::Converter->new( $struct ); $self = $cmc->convert( version => 2 ); # valid or dies return bless $self, $class; } else { # validate original struct my $cmv = CPAN::Meta::Validator->new( $struct ); unless ( $cmv->is_valid) { die "Invalid metadata structure. Errors: " . join(", ", $cmv->errors) . "\n"; } } # up-convert older spec versions my $version = $struct->{'meta-spec'}{version} || '1.0'; if ( $version == 2 ) { $self = $struct; } else { my $cmc = CPAN::Meta::Converter->new( $struct ); $self = $cmc->convert( version => 2 ); } return bless $self, $class; } sub new { my ($class, $struct, $options) = @_; my $self = eval { $class->_new($struct, $options) }; croak($@) if $@; return $self; } #pod =method create #pod #pod my $meta = CPAN::Meta->create($distmeta_struct, \%options); #pod #pod This is same as C, except that C and C fields #pod will be generated if not provided. This means the metadata structure is #pod assumed to otherwise follow the latest L. #pod #pod =cut sub create { my ($class, $struct, $options) = @_; my $version = __PACKAGE__->VERSION || 2; $struct->{generated_by} ||= __PACKAGE__ . " version $version" ; $struct->{'meta-spec'}{version} ||= int($version); my $self = eval { $class->_new($struct, $options) }; croak ($@) if $@; return $self; } #pod =method load_file #pod #pod my $meta = CPAN::Meta->load_file($distmeta_file, \%options); #pod #pod Given a pathname to a file containing metadata, this deserializes the file #pod according to its file suffix and constructs a new C object, just #pod like C. It will die if the deserialized version fails to validate #pod against its stated specification version. #pod #pod It takes the same options as C but C defaults to #pod true. #pod #pod =cut sub load_file { my ($class, $file, $options) = @_; $options->{lazy_validation} = 1 unless exists $options->{lazy_validation}; croak "load_file() requires a valid, readable filename" unless -r $file; my $self; eval { my $struct = Parse::CPAN::Meta->load_file( $file ); $self = $class->_new($struct, $options); }; croak($@) if $@; return $self; } #pod =method load_yaml_string #pod #pod my $meta = CPAN::Meta->load_yaml_string($yaml, \%options); #pod #pod This method returns a new CPAN::Meta object using the first document in the #pod given YAML string. In other respects it is identical to C. #pod #pod =cut sub load_yaml_string { my ($class, $yaml, $options) = @_; $options->{lazy_validation} = 1 unless exists $options->{lazy_validation}; my $self; eval { my ($struct) = Parse::CPAN::Meta->load_yaml_string( $yaml ); $self = $class->_new($struct, $options); }; croak($@) if $@; return $self; } #pod =method load_json_string #pod #pod my $meta = CPAN::Meta->load_json_string($json, \%options); #pod #pod This method returns a new CPAN::Meta object using the structure represented by #pod the given JSON string. In other respects it is identical to C. #pod #pod =cut sub load_json_string { my ($class, $json, $options) = @_; $options->{lazy_validation} = 1 unless exists $options->{lazy_validation}; my $self; eval { my $struct = Parse::CPAN::Meta->load_json_string( $json ); $self = $class->_new($struct, $options); }; croak($@) if $@; return $self; } #pod =method load_string #pod #pod my $meta = CPAN::Meta->load_string($string, \%options); #pod #pod If you don't know if a string contains YAML or JSON, this method will use #pod L to guess. In other respects it is identical to #pod C. #pod #pod =cut sub load_string { my ($class, $string, $options) = @_; $options->{lazy_validation} = 1 unless exists $options->{lazy_validation}; my $self; eval { my $struct = Parse::CPAN::Meta->load_string( $string ); $self = $class->_new($struct, $options); }; croak($@) if $@; return $self; } #pod =method save #pod #pod $meta->save($distmeta_file, \%options); #pod #pod Serializes the object as JSON and writes it to the given file. The only valid #pod option is C, which defaults to '2'. On Perl 5.8.1 or later, the file #pod is saved with UTF-8 encoding. #pod #pod For C 2 (or higher), the filename should end in '.json'. L #pod is the default JSON backend. Using another JSON backend requires L 2.5 or #pod later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate #pod backend like L. #pod #pod For C less than 2, the filename should end in '.yml'. #pod L is used to generate an older metadata structure, which #pod is serialized to YAML. CPAN::Meta::YAML is the default YAML backend. You may #pod set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though #pod this is not recommended due to subtle incompatibilities between YAML parsers on #pod CPAN. #pod #pod =cut sub save { my ($self, $file, $options) = @_; my $version = $options->{version} || '2'; my $layer = $] ge '5.008001' ? ':utf8' : ''; if ( $version ge '2' ) { carp "'$file' should end in '.json'" unless $file =~ m{\.json$}; } else { carp "'$file' should end in '.yml'" unless $file =~ m{\.yml$}; } my $data = $self->as_string( $options ); open my $fh, ">$layer", $file or die "Error opening '$file' for writing: $!\n"; print {$fh} $data; close $fh or die "Error closing '$file': $!\n"; return 1; } #pod =method meta_spec_version #pod #pod This method returns the version part of the C entry in the distmeta #pod structure. It is equivalent to: #pod #pod $meta->meta_spec->{version}; #pod #pod =cut sub meta_spec_version { my ($self) = @_; return $self->meta_spec->{version}; } #pod =method effective_prereqs #pod #pod my $prereqs = $meta->effective_prereqs; #pod #pod my $prereqs = $meta->effective_prereqs( \@feature_identifiers ); #pod #pod This method returns a L object describing all the #pod prereqs for the distribution. If an arrayref of feature identifiers is given, #pod the prereqs for the identified features are merged together with the #pod distribution's core prereqs before the CPAN::Meta::Prereqs object is returned. #pod #pod =cut sub effective_prereqs { my ($self, $features) = @_; $features ||= []; my $prereq = CPAN::Meta::Prereqs->new($self->prereqs); return $prereq unless @$features; my @other = map {; $self->feature($_)->prereqs } @$features; return $prereq->with_merged_prereqs(\@other); } #pod =method should_index_file #pod #pod ... if $meta->should_index_file( $filename ); #pod #pod This method returns true if the given file should be indexed. It decides this #pod by checking the C and C keys in the C property of #pod the distmeta structure. Note that neither the version format nor #pod C are considered. #pod #pod C<$filename> should be given in unix format. #pod #pod =cut sub should_index_file { my ($self, $filename) = @_; for my $no_index_file (@{ $self->no_index->{file} || [] }) { return if $filename eq $no_index_file; } for my $no_index_dir (@{ $self->no_index->{directory} }) { $no_index_dir =~ s{$}{/} unless $no_index_dir =~ m{/\z}; return if index($filename, $no_index_dir) == 0; } return 1; } #pod =method should_index_package #pod #pod ... if $meta->should_index_package( $package ); #pod #pod This method returns true if the given package should be indexed. It decides #pod this by checking the C and C keys in the C #pod property of the distmeta structure. Note that neither the version format nor #pod C are considered. #pod #pod =cut sub should_index_package { my ($self, $package) = @_; for my $no_index_pkg (@{ $self->no_index->{package} || [] }) { return if $package eq $no_index_pkg; } for my $no_index_ns (@{ $self->no_index->{namespace} }) { return if index($package, "${no_index_ns}::") == 0; } return 1; } #pod =method features #pod #pod my @feature_objects = $meta->features; #pod #pod This method returns a list of L objects, one for each #pod optional feature described by the distribution's metadata. #pod #pod =cut sub features { my ($self) = @_; my $opt_f = $self->optional_features; my @features = map {; CPAN::Meta::Feature->new($_ => $opt_f->{ $_ }) } keys %$opt_f; return @features; } #pod =method feature #pod #pod my $feature_object = $meta->feature( $identifier ); #pod #pod This method returns a L object for the optional feature #pod with the given identifier. If no feature with that identifier exists, an #pod exception will be raised. #pod #pod =cut sub feature { my ($self, $ident) = @_; croak "no feature named $ident" unless my $f = $self->optional_features->{ $ident }; return CPAN::Meta::Feature->new($ident, $f); } #pod =method as_struct #pod #pod my $copy = $meta->as_struct( \%options ); #pod #pod This method returns a deep copy of the object's metadata as an unblessed hash #pod reference. It takes an optional hashref of options. If the hashref contains #pod a C argument, the copied metadata will be converted to the version #pod of the specification and returned. For example: #pod #pod my $old_spec = $meta->as_struct( {version => "1.4"} ); #pod #pod =cut sub as_struct { my ($self, $options) = @_; my $struct = _dclone($self); if ( $options->{version} ) { my $cmc = CPAN::Meta::Converter->new( $struct ); $struct = $cmc->convert( version => $options->{version} ); } return $struct; } #pod =method as_string #pod #pod my $string = $meta->as_string( \%options ); #pod #pod This method returns a serialized copy of the object's metadata as a character #pod string. (The strings are B UTF-8 encoded.) It takes an optional hashref #pod of options. If the hashref contains a C argument, the copied metadata #pod will be converted to the version of the specification and returned. For #pod example: #pod #pod my $string = $meta->as_string( {version => "1.4"} ); #pod #pod For C greater than or equal to 2, the string will be serialized as #pod JSON. For C less than 2, the string will be serialized as YAML. In #pod both cases, the same rules are followed as in the C method for choosing #pod a serialization backend. #pod #pod The serialized structure will include a C entry giving #pod the package and version used to serialize. Any existing key in the given #pod C<$meta> object will be clobbered. #pod #pod =cut sub as_string { my ($self, $options) = @_; my $version = $options->{version} || '2'; my $struct; if ( $self->meta_spec_version ne $version ) { my $cmc = CPAN::Meta::Converter->new( $self->as_struct ); $struct = $cmc->convert( version => $version ); } else { $struct = $self->as_struct; } my ($data, $backend); if ( $version ge '2' ) { $backend = Parse::CPAN::Meta->json_backend(); local $struct->{x_serialization_backend} = sprintf '%s version %s', $backend, $backend->VERSION; $data = $backend->new->pretty->canonical->encode($struct); } else { $backend = Parse::CPAN::Meta->yaml_backend(); local $struct->{x_serialization_backend} = sprintf '%s version %s', $backend, $backend->VERSION; $data = eval { no strict 'refs'; &{"$backend\::Dump"}($struct) }; if ( $@ ) { croak $backend->can('errstr') ? $backend->errstr : $@ } } return $data; } # Used by JSON::PP, etc. for "convert_blessed" sub TO_JSON { return { %{ $_[0] } }; } 1; # ABSTRACT: the distribution metadata for a CPAN dist =pod =encoding UTF-8 =head1 NAME CPAN::Meta - the distribution metadata for a CPAN dist =head1 VERSION version 2.150005 =head1 SYNOPSIS use v5.10; use strict; use warnings; use CPAN::Meta; use Module::Load; my $meta = CPAN::Meta->load_file('META.json'); printf "testing requirements for %s version %s\n", $meta->name, $meta->version; my $prereqs = $meta->effective_prereqs; for my $phase ( qw/configure runtime build test/ ) { say "Requirements for $phase:"; my $reqs = $prereqs->requirements_for($phase, "requires"); for my $module ( sort $reqs->required_modules ) { my $status; if ( eval { load $module unless $module eq 'perl'; 1 } ) { my $version = $module eq 'perl' ? $] : $module->VERSION; $status = $reqs->accepts_module($module, $version) ? "$version ok" : "$version not ok"; } else { $status = "missing" }; say " $module ($status)"; } } =head1 DESCRIPTION Software distributions released to the CPAN include a F or, for older distributions, F, which describes the distribution, its contents, and the requirements for building and installing the distribution. The data structure stored in the F file is described in L. CPAN::Meta provides a simple class to represent this distribution metadata (or I), along with some helpful methods for interrogating that data. The documentation below is only for the methods of the CPAN::Meta object. For information on the meaning of individual fields, consult the spec. =head1 METHODS =head2 new my $meta = CPAN::Meta->new($distmeta_struct, \%options); Returns a valid CPAN::Meta object or dies if the supplied metadata hash reference fails to validate. Older-format metadata will be up-converted to version 2 if they validate against the original stated specification. It takes an optional hashref of options. Valid options include: =over =item * lazy_validation -- if true, new will attempt to convert the given metadata to version 2 before attempting to validate it. This means than any fixable errors will be handled by CPAN::Meta::Converter before validation. (Note that this might result in invalid optional data being silently dropped.) The default is false. =back =head2 create my $meta = CPAN::Meta->create($distmeta_struct, \%options); This is same as C, except that C and C fields will be generated if not provided. This means the metadata structure is assumed to otherwise follow the latest L. =head2 load_file my $meta = CPAN::Meta->load_file($distmeta_file, \%options); Given a pathname to a file containing metadata, this deserializes the file according to its file suffix and constructs a new C object, just like C. It will die if the deserialized version fails to validate against its stated specification version. It takes the same options as C but C defaults to true. =head2 load_yaml_string my $meta = CPAN::Meta->load_yaml_string($yaml, \%options); This method returns a new CPAN::Meta object using the first document in the given YAML string. In other respects it is identical to C. =head2 load_json_string my $meta = CPAN::Meta->load_json_string($json, \%options); This method returns a new CPAN::Meta object using the structure represented by the given JSON string. In other respects it is identical to C. =head2 load_string my $meta = CPAN::Meta->load_string($string, \%options); If you don't know if a string contains YAML or JSON, this method will use L to guess. In other respects it is identical to C. =head2 save $meta->save($distmeta_file, \%options); Serializes the object as JSON and writes it to the given file. The only valid option is C, which defaults to '2'. On Perl 5.8.1 or later, the file is saved with UTF-8 encoding. For C 2 (or higher), the filename should end in '.json'. L is the default JSON backend. Using another JSON backend requires L 2.5 or later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate backend like L. For C less than 2, the filename should end in '.yml'. L is used to generate an older metadata structure, which is serialized to YAML. CPAN::Meta::YAML is the default YAML backend. You may set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though this is not recommended due to subtle incompatibilities between YAML parsers on CPAN. =head2 meta_spec_version This method returns the version part of the C entry in the distmeta structure. It is equivalent to: $meta->meta_spec->{version}; =head2 effective_prereqs my $prereqs = $meta->effective_prereqs; my $prereqs = $meta->effective_prereqs( \@feature_identifiers ); This method returns a L object describing all the prereqs for the distribution. If an arrayref of feature identifiers is given, the prereqs for the identified features are merged together with the distribution's core prereqs before the CPAN::Meta::Prereqs object is returned. =head2 should_index_file ... if $meta->should_index_file( $filename ); This method returns true if the given file should be indexed. It decides this by checking the C and C keys in the C property of the distmeta structure. Note that neither the version format nor C are considered. C<$filename> should be given in unix format. =head2 should_index_package ... if $meta->should_index_package( $package ); This method returns true if the given package should be indexed. It decides this by checking the C and C keys in the C property of the distmeta structure. Note that neither the version format nor C are considered. =head2 features my @feature_objects = $meta->features; This method returns a list of L objects, one for each optional feature described by the distribution's metadata. =head2 feature my $feature_object = $meta->feature( $identifier ); This method returns a L object for the optional feature with the given identifier. If no feature with that identifier exists, an exception will be raised. =head2 as_struct my $copy = $meta->as_struct( \%options ); This method returns a deep copy of the object's metadata as an unblessed hash reference. It takes an optional hashref of options. If the hashref contains a C argument, the copied metadata will be converted to the version of the specification and returned. For example: my $old_spec = $meta->as_struct( {version => "1.4"} ); =head2 as_string my $string = $meta->as_string( \%options ); This method returns a serialized copy of the object's metadata as a character string. (The strings are B UTF-8 encoded.) It takes an optional hashref of options. If the hashref contains a C argument, the copied metadata will be converted to the version of the specification and returned. For example: my $string = $meta->as_string( {version => "1.4"} ); For C greater than or equal to 2, the string will be serialized as JSON. For C less than 2, the string will be serialized as YAML. In both cases, the same rules are followed as in the C method for choosing a serialization backend. The serialized structure will include a C entry giving the package and version used to serialize. Any existing key in the given C<$meta> object will be clobbered. =head1 STRING DATA The following methods return a single value, which is the value for the corresponding entry in the distmeta structure. Values should be either undef or strings. =over 4 =item * abstract =item * description =item * dynamic_config =item * generated_by =item * name =item * release_status =item * version =back =head1 LIST DATA These methods return lists of string values, which might be represented in the distmeta structure as arrayrefs or scalars: =over 4 =item * authors =item * keywords =item * licenses =back The C and C methods may also be called as C and C, respectively, to match the field name in the distmeta structure. =head1 MAP DATA These readers return hashrefs of arbitrary unblessed data structures, each described more fully in the specification: =over 4 =item * meta_spec =item * resources =item * provides =item * no_index =item * prereqs =item * optional_features =back =head1 CUSTOM DATA A list of custom keys are available from the C method and particular keys may be retrieved with the C method. say $meta->custom($_) for $meta->custom_keys; If a custom key refers to a data structure, a deep clone is returned. =for Pod::Coverage TO_JSON abstract author authors custom custom_keys description dynamic_config generated_by keywords license licenses meta_spec name no_index optional_features prereqs provides release_status resources version =head1 BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at L When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 SEE ALSO =over 4 =item * L =item * L =back =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan =head1 SUPPORT =head2 Bugs / Feature Requests Please report any bugs or feature requests through the issue tracker at L. You will be notified automatically of any progress on your issue. =head2 Source Code This is open source software. The code repository is available for public review and contribution under the terms of the license. L git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 CONTRIBUTORS =for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov Eric Wilhelm Graham Knop Gregor Hermann Karen Etheridge Kenichi Ishigaki Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern mohawk2 moznion Niko Tyni Olaf Alders Olivier Mengué Randy Sims Tomohiro Hosaka =over 4 =item * Ansgar Burchardt =item * Avar Arnfjord Bjarmason =item * Christopher J. Madsen =item * Chuck Adams =item * Cory G Watson =item * Damyan Ivanov =item * Eric Wilhelm =item * Graham Knop =item * Gregor Hermann =item * Karen Etheridge =item * Kenichi Ishigaki =item * Ken Williams =item * Lars Dieckow =item * Leon Timmermans =item * majensen =item * Mark Fowler =item * Matt S Trout =item * Michael G. Schwern =item * mohawk2 =item * moznion =item * Niko Tyni =item * Olaf Alders =item * Olivier Mengué =item * Randy Sims =item * Tomohiro Hosaka =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/lib/CPAN/Meta/Converter.pm000644 000765 000024 00000140361 12535707053 020303 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; package CPAN::Meta::Converter; our $VERSION = '2.150005'; #pod =head1 SYNOPSIS #pod #pod my $struct = decode_json_file('META.json'); #pod #pod my $cmc = CPAN::Meta::Converter->new( $struct ); #pod #pod my $new_struct = $cmc->convert( version => "2" ); #pod #pod =head1 DESCRIPTION #pod #pod This module converts CPAN Meta structures from one form to another. The #pod primary use is to convert older structures to the most modern version of #pod the specification, but other transformations may be implemented in the #pod future as needed. (E.g. stripping all custom fields or stripping all #pod optional fields.) #pod #pod =cut use CPAN::Meta::Validator; use CPAN::Meta::Requirements; use Parse::CPAN::Meta 1.4400 (); # To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls # before 5.10, we fall back to the EUMM bundled compatibility version module if # that's the only thing available. This shouldn't ever happen in a normal CPAN # install of CPAN::Meta::Requirements, as version.pm will be picked up from # prereqs and be available at runtime. BEGIN { eval "use version ()"; ## no critic if ( my $err = $@ ) { eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic } } # Perl 5.10.0 didn't have "is_qv" in version.pm *_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} }; sub _dclone { my $ref = shift; # if an object is in the data structure and doesn't specify how to # turn itself into JSON, we just stringify the object. That does the # right thing for typical things that might be there, like version objects, # Path::Class objects, etc. no warnings 'once'; no warnings 'redefine'; local *UNIVERSAL::TO_JSON = sub { "$_[0]" }; my $json = Parse::CPAN::Meta->json_backend()->new ->utf8 ->allow_blessed ->convert_blessed; $json->decode($json->encode($ref)) } my %known_specs = ( '2' => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html', '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html', '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html', '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html', '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html' ); my @spec_list = sort { $a <=> $b } keys %known_specs; my ($LOWEST, $HIGHEST) = @spec_list[0,-1]; #--------------------------------------------------------------------------# # converters # # called as $converter->($element, $field_name, $full_meta, $to_version) # # defined return value used for field # undef return value means field is skipped #--------------------------------------------------------------------------# sub _keep { $_[0] } sub _keep_or_one { defined($_[0]) ? $_[0] : 1 } sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 } sub _keep_or_unknown { defined($_[0]) && length($_[0]) ? $_[0] : "unknown" } sub _generated_by { my $gen = shift; my $sig = __PACKAGE__ . " version " . (__PACKAGE__->VERSION || ""); return $sig unless defined $gen and length $gen; return $gen if $gen =~ /\Q$sig/; return "$gen, $sig"; } sub _listify { ! defined $_[0] ? undef : ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] } sub _prefix_custom { my $key = shift; $key =~ s/^(?!x_) # Unless it already starts with x_ (?:x-?)? # Remove leading x- or x (if present) /x_/ix; # and prepend x_ return $key; } sub _ucfirst_custom { my $key = shift; $key = ucfirst $key unless $key =~ /[A-Z]/; return $key; } sub _no_prefix_ucfirst_custom { my $key = shift; $key =~ s/^x_//; return _ucfirst_custom($key); } sub _change_meta_spec { my ($element, undef, undef, $version) = @_; return { version => $version, url => $known_specs{$version}, }; } my @open_source = ( 'perl', 'gpl', 'apache', 'artistic', 'artistic_2', 'lgpl', 'bsd', 'gpl', 'mit', 'mozilla', 'open_source', ); my %is_open_source = map {; $_ => 1 } @open_source; my @valid_licenses_1 = ( @open_source, 'unrestricted', 'restrictive', 'unknown', ); my %license_map_1 = ( ( map { $_ => $_ } @valid_licenses_1 ), artistic2 => 'artistic_2', ); sub _license_1 { my ($element) = @_; return 'unknown' unless defined $element; if ( $license_map_1{lc $element} ) { return $license_map_1{lc $element}; } else { return 'unknown'; } } my @valid_licenses_2 = qw( agpl_3 apache_1_1 apache_2_0 artistic_1 artistic_2 bsd freebsd gfdl_1_2 gfdl_1_3 gpl_1 gpl_2 gpl_3 lgpl_2_1 lgpl_3_0 mit mozilla_1_0 mozilla_1_1 openssl perl_5 qpl_1_0 ssleay sun zlib open_source restricted unrestricted unknown ); # The "old" values were defined by Module::Build, and were often vague. I have # made the decisions below based on reading Module::Build::API and how clearly # it specifies the version of the license. my %license_map_2 = ( (map { $_ => $_ } @valid_licenses_2), apache => 'apache_2_0', # clearly stated as 2.0 artistic => 'artistic_1', # clearly stated as 1 artistic2 => 'artistic_2', # clearly stated as 2 gpl => 'open_source', # we don't know which GPL; punt lgpl => 'open_source', # we don't know which LGPL; punt mozilla => 'open_source', # we don't know which MPL; punt perl => 'perl_5', # clearly Perl 5 restrictive => 'restricted', ); sub _license_2 { my ($element) = @_; return [ 'unknown' ] unless defined $element; $element = [ $element ] unless ref $element eq 'ARRAY'; my @new_list; for my $lic ( @$element ) { next unless defined $lic; if ( my $new = $license_map_2{lc $lic} ) { push @new_list, $new; } } return @new_list ? \@new_list : [ 'unknown' ]; } my %license_downgrade_map = qw( agpl_3 open_source apache_1_1 apache apache_2_0 apache artistic_1 artistic artistic_2 artistic_2 bsd bsd freebsd open_source gfdl_1_2 open_source gfdl_1_3 open_source gpl_1 gpl gpl_2 gpl gpl_3 gpl lgpl_2_1 lgpl lgpl_3_0 lgpl mit mit mozilla_1_0 mozilla mozilla_1_1 mozilla openssl open_source perl_5 perl qpl_1_0 open_source ssleay open_source sun open_source zlib open_source open_source open_source restricted restrictive unrestricted unrestricted unknown unknown ); sub _downgrade_license { my ($element) = @_; if ( ! defined $element ) { return "unknown"; } elsif( ref $element eq 'ARRAY' ) { if ( @$element > 1) { if (grep { !$is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element) { return 'unknown'; } else { return 'open_source'; } } elsif ( @$element == 1 ) { return $license_downgrade_map{lc $element->[0]} || "unknown"; } } elsif ( ! ref $element ) { return $license_downgrade_map{lc $element} || "unknown"; } return "unknown"; } my $no_index_spec_1_2 = { 'file' => \&_listify, 'dir' => \&_listify, 'package' => \&_listify, 'namespace' => \&_listify, }; my $no_index_spec_1_3 = { 'file' => \&_listify, 'directory' => \&_listify, 'package' => \&_listify, 'namespace' => \&_listify, }; my $no_index_spec_2 = { 'file' => \&_listify, 'directory' => \&_listify, 'package' => \&_listify, 'namespace' => \&_listify, ':custom' => \&_prefix_custom, }; sub _no_index_1_2 { my (undef, undef, $meta) = @_; my $no_index = $meta->{no_index} || $meta->{private}; return unless $no_index; # cleanup wrong format if ( ! ref $no_index ) { my $item = $no_index; $no_index = { dir => [ $item ], file => [ $item ] }; } elsif ( ref $no_index eq 'ARRAY' ) { my $list = $no_index; $no_index = { dir => [ @$list ], file => [ @$list ] }; } # common mistake: files -> file if ( exists $no_index->{files} ) { $no_index->{file} = delete $no_index->{files}; } # common mistake: modules -> module if ( exists $no_index->{modules} ) { $no_index->{module} = delete $no_index->{modules}; } return _convert($no_index, $no_index_spec_1_2); } sub _no_index_directory { my ($element, $key, $meta, $version) = @_; return unless $element; # cleanup wrong format if ( ! ref $element ) { my $item = $element; $element = { directory => [ $item ], file => [ $item ] }; } elsif ( ref $element eq 'ARRAY' ) { my $list = $element; $element = { directory => [ @$list ], file => [ @$list ] }; } if ( exists $element->{dir} ) { $element->{directory} = delete $element->{dir}; } # common mistake: files -> file if ( exists $element->{files} ) { $element->{file} = delete $element->{files}; } # common mistake: modules -> module if ( exists $element->{modules} ) { $element->{module} = delete $element->{modules}; } my $spec = $version == 2 ? $no_index_spec_2 : $no_index_spec_1_3; return _convert($element, $spec); } sub _is_module_name { my $mod = shift; return unless defined $mod && length $mod; return $mod =~ m{^[A-Za-z][A-Za-z0-9_]*(?:::[A-Za-z0-9_]+)*$}; } sub _clean_version { my ($element) = @_; return 0 if ! defined $element; $element =~ s{^\s*}{}; $element =~ s{\s*$}{}; $element =~ s{^\.}{0.}; return 0 if ! length $element; return 0 if ( $element eq 'undef' || $element eq '' ); my $v = eval { version->new($element) }; # XXX check defined $v and not just $v because version objects leak memory # in boolean context -- dagolden, 2012-02-03 if ( defined $v ) { return _is_qv($v) ? $v->normal : $element; } else { return 0; } } sub _bad_version_hook { my ($v) = @_; $v =~ s{^\s*}{}; $v =~ s{\s*$}{}; $v =~ s{[a-z]+$}{}; # strip trailing alphabetics my $vobj = eval { version->new($v) }; return defined($vobj) ? $vobj : version->new(0); # or give up } sub _version_map { my ($element) = @_; return unless defined $element; if ( ref $element eq 'HASH' ) { # XXX turn this into CPAN::Meta::Requirements with bad version hook # and then turn it back into a hash my $new_map = CPAN::Meta::Requirements->new( { bad_version_hook => \&_bad_version_hook } # punt ); while ( my ($k,$v) = each %$element ) { next unless _is_module_name($k); if ( !defined($v) || !length($v) || $v eq 'undef' || $v eq '' ) { $v = 0; } # some weird, old META have bad yml with module => module # so check if value is like a module name and not like a version if ( _is_module_name($v) && ! version::is_lax($v) ) { $new_map->add_minimum($k => 0); $new_map->add_minimum($v => 0); } $new_map->add_string_requirement($k => $v); } return $new_map->as_string_hash; } elsif ( ref $element eq 'ARRAY' ) { my $hashref = { map { $_ => 0 } @$element }; return _version_map($hashref); # cleanup any weird stuff } elsif ( ref $element eq '' && length $element ) { return { $element => 0 } } return; } sub _prereqs_from_1 { my (undef, undef, $meta) = @_; my $prereqs = {}; for my $phase ( qw/build configure/ ) { my $key = "${phase}_requires"; $prereqs->{$phase}{requires} = _version_map($meta->{$key}) if $meta->{$key}; } for my $rel ( qw/requires recommends conflicts/ ) { $prereqs->{runtime}{$rel} = _version_map($meta->{$rel}) if $meta->{$rel}; } return $prereqs; } my $prereqs_spec = { configure => \&_prereqs_rel, build => \&_prereqs_rel, test => \&_prereqs_rel, runtime => \&_prereqs_rel, develop => \&_prereqs_rel, ':custom' => \&_prefix_custom, }; my $relation_spec = { requires => \&_version_map, recommends => \&_version_map, suggests => \&_version_map, conflicts => \&_version_map, ':custom' => \&_prefix_custom, }; sub _cleanup_prereqs { my ($prereqs, $key, $meta, $to_version) = @_; return unless $prereqs && ref $prereqs eq 'HASH'; return _convert( $prereqs, $prereqs_spec, $to_version ); } sub _prereqs_rel { my ($relation, $key, $meta, $to_version) = @_; return unless $relation && ref $relation eq 'HASH'; return _convert( $relation, $relation_spec, $to_version ); } BEGIN { my @old_prereqs = qw( requires configure_requires recommends conflicts ); for ( @old_prereqs ) { my $sub = "_get_$_"; my ($phase,$type) = split qr/_/, $_; if ( ! defined $type ) { $type = $phase; $phase = 'runtime'; } no strict 'refs'; *{$sub} = sub { _extract_prereqs($_[2]->{prereqs},$phase,$type) }; } } sub _get_build_requires { my ($data, $key, $meta) = @_; my $test_h = _extract_prereqs($_[2]->{prereqs}, qw(test requires)) || {}; my $build_h = _extract_prereqs($_[2]->{prereqs}, qw(build requires)) || {}; my $test_req = CPAN::Meta::Requirements->from_string_hash($test_h); my $build_req = CPAN::Meta::Requirements->from_string_hash($build_h); $test_req->add_requirements($build_req)->as_string_hash; } sub _extract_prereqs { my ($prereqs, $phase, $type) = @_; return unless ref $prereqs eq 'HASH'; return scalar _version_map($prereqs->{$phase}{$type}); } sub _downgrade_optional_features { my (undef, undef, $meta) = @_; return unless exists $meta->{optional_features}; my $origin = $meta->{optional_features}; my $features = {}; for my $name ( keys %$origin ) { $features->{$name} = { description => $origin->{$name}{description}, requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','requires'), configure_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','configure_requires'), build_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','build_requires'), recommends => _extract_prereqs($origin->{$name}{prereqs},'runtime','recommends'), conflicts => _extract_prereqs($origin->{$name}{prereqs},'runtime','conflicts'), }; for my $k (keys %{$features->{$name}} ) { delete $features->{$name}{$k} unless defined $features->{$name}{$k}; } } return $features; } sub _upgrade_optional_features { my (undef, undef, $meta) = @_; return unless exists $meta->{optional_features}; my $origin = $meta->{optional_features}; my $features = {}; for my $name ( keys %$origin ) { $features->{$name} = { description => $origin->{$name}{description}, prereqs => _prereqs_from_1(undef, undef, $origin->{$name}), }; delete $features->{$name}{prereqs}{configure}; } return $features; } my $optional_features_2_spec = { description => \&_keep, prereqs => \&_cleanup_prereqs, ':custom' => \&_prefix_custom, }; sub _feature_2 { my ($element, $key, $meta, $to_version) = @_; return unless $element && ref $element eq 'HASH'; _convert( $element, $optional_features_2_spec, $to_version ); } sub _cleanup_optional_features_2 { my ($element, $key, $meta, $to_version) = @_; return unless $element && ref $element eq 'HASH'; my $new_data = {}; for my $k ( keys %$element ) { $new_data->{$k} = _feature_2( $element->{$k}, $k, $meta, $to_version ); } return unless keys %$new_data; return $new_data; } sub _optional_features_1_4 { my ($element) = @_; return unless $element; $element = _optional_features_as_map($element); for my $name ( keys %$element ) { for my $drop ( qw/requires_packages requires_os excluded_os/ ) { delete $element->{$name}{$drop}; } } return $element; } sub _optional_features_as_map { my ($element) = @_; return unless $element; if ( ref $element eq 'ARRAY' ) { my %map; for my $feature ( @$element ) { my (@parts) = %$feature; $map{$parts[0]} = $parts[1]; } $element = \%map; } return $element; } sub _is_urlish { defined $_[0] && $_[0] =~ m{\A[-+.a-z0-9]+:.+}i } sub _url_or_drop { my ($element) = @_; return $element if _is_urlish($element); return; } sub _url_list { my ($element) = @_; return unless $element; $element = _listify( $element ); $element = [ grep { _is_urlish($_) } @$element ]; return unless @$element; return $element; } sub _author_list { my ($element) = @_; return [ 'unknown' ] unless $element; $element = _listify( $element ); $element = [ map { defined $_ && length $_ ? $_ : 'unknown' } @$element ]; return [ 'unknown' ] unless @$element; return $element; } my $resource2_upgrade = { license => sub { return _is_urlish($_[0]) ? _listify( $_[0] ) : undef }, homepage => \&_url_or_drop, bugtracker => sub { my ($item) = @_; return unless $item; if ( $item =~ m{^mailto:(.*)$} ) { return { mailto => $1 } } elsif( _is_urlish($item) ) { return { web => $item } } else { return } }, repository => sub { return _is_urlish($_[0]) ? { url => $_[0] } : undef }, ':custom' => \&_prefix_custom, }; sub _upgrade_resources_2 { my (undef, undef, $meta, $version) = @_; return unless exists $meta->{resources}; return _convert($meta->{resources}, $resource2_upgrade); } my $bugtracker2_spec = { web => \&_url_or_drop, mailto => \&_keep, ':custom' => \&_prefix_custom, }; sub _repo_type { my ($element, $key, $meta, $to_version) = @_; return $element if defined $element; return unless exists $meta->{url}; my $repo_url = $meta->{url}; for my $type ( qw/git svn/ ) { return $type if $repo_url =~ m{\A$type}; } return; } my $repository2_spec = { web => \&_url_or_drop, url => \&_url_or_drop, type => \&_repo_type, ':custom' => \&_prefix_custom, }; my $resources2_cleanup = { license => \&_url_list, homepage => \&_url_or_drop, bugtracker => sub { ref $_[0] ? _convert( $_[0], $bugtracker2_spec ) : undef }, repository => sub { my $data = shift; ref $data ? _convert( $data, $repository2_spec ) : undef }, ':custom' => \&_prefix_custom, }; sub _cleanup_resources_2 { my ($resources, $key, $meta, $to_version) = @_; return unless $resources && ref $resources eq 'HASH'; return _convert($resources, $resources2_cleanup, $to_version); } my $resource1_spec = { license => \&_url_or_drop, homepage => \&_url_or_drop, bugtracker => \&_url_or_drop, repository => \&_url_or_drop, ':custom' => \&_keep, }; sub _resources_1_3 { my (undef, undef, $meta, $version) = @_; return unless exists $meta->{resources}; return _convert($meta->{resources}, $resource1_spec); } *_resources_1_4 = *_resources_1_3; sub _resources_1_2 { my (undef, undef, $meta) = @_; my $resources = $meta->{resources} || {}; if ( $meta->{license_url} && ! $resources->{license} ) { $resources->{license} = $meta->{license_url} if _is_urlish($meta->{license_url}); } return unless keys %$resources; return _convert($resources, $resource1_spec); } my $resource_downgrade_spec = { license => sub { return ref $_[0] ? $_[0]->[0] : $_[0] }, homepage => \&_url_or_drop, bugtracker => sub { return $_[0]->{web} }, repository => sub { return $_[0]->{url} || $_[0]->{web} }, ':custom' => \&_no_prefix_ucfirst_custom, }; sub _downgrade_resources { my (undef, undef, $meta, $version) = @_; return unless exists $meta->{resources}; return _convert($meta->{resources}, $resource_downgrade_spec); } sub _release_status { my ($element, undef, $meta) = @_; return $element if $element && $element =~ m{\A(?:stable|testing|unstable)\z}; return _release_status_from_version(undef, undef, $meta); } sub _release_status_from_version { my (undef, undef, $meta) = @_; my $version = $meta->{version} || ''; return ( $version =~ /_/ ) ? 'testing' : 'stable'; } my $provides_spec = { file => \&_keep, version => \&_keep, }; my $provides_spec_2 = { file => \&_keep, version => \&_keep, ':custom' => \&_prefix_custom, }; sub _provides { my ($element, $key, $meta, $to_version) = @_; return unless defined $element && ref $element eq 'HASH'; my $spec = $to_version == 2 ? $provides_spec_2 : $provides_spec; my $new_data = {}; for my $k ( keys %$element ) { $new_data->{$k} = _convert($element->{$k}, $spec, $to_version); $new_data->{$k}{version} = _clean_version($element->{$k}{version}) if exists $element->{$k}{version}; } return $new_data; } sub _convert { my ($data, $spec, $to_version, $is_fragment) = @_; my $new_data = {}; for my $key ( keys %$spec ) { next if $key eq ':custom' || $key eq ':drop'; next unless my $fcn = $spec->{$key}; if ( $is_fragment && $key eq 'generated_by' ) { $fcn = \&_keep; } die "spec for '$key' is not a coderef" unless ref $fcn && ref $fcn eq 'CODE'; my $new_value = $fcn->($data->{$key}, $key, $data, $to_version); $new_data->{$key} = $new_value if defined $new_value; } my $drop_list = $spec->{':drop'}; my $customizer = $spec->{':custom'} || \&_keep; for my $key ( keys %$data ) { next if $drop_list && grep { $key eq $_ } @$drop_list; next if exists $spec->{$key}; # we handled it $new_data->{ $customizer->($key) } = $data->{$key}; } return $new_data; } #--------------------------------------------------------------------------# # define converters for each conversion #--------------------------------------------------------------------------# # each converts from prior version # special ":custom" field is used for keys not recognized in spec my %up_convert = ( '2-from-1.4' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_2, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # CHANGED TO MANDATORY 'dynamic_config' => \&_keep_or_one, # ADDED MANDATORY 'release_status' => \&_release_status, # PRIOR OPTIONAL 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_upgrade_optional_features, 'provides' => \&_provides, 'resources' => \&_upgrade_resources_2, # ADDED OPTIONAL 'description' => \&_keep, 'prereqs' => \&_prereqs_from_1, # drop these deprecated fields, but only after we convert ':drop' => [ qw( build_requires configure_requires conflicts distribution_type license_url private recommends requires ) ], # other random keys need x_ prefixing ':custom' => \&_prefix_custom, }, '1.4-from-1.3' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_optional_features_1_4, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_4, # ADDED OPTIONAL 'configure_requires' => \&_keep, # drop these deprecated fields, but only after we convert ':drop' => [ qw( license_url private )], # other random keys are OK if already valid ':custom' => \&_keep }, '1.3-from-1.2' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_3, # drop these deprecated fields, but only after we convert ':drop' => [ qw( license_url private )], # other random keys are OK if already valid ':custom' => \&_keep }, '1.2-from-1.1' => { # PRIOR MANDATORY 'version' => \&_keep, # CHANGED TO MANDATORY 'license' => \&_license_1, 'name' => \&_keep, 'generated_by' => \&_generated_by, # ADDED MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'meta-spec' => \&_change_meta_spec, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'recommends' => \&_version_map, 'requires' => \&_version_map, # ADDED OPTIONAL 'keywords' => \&_keep, 'no_index' => \&_no_index_1_2, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'resources' => \&_resources_1_2, # drop these deprecated fields, but only after we convert ':drop' => [ qw( license_url private )], # other random keys are OK if already valid ':custom' => \&_keep }, '1.1-from-1.0' => { # CHANGED TO MANDATORY 'version' => \&_keep, # IMPLIED MANDATORY 'name' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'recommends' => \&_version_map, 'requires' => \&_version_map, # ADDED OPTIONAL 'license_url' => \&_url_or_drop, 'private' => \&_keep, # other random keys are OK if already valid ':custom' => \&_keep }, ); my %down_convert = ( '1.4-from-2' => { # MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_downgrade_license, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # OPTIONAL 'build_requires' => \&_get_build_requires, 'configure_requires' => \&_get_configure_requires, 'conflicts' => \&_get_conflicts, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_downgrade_optional_features, 'provides' => \&_provides, 'recommends' => \&_get_recommends, 'requires' => \&_get_requires, 'resources' => \&_downgrade_resources, # drop these unsupported fields (after conversion) ':drop' => [ qw( description prereqs release_status )], # custom keys will be left unchanged ':custom' => \&_keep }, '1.3-from-1.4' => { # MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_3, # drop these unsupported fields, but only after we convert ':drop' => [ qw( configure_requires )], # other random keys are OK if already valid ':custom' => \&_keep, }, '1.2-from-1.3' => { # MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_1_2, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_3, # other random keys are OK if already valid ':custom' => \&_keep, }, '1.1-from-1.2' => { # MANDATORY 'version' => \&_keep, # IMPLIED MANDATORY 'name' => \&_keep, 'meta-spec' => \&_change_meta_spec, # OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'private' => \&_keep, 'recommends' => \&_version_map, 'requires' => \&_version_map, # drop unsupported fields ':drop' => [ qw( abstract author provides no_index keywords resources )], # other random keys are OK if already valid ':custom' => \&_keep, }, '1.0-from-1.1' => { # IMPLIED MANDATORY 'name' => \&_keep, 'meta-spec' => \&_change_meta_spec, 'version' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'recommends' => \&_version_map, 'requires' => \&_version_map, # other random keys are OK if already valid ':custom' => \&_keep, }, ); my %cleanup = ( '2' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_2, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # CHANGED TO MANDATORY 'dynamic_config' => \&_keep_or_one, # ADDED MANDATORY 'release_status' => \&_release_status, # PRIOR OPTIONAL 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_cleanup_optional_features_2, 'provides' => \&_provides, 'resources' => \&_cleanup_resources_2, # ADDED OPTIONAL 'description' => \&_keep, 'prereqs' => \&_cleanup_prereqs, # drop these deprecated fields, but only after we convert ':drop' => [ qw( build_requires configure_requires conflicts distribution_type license_url private recommends requires ) ], # other random keys need x_ prefixing ':custom' => \&_prefix_custom, }, '1.4' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_optional_features_1_4, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_4, # ADDED OPTIONAL 'configure_requires' => \&_keep, # other random keys are OK if already valid ':custom' => \&_keep }, '1.3' => { # PRIOR MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'meta-spec' => \&_change_meta_spec, 'name' => \&_keep, 'version' => \&_keep, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'keywords' => \&_keep, 'no_index' => \&_no_index_directory, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'recommends' => \&_version_map, 'requires' => \&_version_map, 'resources' => \&_resources_1_3, # other random keys are OK if already valid ':custom' => \&_keep }, '1.2' => { # PRIOR MANDATORY 'version' => \&_keep, # CHANGED TO MANDATORY 'license' => \&_license_1, 'name' => \&_keep, 'generated_by' => \&_generated_by, # ADDED MANDATORY 'abstract' => \&_keep_or_unknown, 'author' => \&_author_list, 'meta-spec' => \&_change_meta_spec, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'recommends' => \&_version_map, 'requires' => \&_version_map, # ADDED OPTIONAL 'keywords' => \&_keep, 'no_index' => \&_no_index_1_2, 'optional_features' => \&_optional_features_as_map, 'provides' => \&_provides, 'resources' => \&_resources_1_2, # other random keys are OK if already valid ':custom' => \&_keep }, '1.1' => { # CHANGED TO MANDATORY 'version' => \&_keep, # IMPLIED MANDATORY 'name' => \&_keep, 'meta-spec' => \&_change_meta_spec, # PRIOR OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'recommends' => \&_version_map, 'requires' => \&_version_map, # ADDED OPTIONAL 'license_url' => \&_url_or_drop, 'private' => \&_keep, # other random keys are OK if already valid ':custom' => \&_keep }, '1.0' => { # IMPLIED MANDATORY 'name' => \&_keep, 'meta-spec' => \&_change_meta_spec, 'version' => \&_keep, # IMPLIED OPTIONAL 'build_requires' => \&_version_map, 'conflicts' => \&_version_map, 'distribution_type' => \&_keep, 'dynamic_config' => \&_keep_or_one, 'generated_by' => \&_generated_by, 'license' => \&_license_1, 'recommends' => \&_version_map, 'requires' => \&_version_map, # other random keys are OK if already valid ':custom' => \&_keep, }, ); # for a given field in a spec version, what fields will it feed # into in the *latest* spec (i.e. v2); meta-spec omitted because # we always expect a meta-spec to be generated my %fragments_generate = ( '2' => { 'abstract' => 'abstract', 'author' => 'author', 'generated_by' => 'generated_by', 'license' => 'license', 'name' => 'name', 'version' => 'version', 'dynamic_config' => 'dynamic_config', 'release_status' => 'release_status', 'keywords' => 'keywords', 'no_index' => 'no_index', 'optional_features' => 'optional_features', 'provides' => 'provides', 'resources' => 'resources', 'description' => 'description', 'prereqs' => 'prereqs', }, '1.4' => { 'abstract' => 'abstract', 'author' => 'author', 'generated_by' => 'generated_by', 'license' => 'license', 'name' => 'name', 'version' => 'version', 'build_requires' => 'prereqs', 'conflicts' => 'prereqs', 'distribution_type' => 'distribution_type', 'dynamic_config' => 'dynamic_config', 'keywords' => 'keywords', 'no_index' => 'no_index', 'optional_features' => 'optional_features', 'provides' => 'provides', 'recommends' => 'prereqs', 'requires' => 'prereqs', 'resources' => 'resources', 'configure_requires' => 'prereqs', }, ); # this is not quite true but will work well enough # as 1.4 is a superset of earlier ones $fragments_generate{$_} = $fragments_generate{'1.4'} for qw/1.3 1.2 1.1 1.0/; #--------------------------------------------------------------------------# # Code #--------------------------------------------------------------------------# #pod =method new #pod #pod my $cmc = CPAN::Meta::Converter->new( $struct ); #pod #pod The constructor should be passed a valid metadata structure but invalid #pod structures are accepted. If no meta-spec version is provided, version 1.0 will #pod be assumed. #pod #pod Optionally, you can provide a C argument after C<$struct>: #pod #pod my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" ); #pod #pod This is only needed when converting a metadata fragment that does not include a #pod C field. #pod #pod =cut sub new { my ($class,$data,%args) = @_; # create an attributes hash my $self = { 'data' => $data, 'spec' => _extract_spec_version($data, $args{default_version}), }; # create the object return bless $self, $class; } sub _extract_spec_version { my ($data, $default) = @_; my $spec = $data->{'meta-spec'}; # is meta-spec there and valid? return( $default || "1.0" ) unless defined $spec && ref $spec eq 'HASH'; # before meta-spec? # does the version key look like a valid version? my $v = $spec->{version}; if ( defined $v && $v =~ /^\d+(?:\.\d+)?$/ ) { return $v if defined $v && grep { $v eq $_ } keys %known_specs; # known spec return $v+0 if defined $v && grep { $v == $_ } keys %known_specs; # 2.0 => 2 } # otherwise, use heuristics: look for 1.x vs 2.0 fields return "2" if exists $data->{prereqs}; return "1.4" if exists $data->{configure_requires}; return( $default || "1.2" ); # when meta-spec was first defined } #pod =method convert #pod #pod my $new_struct = $cmc->convert( version => "2" ); #pod #pod Returns a new hash reference with the metadata converted to a different form. #pod C will die if any conversion/standardization still results in an #pod invalid structure. #pod #pod Valid parameters include: #pod #pod =over #pod #pod =item * #pod #pod C -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2"). #pod Defaults to the latest version of the CPAN Meta Spec. #pod #pod =back #pod #pod Conversion proceeds through each version in turn. For example, a version 1.2 #pod structure might be converted to 1.3 then 1.4 then finally to version 2. The #pod conversion process attempts to clean-up simple errors and standardize data. #pod For example, if C is given as a scalar, it will converted to an array #pod reference containing the item. (Converting a structure to its own version will #pod also clean-up and standardize.) #pod #pod When data are cleaned and standardized, missing or invalid fields will be #pod replaced with sensible defaults when possible. This may be lossy or imprecise. #pod For example, some badly structured META.yml files on CPAN have prerequisite #pod modules listed as both keys and values: #pod #pod requires => { 'Foo::Bar' => 'Bam::Baz' } #pod #pod These would be split and each converted to a prerequisite with a minimum #pod version of zero. #pod #pod When some mandatory fields are missing or invalid, the conversion will attempt #pod to provide a sensible default or will fill them with a value of 'unknown'. For #pod example a missing or unrecognized C field will result in a C #pod field of 'unknown'. Fields that may get an 'unknown' include: #pod #pod =for :list #pod * abstract #pod * author #pod * license #pod #pod =cut sub convert { my ($self, %args) = @_; my $args = { %args }; my $new_version = $args->{version} || $HIGHEST; my $is_fragment = $args->{is_fragment}; my ($old_version) = $self->{spec}; my $converted = _dclone($self->{data}); if ( $old_version == $new_version ) { $converted = _convert( $converted, $cleanup{$old_version}, $old_version, $is_fragment ); unless ( $args->{is_fragment} ) { my $cmv = CPAN::Meta::Validator->new( $converted ); unless ( $cmv->is_valid ) { my $errs = join("\n", $cmv->errors); die "Failed to clean-up $old_version metadata. Errors:\n$errs\n"; } } return $converted; } elsif ( $old_version > $new_version ) { my @vers = sort { $b <=> $a } keys %known_specs; for my $i ( 0 .. $#vers-1 ) { next if $vers[$i] > $old_version; last if $vers[$i+1] < $new_version; my $spec_string = "$vers[$i+1]-from-$vers[$i]"; $converted = _convert( $converted, $down_convert{$spec_string}, $vers[$i+1], $is_fragment ); unless ( $args->{is_fragment} ) { my $cmv = CPAN::Meta::Validator->new( $converted ); unless ( $cmv->is_valid ) { my $errs = join("\n", $cmv->errors); die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n"; } } } return $converted; } else { my @vers = sort { $a <=> $b } keys %known_specs; for my $i ( 0 .. $#vers-1 ) { next if $vers[$i] < $old_version; last if $vers[$i+1] > $new_version; my $spec_string = "$vers[$i+1]-from-$vers[$i]"; $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1], $is_fragment ); unless ( $args->{is_fragment} ) { my $cmv = CPAN::Meta::Validator->new( $converted ); unless ( $cmv->is_valid ) { my $errs = join("\n", $cmv->errors); die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n"; } } } return $converted; } } #pod =method upgrade_fragment #pod #pod my $new_struct = $cmc->upgrade_fragment; #pod #pod Returns a new hash reference with the metadata converted to the latest version #pod of the CPAN Meta Spec. No validation is done on the result -- you must #pod validate after merging fragments into a complete metadata document. #pod #pod Available since version 2.141170. #pod #pod =cut sub upgrade_fragment { my ($self) = @_; my ($old_version) = $self->{spec}; my %expected = map {; $_ => 1 } grep { defined } map { $fragments_generate{$old_version}{$_} } keys %{ $self->{data} }; my $converted = $self->convert( version => $HIGHEST, is_fragment => 1 ); for my $key ( keys %$converted ) { next if $key =~ /^x_/i || $key eq 'meta-spec'; delete $converted->{$key} unless $expected{$key}; } return $converted; } 1; # ABSTRACT: Convert CPAN distribution metadata structures =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Converter - Convert CPAN distribution metadata structures =head1 VERSION version 2.150005 =head1 SYNOPSIS my $struct = decode_json_file('META.json'); my $cmc = CPAN::Meta::Converter->new( $struct ); my $new_struct = $cmc->convert( version => "2" ); =head1 DESCRIPTION This module converts CPAN Meta structures from one form to another. The primary use is to convert older structures to the most modern version of the specification, but other transformations may be implemented in the future as needed. (E.g. stripping all custom fields or stripping all optional fields.) =head1 METHODS =head2 new my $cmc = CPAN::Meta::Converter->new( $struct ); The constructor should be passed a valid metadata structure but invalid structures are accepted. If no meta-spec version is provided, version 1.0 will be assumed. Optionally, you can provide a C argument after C<$struct>: my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" ); This is only needed when converting a metadata fragment that does not include a C field. =head2 convert my $new_struct = $cmc->convert( version => "2" ); Returns a new hash reference with the metadata converted to a different form. C will die if any conversion/standardization still results in an invalid structure. Valid parameters include: =over =item * C -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2"). Defaults to the latest version of the CPAN Meta Spec. =back Conversion proceeds through each version in turn. For example, a version 1.2 structure might be converted to 1.3 then 1.4 then finally to version 2. The conversion process attempts to clean-up simple errors and standardize data. For example, if C is given as a scalar, it will converted to an array reference containing the item. (Converting a structure to its own version will also clean-up and standardize.) When data are cleaned and standardized, missing or invalid fields will be replaced with sensible defaults when possible. This may be lossy or imprecise. For example, some badly structured META.yml files on CPAN have prerequisite modules listed as both keys and values: requires => { 'Foo::Bar' => 'Bam::Baz' } These would be split and each converted to a prerequisite with a minimum version of zero. When some mandatory fields are missing or invalid, the conversion will attempt to provide a sensible default or will fill them with a value of 'unknown'. For example a missing or unrecognized C field will result in a C field of 'unknown'. Fields that may get an 'unknown' include: =over 4 =item * abstract =item * author =item * license =back =head2 upgrade_fragment my $new_struct = $cmc->upgrade_fragment; Returns a new hash reference with the metadata converted to the latest version of the CPAN Meta Spec. No validation is done on the result -- you must validate after merging fragments into a complete metadata document. Available since version 2.141170. =head1 BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at L When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/lib/CPAN/Meta/Feature.pm000644 000765 000024 00000006435 12535707053 017732 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; package CPAN::Meta::Feature; our $VERSION = '2.150005'; use CPAN::Meta::Prereqs; #pod =head1 DESCRIPTION #pod #pod A CPAN::Meta::Feature object describes an optional feature offered by a CPAN #pod distribution and specified in the distribution's F (or F) #pod file. #pod #pod For the most part, this class will only be used when operating on the result of #pod the C or C methods on a L object. #pod #pod =method new #pod #pod my $feature = CPAN::Meta::Feature->new( $identifier => \%spec ); #pod #pod This returns a new Feature object. The C<%spec> argument to the constructor #pod should be the same as the value of the C entry in the #pod distmeta. It must contain entries for C and C. #pod #pod =cut sub new { my ($class, $identifier, $spec) = @_; my %guts = ( identifier => $identifier, description => $spec->{description}, prereqs => CPAN::Meta::Prereqs->new($spec->{prereqs}), ); bless \%guts => $class; } #pod =method identifier #pod #pod This method returns the feature's identifier. #pod #pod =cut sub identifier { $_[0]{identifier} } #pod =method description #pod #pod This method returns the feature's long description. #pod #pod =cut sub description { $_[0]{description} } #pod =method prereqs #pod #pod This method returns the feature's prerequisites as a L #pod object. #pod #pod =cut sub prereqs { $_[0]{prereqs} } 1; # ABSTRACT: an optional feature provided by a CPAN distribution =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Feature - an optional feature provided by a CPAN distribution =head1 VERSION version 2.150005 =head1 DESCRIPTION A CPAN::Meta::Feature object describes an optional feature offered by a CPAN distribution and specified in the distribution's F (or F) file. For the most part, this class will only be used when operating on the result of the C or C methods on a L object. =head1 METHODS =head2 new my $feature = CPAN::Meta::Feature->new( $identifier => \%spec ); This returns a new Feature object. The C<%spec> argument to the constructor should be the same as the value of the C entry in the distmeta. It must contain entries for C and C. =head2 identifier This method returns the feature's identifier. =head2 description This method returns the feature's long description. =head2 prereqs This method returns the feature's prerequisites as a L object. =head1 BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at L When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/lib/CPAN/Meta/History/000755 000765 000024 00000000000 12535707053 017432 5ustar00davidstaff000000 000000 CPAN-Meta-2.150005/lib/CPAN/Meta/History.pm000644 000765 000024 00000012266 12535707053 017777 0ustar00davidstaff000000 000000 # vi:tw=72 use 5.006; use strict; use warnings; package CPAN::Meta::History; our $VERSION = '2.150005'; 1; # ABSTRACT: history of CPAN Meta Spec changes __END__ =pod =encoding UTF-8 =head1 NAME CPAN::Meta::History - history of CPAN Meta Spec changes =head1 VERSION version 2.150005 =head1 DESCRIPTION The CPAN Meta Spec has gone through several iterations. It was originally written in HTML and later revised into POD (though published in HTML generated from the POD). Fields were added, removed or changed, sometimes by design and sometimes to reflect real-world usage after the fact. This document reconstructs the history of the CPAN Meta Spec based on change logs, repository commit messages and the published HTML files. In some cases, particularly prior to version 1.2, the exact version when certain fields were introduced or changed is inconsistent between sources. When in doubt, the published HTML files for versions 1.0 to 1.4 as they existed when version 2 was developed are used as the definitive source. Starting with version 2, the specification document is part of the CPAN-Meta distribution and will be published on CPAN as L. Going forward, specification version numbers will be integers and decimal portions will correspond to a release date for the CPAN::Meta library. =head1 HISTORY =head2 Version 2 April 2010 =over =item * Revised spec examples as perl data structures rather than YAML =item * Switched to JSON serialization from YAML =item * Specified allowed version number formats =item * Replaced 'requires', 'build_requires', 'configure_requires', 'recommends' and 'conflicts' with new 'prereqs' data structure divided by I (configure, build, test, runtime, etc.) and I (requires, recommends, suggests, conflicts) =item * Added support for 'develop' phase for requirements for maintaining a list of authoring tools =item * Changed 'license' to a list and revised the set of valid licenses =item * Made 'dynamic_config' mandatory to reduce confusion =item * Changed 'resources' subkey 'repository' to a hash that clarifies repository type, url for browsing and url for checkout =item * Changed 'resources' subkey 'bugtracker' to a hash for either web or mailto resource =item * Changed specification of 'optional_features': =over =item * Added formal specification and usage guide instead of just example =item * Changed to use new prereqs data structure instead of individual keys =back =item * Clarified intended use of 'author' as generalized contact list =item * Added 'release_status' field to indicate stable, testing or unstable status to provide hints to indexers =item * Added 'description' field for a longer description of the distribution =item * Formalized use of "x_" or "X_" for all custom keys not listed in the official spec =back =head2 Version 1.4 June 2008 =over =item * Noted explicit support for 'perl' in prerequisites =item * Added 'configure_requires' prerequisite type =item * Changed 'optional_features' =over =item * Example corrected to show map of maps instead of list of maps (though descriptive text said 'map' even in v1.3) =item * Removed 'requires_packages', 'requires_os' and 'excluded_os' as valid subkeys =back =back =head2 Version 1.3 November 2006 =over =item * Added 'no_index' subkey 'directory' and removed 'dir' to match actual usage in the wild =item * Added a 'repository' subkey to 'resources' =back =head2 Version 1.2 August 2005 =over =item * Re-wrote and restructured spec in POD syntax =item * Changed 'name' to be mandatory =item * Changed 'generated_by' to be mandatory =item * Changed 'license' to be mandatory =item * Added version range specifications for prerequisites =item * Added required 'abstract' field =item * Added required 'author' field =item * Added required 'meta-spec' field to define 'version' (and 'url') of the CPAN Meta Spec used for metadata =item * Added 'provides' field =item * Added 'no_index' field and deprecated 'private' field. 'no_index' subkeys include 'file', 'dir', 'package' and 'namespace' =item * Added 'keywords' field =item * Added 'resources' field with subkeys 'homepage', 'license', and 'bugtracker' =item * Added 'optional_features' field as an alternate under 'recommends'. Includes 'description', 'requires', 'build_requires', 'conflicts', 'requires_packages', 'requires_os' and 'excluded_os' as valid subkeys =item * Removed 'license_uri' field =back =head2 Version 1.1 May 2003 =over =item * Changed 'version' to be mandatory =item * Added 'private' field =item * Added 'license_uri' field =back =head2 Version 1.0 March 2003 =over =item * Original release (in HTML format only) =item * Included 'name', 'version', 'license', 'distribution_type', 'requires', 'recommends', 'build_requires', 'conflicts', 'dynamic_config', 'generated_by' =back =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut CPAN-Meta-2.150005/lib/CPAN/Meta/Merge.pm000644 000765 000024 00000016515 12535707053 017376 0ustar00davidstaff000000 000000 use strict; use warnings; package CPAN::Meta::Merge; our $VERSION = '2.150005'; use Carp qw/croak/; use Scalar::Util qw/blessed/; use CPAN::Meta::Converter 2.141170; sub _is_identical { my ($left, $right) = @_; return (not defined $left and not defined $right) # if either of these are references, we compare the serialized value || (defined $left and defined $right and $left eq $right); } sub _identical { my ($left, $right, $path) = @_; croak sprintf "Can't merge attribute %s: '%s' does not equal '%s'", join('.', @{$path}), $left, $right unless _is_identical($left, $right); return $left; } sub _merge { my ($current, $next, $mergers, $path) = @_; for my $key (keys %{$next}) { if (not exists $current->{$key}) { $current->{$key} = $next->{$key}; } elsif (my $merger = $mergers->{$key}) { $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]); } elsif ($merger = $mergers->{':default'}) { $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]); } else { croak sprintf "Can't merge unknown attribute '%s'", join '.', @{$path}, $key; } } return $current; } sub _uniq { my %seen = (); return grep { not $seen{$_}++ } @_; } sub _set_addition { my ($left, $right) = @_; return [ +_uniq(@{$left}, @{$right}) ]; } sub _uniq_map { my ($left, $right, $path) = @_; for my $key (keys %{$right}) { if (not exists $left->{$key}) { $left->{$key} = $right->{$key}; } # identical strings or references are merged identically elsif (_is_identical($left->{$key}, $right->{$key})) { 1; # do nothing - keep left } elsif (ref $left->{$key} eq 'HASH' and ref $right->{$key} eq 'HASH') { $left->{$key} = _uniq_map($left->{$key}, $right->{$key}, [ @{$path}, $key ]); } else { croak 'Duplication of element ' . join '.', @{$path}, $key; } } return $left; } sub _improvize { my ($left, $right, $path) = @_; my ($name) = reverse @{$path}; if ($name =~ /^x_/) { if (ref($left) eq 'ARRAY') { return _set_addition($left, $right, $path); } elsif (ref($left) eq 'HASH') { return _uniq_map($left, $right, $path); } else { return _identical($left, $right, $path); } } croak sprintf "Can't merge '%s'", join '.', @{$path}; } sub _optional_features { my ($left, $right, $path) = @_; for my $key (keys %{$right}) { if (not exists $left->{$key}) { $left->{$key} = $right->{$key}; } else { for my $subkey (keys %{ $right->{$key} }) { next if $subkey eq 'prereqs'; if (not exists $left->{$key}{$subkey}) { $left->{$key}{$subkey} = $right->{$key}{$subkey}; } else { Carp::croak "Cannot merge two optional_features named '$key' with different '$subkey' values" if do { no warnings 'uninitialized'; $left->{$key}{$subkey} ne $right->{$key}{$subkey} }; } } require CPAN::Meta::Prereqs; $left->{$key}{prereqs} = CPAN::Meta::Prereqs->new($left->{$key}{prereqs}) ->with_merged_prereqs(CPAN::Meta::Prereqs->new($right->{$key}{prereqs})) ->as_string_hash; } } return $left; } my %default = ( abstract => \&_identical, author => \&_set_addition, dynamic_config => sub { my ($left, $right) = @_; return $left || $right; }, generated_by => sub { my ($left, $right) = @_; return join ', ', _uniq(split(/, /, $left), split(/, /, $right)); }, license => \&_set_addition, 'meta-spec' => { version => \&_identical, url => \&_identical }, name => \&_identical, release_status => \&_identical, version => \&_identical, description => \&_identical, keywords => \&_set_addition, no_index => { map { ($_ => \&_set_addition) } qw/file directory package namespace/ }, optional_features => \&_optional_features, prereqs => sub { require CPAN::Meta::Prereqs; my ($left, $right) = map { CPAN::Meta::Prereqs->new($_) } @_[0,1]; return $left->with_merged_prereqs($right)->as_string_hash; }, provides => \&_uniq_map, resources => { license => \&_set_addition, homepage => \&_identical, bugtracker => \&_uniq_map, repository => \&_uniq_map, ':default' => \&_improvize, }, ':default' => \&_improvize, ); sub new { my ($class, %arguments) = @_; croak 'default version required' if not exists $arguments{default_version}; my %mapping = %default; my %extra = %{ $arguments{extra_mappings} || {} }; for my $key (keys %extra) { if (ref($mapping{$key}) eq 'HASH') { $mapping{$key} = { %{ $mapping{$key} }, %{ $extra{$key} } }; } else { $mapping{$key} = $extra{$key}; } } return bless { default_version => $arguments{default_version}, mapping => _coerce_mapping(\%mapping, []), }, $class; } my %coderef_for = ( set_addition => \&_set_addition, uniq_map => \&_uniq_map, identical => \&_identical, improvize => \&_improvize, ); sub _coerce_mapping { my ($orig, $map_path) = @_; my %ret; for my $key (keys %{$orig}) { my $value = $orig->{$key}; if (ref($orig->{$key}) eq 'CODE') { $ret{$key} = $value; } elsif (ref($value) eq 'HASH') { my $mapping = _coerce_mapping($value, [ @{$map_path}, $key ]); $ret{$key} = sub { my ($left, $right, $path) = @_; return _merge($left, $right, $mapping, [ @{$path} ]); }; } elsif ($coderef_for{$value}) { $ret{$key} = $coderef_for{$value}; } else { croak "Don't know what to do with " . join '.', @{$map_path}, $key; } } return \%ret; } sub merge { my ($self, @items) = @_; my $current = {}; for my $next (@items) { if ( blessed($next) && $next->isa('CPAN::Meta') ) { $next = $next->as_struct; } elsif ( ref($next) eq 'HASH' ) { my $cmc = CPAN::Meta::Converter->new( $next, default_version => $self->{default_version} ); $next = $cmc->upgrade_fragment; } else { croak "Don't know how to merge '$next'"; } $current = _merge($current, $next, $self->{mapping}, []); } return $current; } 1; # ABSTRACT: Merging CPAN Meta fragments # vim: ts=2 sts=2 sw=2 et : __END__ =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Merge - Merging CPAN Meta fragments =head1 VERSION version 2.150005 =head1 SYNOPSIS my $merger = CPAN::Meta::Merge->new(default_version => "2"); my $meta = $merger->merge($base, @additional); =head1 DESCRIPTION =head1 METHODS =head2 new This creates a CPAN::Meta::Merge object. It takes one mandatory named argument, C, declaring the version of the meta-spec that must be used for the merge. It can optionally take an C argument that allows one to add additional merging functions for specific elements. =head2 merge(@fragments) Merge all C<@fragments> together. It will accept both CPAN::Meta objects and (possibly incomplete) hashrefs of metadata. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut CPAN-Meta-2.150005/lib/CPAN/Meta/Prereqs.pm000644 000765 000024 00000027202 12535707053 017753 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; package CPAN::Meta::Prereqs; our $VERSION = '2.150005'; #pod =head1 DESCRIPTION #pod #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN #pod distribution or one of its optional features. Each set of prereqs is #pod organized by phase and type, as described in L. #pod #pod =cut use Carp qw(confess); use Scalar::Util qw(blessed); use CPAN::Meta::Requirements 2.121; #pod =method new #pod #pod my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec ); #pod #pod This method returns a new set of Prereqs. The input should look like the #pod contents of the C field described in L, meaning #pod something more or less like this: #pod #pod my $prereq = CPAN::Meta::Prereqs->new({ #pod runtime => { #pod requires => { #pod 'Some::Module' => '1.234', #pod ..., #pod }, #pod ..., #pod }, #pod ..., #pod }); #pod #pod You can also construct an empty set of prereqs with: #pod #pod my $prereqs = CPAN::Meta::Prereqs->new; #pod #pod This empty set of prereqs is useful for accumulating new prereqs before finally #pod dumping the whole set into a structure or string. #pod #pod =cut sub __legal_phases { qw(configure build test runtime develop) } sub __legal_types { qw(requires recommends suggests conflicts) } # expect a prereq spec from META.json -- rjbs, 2010-04-11 sub new { my ($class, $prereq_spec) = @_; $prereq_spec ||= {}; my %is_legal_phase = map {; $_ => 1 } $class->__legal_phases; my %is_legal_type = map {; $_ => 1 } $class->__legal_types; my %guts; PHASE: for my $phase (keys %$prereq_spec) { next PHASE unless $phase =~ /\Ax_/i or $is_legal_phase{$phase}; my $phase_spec = $prereq_spec->{ $phase }; next PHASE unless keys %$phase_spec; TYPE: for my $type (keys %$phase_spec) { next TYPE unless $type =~ /\Ax_/i or $is_legal_type{$type}; my $spec = $phase_spec->{ $type }; next TYPE unless keys %$spec; $guts{prereqs}{$phase}{$type} = CPAN::Meta::Requirements->from_string_hash( $spec ); } } return bless \%guts => $class; } #pod =method requirements_for #pod #pod my $requirements = $prereqs->requirements_for( $phase, $type ); #pod #pod This method returns a L object for the given #pod phase/type combination. If no prerequisites are registered for that #pod combination, a new CPAN::Meta::Requirements object will be returned, and it may #pod be added to as needed. #pod #pod If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will #pod be raised. #pod #pod =cut sub requirements_for { my ($self, $phase, $type) = @_; confess "requirements_for called without phase" unless defined $phase; confess "requirements_for called without type" unless defined $type; unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) { confess "requested requirements for unknown phase: $phase"; } unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) { confess "requested requirements for unknown type: $type"; } my $req = ($self->{prereqs}{$phase}{$type} ||= CPAN::Meta::Requirements->new); $req->finalize if $self->is_finalized; return $req; } #pod =method with_merged_prereqs #pod #pod my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs ); #pod #pod my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs ); #pod #pod This method returns a new CPAN::Meta::Prereqs objects in which all the #pod other prerequisites given are merged into the current set. This is primarily #pod provided for combining a distribution's core prereqs with the prereqs of one of #pod its optional features. #pod #pod The new prereqs object has no ties to the originals, and altering it further #pod will not alter them. #pod #pod =cut sub with_merged_prereqs { my ($self, $other) = @_; my @other = blessed($other) ? $other : @$other; my @prereq_objs = ($self, @other); my %new_arg; for my $phase ($self->__legal_phases) { for my $type ($self->__legal_types) { my $req = CPAN::Meta::Requirements->new; for my $prereq (@prereq_objs) { my $this_req = $prereq->requirements_for($phase, $type); next unless $this_req->required_modules; $req->add_requirements($this_req); } next unless $req->required_modules; $new_arg{ $phase }{ $type } = $req->as_string_hash; } } return (ref $self)->new(\%new_arg); } #pod =method merged_requirements #pod #pod my $new_reqs = $prereqs->merged_requirements( \@phases, \@types ); #pod my $new_reqs = $prereqs->merged_requirements( \@phases ); #pod my $new_reqs = $prereqs->merged_requirements(); #pod #pod This method joins together all requirements across a number of phases #pod and types into a new L object. If arguments #pod are omitted, it defaults to "runtime", "build" and "test" for phases #pod and "requires" and "recommends" for types. #pod #pod =cut sub merged_requirements { my ($self, $phases, $types) = @_; $phases = [qw/runtime build test/] unless defined $phases; $types = [qw/requires recommends/] unless defined $types; confess "merged_requirements phases argument must be an arrayref" unless ref $phases eq 'ARRAY'; confess "merged_requirements types argument must be an arrayref" unless ref $types eq 'ARRAY'; my $req = CPAN::Meta::Requirements->new; for my $phase ( @$phases ) { unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) { confess "requested requirements for unknown phase: $phase"; } for my $type ( @$types ) { unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) { confess "requested requirements for unknown type: $type"; } $req->add_requirements( $self->requirements_for($phase, $type) ); } } $req->finalize if $self->is_finalized; return $req; } #pod =method as_string_hash #pod #pod This method returns a hashref containing structures suitable for dumping into a #pod distmeta data structure. It is made up of hashes and strings, only; there will #pod be no Prereqs, CPAN::Meta::Requirements, or C objects inside it. #pod #pod =cut sub as_string_hash { my ($self) = @_; my %hash; for my $phase ($self->__legal_phases) { for my $type ($self->__legal_types) { my $req = $self->requirements_for($phase, $type); next unless $req->required_modules; $hash{ $phase }{ $type } = $req->as_string_hash; } } return \%hash; } #pod =method is_finalized #pod #pod This method returns true if the set of prereqs has been marked "finalized," and #pod cannot be altered. #pod #pod =cut sub is_finalized { $_[0]{finalized} } #pod =method finalize #pod #pod Calling C on a Prereqs object will close it for further modification. #pod Attempting to make any changes that would actually alter the prereqs will #pod result in an exception being thrown. #pod #pod =cut sub finalize { my ($self) = @_; $self->{finalized} = 1; for my $phase (keys %{ $self->{prereqs} }) { $_->finalize for values %{ $self->{prereqs}{$phase} }; } } #pod =method clone #pod #pod my $cloned_prereqs = $prereqs->clone; #pod #pod This method returns a Prereqs object that is identical to the original object, #pod but can be altered without affecting the original object. Finalization does #pod not survive cloning, meaning that you may clone a finalized set of prereqs and #pod then modify the clone. #pod #pod =cut sub clone { my ($self) = @_; my $clone = (ref $self)->new( $self->as_string_hash ); } 1; # ABSTRACT: a set of distribution prerequisites by phase and type =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type =head1 VERSION version 2.150005 =head1 DESCRIPTION A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN distribution or one of its optional features. Each set of prereqs is organized by phase and type, as described in L. =head1 METHODS =head2 new my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec ); This method returns a new set of Prereqs. The input should look like the contents of the C field described in L, meaning something more or less like this: my $prereq = CPAN::Meta::Prereqs->new({ runtime => { requires => { 'Some::Module' => '1.234', ..., }, ..., }, ..., }); You can also construct an empty set of prereqs with: my $prereqs = CPAN::Meta::Prereqs->new; This empty set of prereqs is useful for accumulating new prereqs before finally dumping the whole set into a structure or string. =head2 requirements_for my $requirements = $prereqs->requirements_for( $phase, $type ); This method returns a L object for the given phase/type combination. If no prerequisites are registered for that combination, a new CPAN::Meta::Requirements object will be returned, and it may be added to as needed. If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will be raised. =head2 with_merged_prereqs my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs ); my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs ); This method returns a new CPAN::Meta::Prereqs objects in which all the other prerequisites given are merged into the current set. This is primarily provided for combining a distribution's core prereqs with the prereqs of one of its optional features. The new prereqs object has no ties to the originals, and altering it further will not alter them. =head2 merged_requirements my $new_reqs = $prereqs->merged_requirements( \@phases, \@types ); my $new_reqs = $prereqs->merged_requirements( \@phases ); my $new_reqs = $prereqs->merged_requirements(); This method joins together all requirements across a number of phases and types into a new L object. If arguments are omitted, it defaults to "runtime", "build" and "test" for phases and "requires" and "recommends" for types. =head2 as_string_hash This method returns a hashref containing structures suitable for dumping into a distmeta data structure. It is made up of hashes and strings, only; there will be no Prereqs, CPAN::Meta::Requirements, or C objects inside it. =head2 is_finalized This method returns true if the set of prereqs has been marked "finalized," and cannot be altered. =head2 finalize Calling C on a Prereqs object will close it for further modification. Attempting to make any changes that would actually alter the prereqs will result in an exception being thrown. =head2 clone my $cloned_prereqs = $prereqs->clone; This method returns a Prereqs object that is identical to the original object, but can be altered without affecting the original object. Finalization does not survive cloning, meaning that you may clone a finalized set of prereqs and then modify the clone. =head1 BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at L When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/lib/CPAN/Meta/Spec.pm000644 000765 000024 00000107761 12535707053 017235 0ustar00davidstaff000000 000000 # XXX RULES FOR PATCHING THIS FILE XXX # Patches that fix typos or formatting are acceptable. Patches # that change semantics are not acceptable without prior approval # by David Golden or Ricardo Signes. use 5.006; use strict; use warnings; package CPAN::Meta::Spec; our $VERSION = '2.150005'; 1; # ABSTRACT: specification for CPAN distribution metadata # vi:tw=72 __END__ =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Spec - specification for CPAN distribution metadata =head1 VERSION version 2.150005 =head1 SYNOPSIS my $distmeta = { name => 'Module-Build', abstract => 'Build and install Perl modules', description => "Module::Build is a system for " . "building, testing, and installing Perl modules. " . "It is meant to ... blah blah blah ...", version => '0.36', release_status => 'stable', author => [ 'Ken Williams ', 'Module-Build List ', # additional contact ], license => [ 'perl_5' ], prereqs => { runtime => { requires => { 'perl' => '5.006', 'ExtUtils::Install' => '0', 'File::Basename' => '0', 'File::Compare' => '0', 'IO::File' => '0', }, recommends => { 'Archive::Tar' => '1.00', 'ExtUtils::Install' => '0.3', 'ExtUtils::ParseXS' => '2.02', }, }, build => { requires => { 'Test::More' => '0', }, } }, resources => { license => ['http://dev.perl.org/licenses/'], }, optional_features => { domination => { description => 'Take over the world', prereqs => { develop => { requires => { 'Genius::Evil' => '1.234' } }, runtime => { requires => { 'Machine::Weather' => '2.0' } }, }, }, }, dynamic_config => 1, keywords => [ qw/ toolchain cpan dual-life / ], 'meta-spec' => { version => '2', url => 'https://metacpan.org/pod/CPAN::Meta::Spec', }, generated_by => 'Module::Build version 0.36', }; =head1 DESCRIPTION This document describes version 2 of the CPAN distribution metadata specification, also known as the "CPAN Meta Spec". Revisions of this specification for typo corrections and prose clarifications may be issued as CPAN::Meta::Spec 2.I. These revisions will never change semantics or add or remove specified behavior. Distribution metadata describe important properties of Perl distributions. Distribution building tools like Module::Build, Module::Install, ExtUtils::MakeMaker or Dist::Zilla should create a metadata file in accordance with this specification and include it with the distribution for use by automated tools that index, examine, package or install Perl distributions. =head1 TERMINOLOGY =over 4 =item distribution This is the primary object described by the metadata. In the context of this document it usually refers to a collection of modules, scripts, and/or documents that are distributed together for other developers to use. Examples of distributions are C, C, or C. =item module This refers to a reusable library of code contained in a single file. Modules usually contain one or more packages and are often referred to by the name of a primary package that can be mapped to the file name. For example, one might refer to C instead of F =item package This refers to a namespace declared with the Perl C statement. In Perl, packages often have a version number property given by the C<$VERSION> variable in the namespace. =item consumer This refers to code that reads a metadata file, deserializes it into a data structure in memory, or interprets a data structure of metadata elements. =item producer This refers to code that constructs a metadata data structure, serializes into a bytestream and/or writes it to disk. =item must, should, may, etc. These terms are interpreted as described in IETF RFC 2119. =back =head1 DATA TYPES Fields in the L section describe data elements, each of which has an associated data type as described herein. There are four primitive types: Boolean, String, List and Map. Other types are subtypes of primitives and define compound data structures or define constraints on the values of a data element. =head2 Boolean A I is used to provide a true or false value. It B be represented as a defined value. =head2 String A I is data element containing a non-zero length sequence of Unicode characters, such as an ordinary Perl scalar that is not a reference. =head2 List A I is an ordered collection of zero or more data elements. Elements of a List may be of mixed types. Producers B represent List elements using a data structure which unambiguously indicates that multiple values are possible, such as a reference to a Perl array (an "arrayref"). Consumers expecting a List B consider a String as equivalent to a List of length 1. =head2 Map A I is an unordered collection of zero or more data elements ("values"), indexed by associated String elements ("keys"). The Map's value elements may be of mixed types. =head2 License String A I is a subtype of String with a restricted set of values. Valid values are described in detail in the description of the L field. =head2 URL I is a subtype of String containing a Uniform Resource Locator or Identifier. [ This type is called URL and not URI for historical reasons. ] =head2 Version A I is a subtype of String containing a value that describes the version number of packages or distributions. Restrictions on format are described in detail in the L section. =head2 Version Range The I type is a subtype of String. It describes a range of Versions that may be present or installed to fulfill prerequisites. It is specified in detail in the L section. =head1 STRUCTURE The metadata structure is a data element of type Map. This section describes valid keys within the Map. Any keys not described in this specification document (whether top-level or within compound data structures described herein) are considered I and B begin with an "x" or "X" and be followed by an underscore; i.e. they must match the pattern: C<< qr{\Ax_}i >>. If a custom key refers to a compound data structure, subkeys within it do not need an "x_" or "X_" prefix. Consumers of metadata may ignore any or all custom keys. All other keys not described herein are invalid and should be ignored by consumers. Producers must not generate or output invalid keys. For each key, an example is provided followed by a description. The description begins with the version of spec in which the key was added or in which the definition was modified, whether the key is I or I and the data type of the corresponding data element. These items are in parentheses, brackets and braces, respectively. If a data type is a Map or Map subtype, valid subkeys will be described as well. Some fields are marked I. These are shown for historical context and must not be produced in or consumed from any metadata structure of version 2 or higher. =head2 REQUIRED FIELDS =head3 abstract Example: abstract => 'Build and install Perl modules' (Spec 1.2) [required] {String} This is a short description of the purpose of the distribution. =head3 author Example: author => [ 'Ken Williams ' ] (Spec 1.2) [required] {List of one or more Strings} This List indicates the person(s) to contact concerning the distribution. The preferred form of the contact string is: contact-name This field provides a general contact list independent of other structured fields provided within the L field, such as C. The addressee(s) can be contacted for any purpose including but not limited to (security) problems with the distribution, questions about the distribution or bugs in the distribution. A distribution's original author is usually the contact listed within this field. Co-maintainers, successor maintainers or mailing lists devoted to the distribution may also be listed in addition to or instead of the original author. =head3 dynamic_config Example: dynamic_config => 1 (Spec 2) [required] {Boolean} A boolean flag indicating whether a F or F (or similar) must be executed to determine prerequisites. This field should be set to a true value if the distribution performs some dynamic configuration (asking questions, sensing the environment, etc.) as part of its configuration. This field should be set to a false value to indicate that prerequisites included in metadata may be considered final and valid for static analysis. Note: when this field is true, post-configuration prerequisites are not guaranteed to bear any relation whatsoever to those stated in the metadata, and relying on them doing so is an error. See also L in the implementors' notes. This field explicitly B indicate whether installation may be safely performed without using a Makefile or Build file, as there may be special files to install or custom installation targets (e.g. for dual-life modules that exist on CPAN as well as in the Perl core). This field only defines whether or not prerequisites are exactly as given in the metadata. =head3 generated_by Example: generated_by => 'Module::Build version 0.36' (Spec 1.0) [required] {String} This field indicates the tool that was used to create this metadata. There are no defined semantics for this field, but it is traditional to use a string in the form "Generating::Package version 1.23" or the author's name, if the file was generated by hand. =head3 license Example: license => [ 'perl_5' ] license => [ 'apache_2_0', 'mozilla_1_0' ] (Spec 2) [required] {List of one or more License Strings} One or more licenses that apply to some or all of the files in the distribution. If multiple licenses are listed, the distribution documentation should be consulted to clarify the interpretation of multiple licenses. The following list of license strings are valid: string description ------------- ----------------------------------------------- agpl_3 GNU Affero General Public License, Version 3 apache_1_1 Apache Software License, Version 1.1 apache_2_0 Apache License, Version 2.0 artistic_1 Artistic License, (Version 1) artistic_2 Artistic License, Version 2.0 bsd BSD License (three-clause) freebsd FreeBSD License (two-clause) gfdl_1_2 GNU Free Documentation License, Version 1.2 gfdl_1_3 GNU Free Documentation License, Version 1.3 gpl_1 GNU General Public License, Version 1 gpl_2 GNU General Public License, Version 2 gpl_3 GNU General Public License, Version 3 lgpl_2_1 GNU Lesser General Public License, Version 2.1 lgpl_3_0 GNU Lesser General Public License, Version 3.0 mit MIT (aka X11) License mozilla_1_0 Mozilla Public License, Version 1.0 mozilla_1_1 Mozilla Public License, Version 1.1 openssl OpenSSL License perl_5 The Perl 5 License (Artistic 1 & GPL 1 or later) qpl_1_0 Q Public License, Version 1.0 ssleay Original SSLeay License sun Sun Internet Standards Source License (SISSL) zlib zlib License The following license strings are also valid and indicate other licensing not described above: string description ------------- ----------------------------------------------- open_source Other Open Source Initiative (OSI) approved license restricted Requires special permission from copyright holder unrestricted Not an OSI approved license, but not restricted unknown License not provided in metadata All other strings are invalid in the license field. =head3 meta-spec Example: 'meta-spec' => { version => '2', url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', } (Spec 1.2) [required] {Map} This field indicates the version of the CPAN Meta Spec that should be used to interpret the metadata. Consumers must check this key as soon as possible and abort further metadata processing if the meta-spec version is not supported by the consumer. The following keys are valid, but only C is required. =over =item version This subkey gives the integer I of the CPAN Meta Spec against which the document was generated. =item url This is a I of the metadata specification document corresponding to the given version. This is strictly for human-consumption and should not impact the interpretation of the document. For the version 2 spec, either of these are recommended: =over 4 =item * C =item * C =back =back =head3 name Example: name => 'Module-Build' (Spec 1.0) [required] {String} This field is the name of the distribution. This is often created by taking the "main package" in the distribution and changing C<::> to C<->, but the name may be completely unrelated to the packages within the distribution. For example, L is distributed as part of the distribution name "libwww-perl". =head3 release_status Example: release_status => 'stable' (Spec 2) [required] {String} This field provides the release status of this distribution. If the C field contains an underscore character, then C B be "stable." The C field B have one of the following values: =over =item stable This indicates an ordinary, "final" release that should be indexed by PAUSE or other indexers. =item testing This indicates a "beta" release that is substantially complete, but has an elevated risk of bugs and requires additional testing. The distribution should not be installed over a stable release without an explicit request or other confirmation from a user. This release status may also be used for "release candidate" versions of a distribution. =item unstable This indicates an "alpha" release that is under active development, but has been released for early feedback or testing and may be missing features or may have serious bugs. The distribution should not be installed over a stable release without an explicit request or other confirmation from a user. =back Consumers B use this field to determine how to index the distribution for CPAN or other repositories in addition to or in replacement of heuristics based on version number or file name. =head3 version Example: version => '0.36' (Spec 1.0) [required] {Version} This field gives the version of the distribution to which the metadata structure refers. =head2 OPTIONAL FIELDS =head3 description Example: description => "Module::Build is a system for " . "building, testing, and installing Perl modules. " . "It is meant to ... blah blah blah ...", (Spec 2) [optional] {String} A longer, more complete description of the purpose or intended use of the distribution than the one provided by the C key. =head3 keywords Example: keywords => [ qw/ toolchain cpan dual-life / ] (Spec 1.1) [optional] {List of zero or more Strings} A List of keywords that describe this distribution. Keywords B include whitespace. =head3 no_index Example: no_index => { file => [ 'My/Module.pm' ], directory => [ 'My/Private' ], package => [ 'My::Module::Secret' ], namespace => [ 'My::Module::Sample' ], } (Spec 1.2) [optional] {Map} This Map describes any files, directories, packages, and namespaces that are private to the packaging or implementation of the distribution and should be ignored by indexing or search tools. Note that this is a list of exclusions, and the spec does not define what to I - see L in the implementors notes for more information. Valid subkeys are as follows: =over =item file A I of relative paths to files. Paths B specified with unix conventions. =item directory A I of relative paths to directories. Paths B specified with unix conventions. [ Note: previous editions of the spec had C instead of C ] =item package A I of package names. =item namespace A I of package namespaces, where anything below the namespace must be ignored, but I the namespace itself. In the example above for C, C would be ignored, but C would not. =back =head3 optional_features Example: optional_features => { sqlite => { description => 'Provides SQLite support', prereqs => { runtime => { requires => { 'DBD::SQLite' => '1.25' } } } } } (Spec 2) [optional] {Map} This Map describes optional features with incremental prerequisites. Each key of the C Map is a String used to identify the feature and each value is a Map with additional information about the feature. Valid subkeys include: =over =item description This is a String describing the feature. Every optional feature should provide a description =item prereqs This entry is required and has the same structure as that of the C> key. It provides a list of package requirements that must be satisfied for the feature to be supported or enabled. There is one crucial restriction: the prereqs of an optional feature B include C phase prereqs. =back Consumers B include optional features as prerequisites without explicit instruction from users (whether via interactive prompting, a function parameter or a configuration value, etc. ). If an optional feature is used by a consumer to add additional prerequisites, the consumer should merge the optional feature prerequisites into those given by the C key using the same semantics. See L for details on merging prerequisites. I Because there is currently no way for a distribution to specify a dependency on an optional feature of another dependency, the use of C is discouraged. Instead, create a separate, installable distribution that ensures the desired feature is available. For example, if C has a C feature, release a separate C distribution that satisfies requirements for the feature. =head3 prereqs Example: prereqs => { runtime => { requires => { 'perl' => '5.006', 'File::Spec' => '0.86', 'JSON' => '2.16', }, recommends => { 'JSON::XS' => '2.26', }, suggests => { 'Archive::Tar' => '0', }, }, build => { requires => { 'Alien::SDL' => '1.00', }, }, test => { recommends => { 'Test::Deep' => '0.10', }, } } (Spec 2) [optional] {Map} This is a Map that describes all the prerequisites of the distribution. The keys are phases of activity, such as C, C, C or C. Values are Maps in which the keys name the type of prerequisite relationship such as C, C, or C and the value provides a set of prerequisite relations. The set of relations B be specified as a Map of package names to version ranges. The full definition for this field is given in the L section. =head3 provides Example: provides => { 'Foo::Bar' => { file => 'lib/Foo/Bar.pm', version => '0.27_02', }, 'Foo::Bar::Blah' => { file => 'lib/Foo/Bar/Blah.pm', }, 'Foo::Bar::Baz' => { file => 'lib/Foo/Bar/Baz.pm', version => '0.3', }, } (Spec 1.2) [optional] {Map} This describes all packages provided by this distribution. This information is used by distribution and automation mechanisms like PAUSE, CPAN, metacpan.org and search.cpan.org to build indexes saying in which distribution various packages can be found. The keys of C are package names that can be found within the distribution. If a package name key is provided, it must have a Map with the following valid subkeys: =over =item file This field is required. It must contain a Unix-style relative file path from the root of the distribution directory to a file that contains or generates the package. It may be given as C or C to claim a package for indexing without needing a C<*.pm>. =item version If it exists, this field must contains a I String for the package. If the package does not have a C<$VERSION>, this field must be omitted. =back =head3 resources Example: resources => { license => [ 'http://dev.perl.org/licenses/' ], homepage => 'http://sourceforge.net/projects/module-build', bugtracker => { web => 'http://rt.cpan.org/Public/Dist/Display.html?Name=CPAN-Meta', mailto => 'meta-bugs@example.com', }, repository => { url => 'git://github.com/dagolden/cpan-meta.git', web => 'http://github.com/dagolden/cpan-meta', type => 'git', }, x_twitter => 'http://twitter.com/cpan_linked/', } (Spec 2) [optional] {Map} This field describes resources related to this distribution. Valid subkeys include: =over =item homepage The official home of this project on the web. =item license A List of I's that relate to this distribution's license. As with the top-level C field, distribution documentation should be consulted to clarify the interpretation of multiple licenses provided here. =item bugtracker This entry describes the bug tracking system for this distribution. It is a Map with the following valid keys: web - a URL pointing to a web front-end for the bug tracker mailto - an email address to which bugs can be sent =item repository This entry describes the source control repository for this distribution. It is a Map with the following valid keys: url - a URL pointing to the repository itself web - a URL pointing to a web front-end for the repository type - a lowercase string indicating the VCS used Because a url like C is ambiguous as to type, producers should provide a C whenever a C key is given. The C field should be the name of the most common program used to work with the repository, e.g. C, C, C, C, C or C. =back =head2 DEPRECATED FIELDS =head3 build_requires I<(Deprecated in Spec 2)> [optional] {String} Replaced by C =head3 configure_requires I<(Deprecated in Spec 2)> [optional] {String} Replaced by C =head3 conflicts I<(Deprecated in Spec 2)> [optional] {String} Replaced by C =head3 distribution_type I<(Deprecated in Spec 2)> [optional] {String} This field indicated 'module' or 'script' but was considered meaningless, since many distributions are hybrids of several kinds of things. =head3 license_uri I<(Deprecated in Spec 1.2)> [optional] {URL} Replaced by C in C =head3 private I<(Deprecated in Spec 1.2)> [optional] {Map} This field has been renamed to L. =head3 recommends I<(Deprecated in Spec 2)> [optional] {String} Replaced by C =head3 requires I<(Deprecated in Spec 2)> [optional] {String} Replaced by C =head1 VERSION NUMBERS =head2 Version Formats This section defines the Version type, used by several fields in the CPAN Meta Spec. Version numbers must be treated as strings, not numbers. For example, C<1.200> B be serialized as C<1.2>. Version comparison should be delegated to the Perl L module, version 0.80 or newer. Unless otherwise specified, version numbers B appear in one of two formats: =over =item Decimal versions Decimal versions are regular "decimal numbers", with some limitations. They B be non-negative and B begin and end with a digit. A single underscore B be included, but B be between two digits. They B use exponential notation ("1.23e-2"). version => '1.234' # OK version => '1.23_04' # OK version => '1.23_04_05' # Illegal version => '1.' # Illegal version => '.1' # Illegal =item Dotted-integer versions Dotted-integer (also known as dotted-decimal) versions consist of positive integers separated by full stop characters (i.e. "dots", "periods" or "decimal points"). This are equivalent in format to Perl "v-strings", with some additional restrictions on form. They must be given in "normal" form, which has a leading "v" character and at least three integer components. To retain a one-to-one mapping with decimal versions, all components after the first B be restricted to the range 0 to 999. The final component B be separated by an underscore character instead of a period. version => 'v1.2.3' # OK version => 'v1.2_3' # OK version => 'v1.2.3.4' # OK version => 'v1.2.3_4' # OK version => 'v2009.10.31' # OK version => 'v1.2' # Illegal version => '1.2.3' # Illegal version => 'v1.2_3_4' # Illegal version => 'v1.2009.10.31' # Not recommended =back =head2 Version Ranges Some fields (prereq, optional_features) indicate the particular version(s) of some other module that may be required as a prerequisite. This section details the Version Range type used to provide this information. The simplest format for a Version Range is just the version number itself, e.g. C<2.4>. This means that B version 2.4 must be present. To indicate that B version of a prerequisite is okay, even if the prerequisite doesn't define a version at all, use the version C<0>. Alternatively, a version range B use the operators E (less than), E= (less than or equal), E (greater than), E= (greater than or equal), == (equal), and != (not equal). For example, the specification C 2.0> means that any version of the prerequisite less than 2.0 is suitable. For more complicated situations, version specifications B be AND-ed together using commas. The specification C= 1.2, != 1.5, E 2.0> indicates a version that must be B 1.2, B 2.0, and B 1.5. =head1 PREREQUISITES =head2 Prereq Spec The C key in the top-level metadata and within C define the relationship between a distribution and other packages. The prereq spec structure is a hierarchical data structure which divides prerequisites into I of activity in the installation process and I that indicate how prerequisites should be resolved. For example, to specify that C is C during the C phase, this entry would appear in the distribution metadata: prereqs => { test => { requires => { 'Data::Dumper' => '2.00' } } } =head3 Phases Requirements for regular use must be listed in the C phase. Other requirements should be listed in the earliest stage in which they are required and consumers must accumulate and satisfy requirements across phases before executing the activity. For example, C requirements must also be available during the C phase. before action requirements that must be met ---------------- -------------------------------- perl Build.PL configure perl Makefile.PL make configure, runtime, build Build make test configure, runtime, build, test Build test Consumers that install the distribution must ensure that I requirements are also installed and may install dependencies from other phases. after action requirements that must be met ---------------- -------------------------------- make install runtime Build install =over =item configure The configure phase occurs before any dynamic configuration has been attempted. Libraries required by the configure phase B be available for use before the distribution building tool has been executed. =item build The build phase is when the distribution's source code is compiled (if necessary) and otherwise made ready for installation. =item test The test phase is when the distribution's automated test suite is run. Any library that is needed only for testing and not for subsequent use should be listed here. =item runtime The runtime phase refers not only to when the distribution's contents are installed, but also to its continued use. Any library that is a prerequisite for regular use of this distribution should be indicated here. =item develop The develop phase's prereqs are libraries needed to work on the distribution's source code as its author does. These tools might be needed to build a release tarball, to run author-only tests, or to perform other tasks related to developing new versions of the distribution. =back =head3 Relationships =over =item requires These dependencies B be installed for proper completion of the phase. =item recommends Recommended dependencies are I encouraged and should be satisfied except in resource constrained environments. =item suggests These dependencies are optional, but are suggested for enhanced operation of the described distribution. =item conflicts These libraries cannot be installed when the phase is in operation. This is a very rare situation, and the C relationship should be used with great caution, or not at all. =back =head2 Merging and Resolving Prerequisites Whenever metadata consumers merge prerequisites, either from different phases or from C, they should merged in a way which preserves the intended semantics of the prerequisite structure. Generally, this means concatenating the version specifications using commas, as described in the L section. Another subtle error that can occur in resolving prerequisites comes from the way that modules in prerequisites are indexed to distribution files on CPAN. When a module is deleted from a distribution, prerequisites calling for that module could indicate an older distribution should be installed, potentially overwriting files from a newer distribution. For example, as of Oct 31, 2009, the CPAN index file contained these module-distribution mappings: Class::MOP 0.94 D/DR/DROLSKY/Class-MOP-0.94.tar.gz Class::MOP::Class 0.94 D/DR/DROLSKY/Class-MOP-0.94.tar.gz Class::MOP::Class::Immutable 0.04 S/ST/STEVAN/Class-MOP-0.36.tar.gz Consider the case where "Class::MOP" 0.94 is installed. If a distribution specified "Class::MOP::Class::Immutable" as a prerequisite, it could result in Class-MOP-0.36.tar.gz being installed, overwriting any files from Class-MOP-0.94.tar.gz. Consumers of metadata B test whether prerequisites would result in installed module files being "downgraded" to an older version and B warn users or ignore the prerequisite that would cause such a result. =head1 SERIALIZATION Distribution metadata should be serialized (as a hashref) as JSON-encoded data and packaged with distributions as the file F. In the past, the distribution metadata structure had been packed with distributions as F, a file in the YAML Tiny format (for which, see L). Tools that consume distribution metadata from disk should be capable of loading F, but should prefer F if both are found. =head1 NOTES FOR IMPLEMENTORS =head2 Extracting Version Numbers from Perl Modules To get the version number from a Perl module, consumers should use the C<< MM->parse_version($file) >> method provided by L or L. For example, for the module given by C<$mod>, the version may be retrieved in one of the following ways: # via ExtUtils::MakeMaker my $file = MM->_installed_file_for_module($mod); my $version = MM->parse_version($file) The private C<_installed_file_for_module> method may be replaced with other methods for locating a module in C<@INC>. # via Module::Metadata my $info = Module::Metadata->new_from_module($mod); my $version = $info->version; If only a filename is available, the following approach may be used: # via Module::Build my $info = Module::Metadata->new_from_file($file); my $version = $info->version; =head2 Comparing Version Numbers The L module provides the most reliable way to compare version numbers in all the various ways they might be provided or might exist within modules. Given two strings containing version numbers, C<$v1> and C<$v2>, they should be converted to C objects before using ordinary comparison operators. For example: use version; if ( version->new($v1) <=> version->new($v2) ) { print "Versions are not equal\n"; } If the only comparison needed is whether an installed module is of a sufficiently high version, a direct test may be done using the string form of C and the C function. For example, for module C<$mod> and version prerequisite C<$prereq>: if ( eval "use $mod $prereq (); 1" ) { print "Module $mod version is OK.\n"; } If the values of C<$mod> and C<$prereq> have not been scrubbed, however, this presents security implications. =head2 Prerequisites for dynamically configured distributions When C is true, it is an error to presume that the prerequisites given in distribution metadata will have any relationship whatsoever to the actual prerequisites of the distribution. In practice, however, one can generally expect such prerequisites to be one of two things: =over 4 =item * The minimum prerequisites for the distribution, to which dynamic configuration will only add items =item * Whatever the distribution configured with on the releaser's machine at release time =back The second case often turns out to have identical results to the first case, albeit only by accident. As such, consumers may use this data for informational analysis, but presenting it to the user as canonical or relying on it as such is invariably the height of folly. =head2 Indexing distributions a la PAUSE While no_index tells you what must be ignored when indexing, this spec holds no opinion on how you should get your initial candidate list of things to possibly index. For "normal" distributions you might consider simply indexing the contents of lib/, but there are many fascinating oddities on CPAN and many dists from the days when it was normal to put the main .pm file in the root of the distribution archive - so PAUSE currently indexes all .pm and .PL files that are not either (a) specifically excluded by no_index (b) in C, C, or C directories, or common 'mistake' directories such as C. Or: If you're trying to be PAUSE-like, make sure you skip C, C and C as well as anything marked as no_index. Also remember: If the META file contains a provides field, you shouldn't be indexing anything in the first place - just use that. =head1 SEE ALSO =over 4 =item * CPAN, L =item * JSON, L =item * YAML, L =item * L =item * L =item * L =item * L =item * L =back =head1 HISTORY Ken Williams wrote the original CPAN Meta Spec (also known as the "META.yml spec") in 2003 and maintained it through several revisions with input from various members of the community. In 2005, Randy Sims redrafted it from HTML to POD for the version 1.2 release. Ken continued to maintain the spec through version 1.4. In late 2009, David Golden organized the version 2 proposal review process. David and Ricardo Signes drafted the final version 2 spec in April 2010 based on the version 1.4 spec and patches contributed during the proposal process. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut CPAN-Meta-2.150005/lib/CPAN/Meta/Validator.pm000644 000765 000024 00000102161 12535707053 020255 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; package CPAN::Meta::Validator; our $VERSION = '2.150005'; #pod =head1 SYNOPSIS #pod #pod my $struct = decode_json_file('META.json'); #pod #pod my $cmv = CPAN::Meta::Validator->new( $struct ); #pod #pod unless ( $cmv->is_valid ) { #pod my $msg = "Invalid META structure. Errors found:\n"; #pod $msg .= join( "\n", $cmv->errors ); #pod die $msg; #pod } #pod #pod =head1 DESCRIPTION #pod #pod This module validates a CPAN Meta structure against the version of the #pod the specification claimed in the C field of the structure. #pod #pod =cut #--------------------------------------------------------------------------# # This code copied and adapted from Test::CPAN::Meta # by Barbie, for Miss Barbell Productions, # L #--------------------------------------------------------------------------# #--------------------------------------------------------------------------# # Specification Definitions #--------------------------------------------------------------------------# my %known_specs = ( '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html', '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html', '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html', '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html', '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html' ); my %known_urls = map {$known_specs{$_} => $_} keys %known_specs; my $module_map1 = { 'map' => { ':key' => { name => \&module, value => \&exversion } } }; my $module_map2 = { 'map' => { ':key' => { name => \&module, value => \&version } } }; my $no_index_2 = { 'map' => { file => { list => { value => \&string } }, directory => { list => { value => \&string } }, 'package' => { list => { value => \&string } }, namespace => { list => { value => \&string } }, ':key' => { name => \&custom_2, value => \&anything }, } }; my $no_index_1_3 = { 'map' => { file => { list => { value => \&string } }, directory => { list => { value => \&string } }, 'package' => { list => { value => \&string } }, namespace => { list => { value => \&string } }, ':key' => { name => \&string, value => \&anything }, } }; my $no_index_1_2 = { 'map' => { file => { list => { value => \&string } }, dir => { list => { value => \&string } }, 'package' => { list => { value => \&string } }, namespace => { list => { value => \&string } }, ':key' => { name => \&string, value => \&anything }, } }; my $no_index_1_1 = { 'map' => { ':key' => { name => \&string, list => { value => \&string } }, } }; my $prereq_map = { map => { ':key' => { name => \&phase, 'map' => { ':key' => { name => \&relation, %$module_map1, }, }, } }, }; my %definitions = ( '2' => { # REQUIRED 'abstract' => { mandatory => 1, value => \&string }, 'author' => { mandatory => 1, list => { value => \&string } }, 'dynamic_config' => { mandatory => 1, value => \&boolean }, 'generated_by' => { mandatory => 1, value => \&string }, 'license' => { mandatory => 1, list => { value => \&license } }, 'meta-spec' => { mandatory => 1, 'map' => { version => { mandatory => 1, value => \&version}, url => { value => \&url }, ':key' => { name => \&custom_2, value => \&anything }, } }, 'name' => { mandatory => 1, value => \&string }, 'release_status' => { mandatory => 1, value => \&release_status }, 'version' => { mandatory => 1, value => \&version }, # OPTIONAL 'description' => { value => \&string }, 'keywords' => { list => { value => \&string } }, 'no_index' => $no_index_2, 'optional_features' => { 'map' => { ':key' => { name => \&string, 'map' => { description => { value => \&string }, prereqs => $prereq_map, ':key' => { name => \&custom_2, value => \&anything }, } } } }, 'prereqs' => $prereq_map, 'provides' => { 'map' => { ':key' => { name => \&module, 'map' => { file => { mandatory => 1, value => \&file }, version => { value => \&version }, ':key' => { name => \&custom_2, value => \&anything }, } } } }, 'resources' => { 'map' => { license => { list => { value => \&url } }, homepage => { value => \&url }, bugtracker => { 'map' => { web => { value => \&url }, mailto => { value => \&string}, ':key' => { name => \&custom_2, value => \&anything }, } }, repository => { 'map' => { web => { value => \&url }, url => { value => \&url }, type => { value => \&string }, ':key' => { name => \&custom_2, value => \&anything }, } }, ':key' => { value => \&string, name => \&custom_2 }, } }, # CUSTOM -- additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&custom_2, value => \&anything }, }, '1.4' => { 'meta-spec' => { mandatory => 1, 'map' => { version => { mandatory => 1, value => \&version}, url => { mandatory => 1, value => \&urlspec }, ':key' => { name => \&string, value => \&anything }, }, }, 'name' => { mandatory => 1, value => \&string }, 'version' => { mandatory => 1, value => \&version }, 'abstract' => { mandatory => 1, value => \&string }, 'author' => { mandatory => 1, list => { value => \&string } }, 'license' => { mandatory => 1, value => \&license }, 'generated_by' => { mandatory => 1, value => \&string }, 'distribution_type' => { value => \&string }, 'dynamic_config' => { value => \&boolean }, 'requires' => $module_map1, 'recommends' => $module_map1, 'build_requires' => $module_map1, 'configure_requires' => $module_map1, 'conflicts' => $module_map2, 'optional_features' => { 'map' => { ':key' => { name => \&string, 'map' => { description => { value => \&string }, requires => $module_map1, recommends => $module_map1, build_requires => $module_map1, conflicts => $module_map2, ':key' => { name => \&string, value => \&anything }, } } } }, 'provides' => { 'map' => { ':key' => { name => \&module, 'map' => { file => { mandatory => 1, value => \&file }, version => { value => \&version }, ':key' => { name => \&string, value => \&anything }, } } } }, 'no_index' => $no_index_1_3, 'private' => $no_index_1_3, 'keywords' => { list => { value => \&string } }, 'resources' => { 'map' => { license => { value => \&url }, homepage => { value => \&url }, bugtracker => { value => \&url }, repository => { value => \&url }, ':key' => { value => \&string, name => \&custom_1 }, } }, # additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&string, value => \&anything }, }, '1.3' => { 'meta-spec' => { mandatory => 1, 'map' => { version => { mandatory => 1, value => \&version}, url => { mandatory => 1, value => \&urlspec }, ':key' => { name => \&string, value => \&anything }, }, }, 'name' => { mandatory => 1, value => \&string }, 'version' => { mandatory => 1, value => \&version }, 'abstract' => { mandatory => 1, value => \&string }, 'author' => { mandatory => 1, list => { value => \&string } }, 'license' => { mandatory => 1, value => \&license }, 'generated_by' => { mandatory => 1, value => \&string }, 'distribution_type' => { value => \&string }, 'dynamic_config' => { value => \&boolean }, 'requires' => $module_map1, 'recommends' => $module_map1, 'build_requires' => $module_map1, 'conflicts' => $module_map2, 'optional_features' => { 'map' => { ':key' => { name => \&string, 'map' => { description => { value => \&string }, requires => $module_map1, recommends => $module_map1, build_requires => $module_map1, conflicts => $module_map2, ':key' => { name => \&string, value => \&anything }, } } } }, 'provides' => { 'map' => { ':key' => { name => \&module, 'map' => { file => { mandatory => 1, value => \&file }, version => { value => \&version }, ':key' => { name => \&string, value => \&anything }, } } } }, 'no_index' => $no_index_1_3, 'private' => $no_index_1_3, 'keywords' => { list => { value => \&string } }, 'resources' => { 'map' => { license => { value => \&url }, homepage => { value => \&url }, bugtracker => { value => \&url }, repository => { value => \&url }, ':key' => { value => \&string, name => \&custom_1 }, } }, # additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&string, value => \&anything }, }, # v1.2 is misleading, it seems to assume that a number of fields where created # within v1.1, when they were created within v1.2. This may have been an # original mistake, and that a v1.1 was retro fitted into the timeline, when # v1.2 was originally slated as v1.1. But I could be wrong ;) '1.2' => { 'meta-spec' => { mandatory => 1, 'map' => { version => { mandatory => 1, value => \&version}, url => { mandatory => 1, value => \&urlspec }, ':key' => { name => \&string, value => \&anything }, }, }, 'name' => { mandatory => 1, value => \&string }, 'version' => { mandatory => 1, value => \&version }, 'license' => { mandatory => 1, value => \&license }, 'generated_by' => { mandatory => 1, value => \&string }, 'author' => { mandatory => 1, list => { value => \&string } }, 'abstract' => { mandatory => 1, value => \&string }, 'distribution_type' => { value => \&string }, 'dynamic_config' => { value => \&boolean }, 'keywords' => { list => { value => \&string } }, 'private' => $no_index_1_2, '$no_index' => $no_index_1_2, 'requires' => $module_map1, 'recommends' => $module_map1, 'build_requires' => $module_map1, 'conflicts' => $module_map2, 'optional_features' => { 'map' => { ':key' => { name => \&string, 'map' => { description => { value => \&string }, requires => $module_map1, recommends => $module_map1, build_requires => $module_map1, conflicts => $module_map2, ':key' => { name => \&string, value => \&anything }, } } } }, 'provides' => { 'map' => { ':key' => { name => \&module, 'map' => { file => { mandatory => 1, value => \&file }, version => { value => \&version }, ':key' => { name => \&string, value => \&anything }, } } } }, 'resources' => { 'map' => { license => { value => \&url }, homepage => { value => \&url }, bugtracker => { value => \&url }, repository => { value => \&url }, ':key' => { value => \&string, name => \&custom_1 }, } }, # additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&string, value => \&anything }, }, # note that the 1.1 spec only specifies 'version' as mandatory '1.1' => { 'name' => { value => \&string }, 'version' => { mandatory => 1, value => \&version }, 'license' => { value => \&license }, 'generated_by' => { value => \&string }, 'license_uri' => { value => \&url }, 'distribution_type' => { value => \&string }, 'dynamic_config' => { value => \&boolean }, 'private' => $no_index_1_1, 'requires' => $module_map1, 'recommends' => $module_map1, 'build_requires' => $module_map1, 'conflicts' => $module_map2, # additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&string, value => \&anything }, }, # note that the 1.0 spec doesn't specify optional or mandatory fields # but we will treat version as mandatory since otherwise META 1.0 is # completely arbitrary and pointless '1.0' => { 'name' => { value => \&string }, 'version' => { mandatory => 1, value => \&version }, 'license' => { value => \&license }, 'generated_by' => { value => \&string }, 'license_uri' => { value => \&url }, 'distribution_type' => { value => \&string }, 'dynamic_config' => { value => \&boolean }, 'requires' => $module_map1, 'recommends' => $module_map1, 'build_requires' => $module_map1, 'conflicts' => $module_map2, # additional user defined key/value pairs # note we can only validate the key name, as the structure is user defined ':key' => { name => \&string, value => \&anything }, }, ); #--------------------------------------------------------------------------# # Code #--------------------------------------------------------------------------# #pod =method new #pod #pod my $cmv = CPAN::Meta::Validator->new( $struct ) #pod #pod The constructor must be passed a metadata structure. #pod #pod =cut sub new { my ($class,$data) = @_; # create an attributes hash my $self = { 'data' => $data, 'spec' => eval { $data->{'meta-spec'}{'version'} } || "1.0", 'errors' => undef, }; # create the object return bless $self, $class; } #pod =method is_valid #pod #pod if ( $cmv->is_valid ) { #pod ... #pod } #pod #pod Returns a boolean value indicating whether the metadata provided #pod is valid. #pod #pod =cut sub is_valid { my $self = shift; my $data = $self->{data}; my $spec_version = $self->{spec}; $self->check_map($definitions{$spec_version},$data); return ! $self->errors; } #pod =method errors #pod #pod warn( join "\n", $cmv->errors ); #pod #pod Returns a list of errors seen during validation. #pod #pod =cut sub errors { my $self = shift; return () unless(defined $self->{errors}); return @{$self->{errors}}; } #pod =begin :internals #pod #pod =head2 Check Methods #pod #pod =over #pod #pod =item * #pod #pod check_map($spec,$data) #pod #pod Checks whether a map (or hash) part of the data structure conforms to the #pod appropriate specification definition. #pod #pod =item * #pod #pod check_list($spec,$data) #pod #pod Checks whether a list (or array) part of the data structure conforms to #pod the appropriate specification definition. #pod #pod =item * #pod #pod =back #pod #pod =cut my $spec_error = "Missing validation action in specification. " . "Must be one of 'map', 'list', or 'value'"; sub check_map { my ($self,$spec,$data) = @_; if(ref($spec) ne 'HASH') { $self->_error( "Unknown META specification, cannot validate." ); return; } if(ref($data) ne 'HASH') { $self->_error( "Expected a map structure from string or file." ); return; } for my $key (keys %$spec) { next unless($spec->{$key}->{mandatory}); next if(defined $data->{$key}); push @{$self->{stack}}, $key; $self->_error( "Missing mandatory field, '$key'" ); pop @{$self->{stack}}; } for my $key (keys %$data) { push @{$self->{stack}}, $key; if($spec->{$key}) { if($spec->{$key}{value}) { $spec->{$key}{value}->($self,$key,$data->{$key}); } elsif($spec->{$key}{'map'}) { $self->check_map($spec->{$key}{'map'},$data->{$key}); } elsif($spec->{$key}{'list'}) { $self->check_list($spec->{$key}{'list'},$data->{$key}); } else { $self->_error( "$spec_error for '$key'" ); } } elsif ($spec->{':key'}) { $spec->{':key'}{name}->($self,$key,$key); if($spec->{':key'}{value}) { $spec->{':key'}{value}->($self,$key,$data->{$key}); } elsif($spec->{':key'}{'map'}) { $self->check_map($spec->{':key'}{'map'},$data->{$key}); } elsif($spec->{':key'}{'list'}) { $self->check_list($spec->{':key'}{'list'},$data->{$key}); } else { $self->_error( "$spec_error for ':key'" ); } } else { $self->_error( "Unknown key, '$key', found in map structure" ); } pop @{$self->{stack}}; } } sub check_list { my ($self,$spec,$data) = @_; if(ref($data) ne 'ARRAY') { $self->_error( "Expected a list structure" ); return; } if(defined $spec->{mandatory}) { if(!defined $data->[0]) { $self->_error( "Missing entries from mandatory list" ); } } for my $value (@$data) { push @{$self->{stack}}, $value || ""; if(defined $spec->{value}) { $spec->{value}->($self,'list',$value); } elsif(defined $spec->{'map'}) { $self->check_map($spec->{'map'},$value); } elsif(defined $spec->{'list'}) { $self->check_list($spec->{'list'},$value); } elsif ($spec->{':key'}) { $self->check_map($spec,$value); } else { $self->_error( "$spec_error associated with '$self->{stack}[-2]'" ); } pop @{$self->{stack}}; } } #pod =head2 Validator Methods #pod #pod =over #pod #pod =item * #pod #pod header($self,$key,$value) #pod #pod Validates that the header is valid. #pod #pod Note: No longer used as we now read the data structure, not the file. #pod #pod =item * #pod #pod url($self,$key,$value) #pod #pod Validates that a given value is in an acceptable URL format #pod #pod =item * #pod #pod urlspec($self,$key,$value) #pod #pod Validates that the URL to a META specification is a known one. #pod #pod =item * #pod #pod string_or_undef($self,$key,$value) #pod #pod Validates that the value is either a string or an undef value. Bit of a #pod catchall function for parts of the data structure that are completely user #pod defined. #pod #pod =item * #pod #pod string($self,$key,$value) #pod #pod Validates that a string exists for the given key. #pod #pod =item * #pod #pod file($self,$key,$value) #pod #pod Validate that a file is passed for the given key. This may be made more #pod thorough in the future. For now it acts like \&string. #pod #pod =item * #pod #pod exversion($self,$key,$value) #pod #pod Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'. #pod #pod =item * #pod #pod version($self,$key,$value) #pod #pod Validates a single version string. Versions of the type '5.8.8' and '0.00_00' #pod are both valid. A leading 'v' like 'v1.2.3' is also valid. #pod #pod =item * #pod #pod boolean($self,$key,$value) #pod #pod Validates for a boolean value. Currently these values are '1', '0', 'true', #pod 'false', however the latter 2 may be removed. #pod #pod =item * #pod #pod license($self,$key,$value) #pod #pod Validates that a value is given for the license. Returns 1 if an known license #pod type, or 2 if a value is given but the license type is not a recommended one. #pod #pod =item * #pod #pod custom_1($self,$key,$value) #pod #pod Validates that the given key is in CamelCase, to indicate a user defined #pod keyword and only has characters in the class [-_a-zA-Z]. In version 1.X #pod of the spec, this was only explicitly stated for 'resources'. #pod #pod =item * #pod #pod custom_2($self,$key,$value) #pod #pod Validates that the given key begins with 'x_' or 'X_', to indicate a user #pod defined keyword and only has characters in the class [-_a-zA-Z] #pod #pod =item * #pod #pod identifier($self,$key,$value) #pod #pod Validates that key is in an acceptable format for the META specification, #pod for an identifier, i.e. any that matches the regular expression #pod qr/[a-z][a-z_]/i. #pod #pod =item * #pod #pod module($self,$key,$value) #pod #pod Validates that a given key is in an acceptable module name format, e.g. #pod 'Test::CPAN::Meta::Version'. #pod #pod =back #pod #pod =end :internals #pod #pod =cut sub header { my ($self,$key,$value) = @_; if(defined $value) { return 1 if($value && $value =~ /^--- #YAML:1.0/); } $self->_error( "file does not have a valid YAML header." ); return 0; } sub release_status { my ($self,$key,$value) = @_; if(defined $value) { my $version = $self->{data}{version} || ''; if ( $version =~ /_/ ) { return 1 if ( $value =~ /\A(?:testing|unstable)\z/ ); $self->_error( "'$value' for '$key' is invalid for version '$version'" ); } else { return 1 if ( $value =~ /\A(?:stable|testing|unstable)\z/ ); $self->_error( "'$value' for '$key' is invalid" ); } } else { $self->_error( "'$key' is not defined" ); } return 0; } # _uri_split taken from URI::Split by Gisle Aas, Copyright 2003 sub _uri_split { return $_[0] =~ m,(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?,; } sub url { my ($self,$key,$value) = @_; if(defined $value) { my ($scheme, $auth, $path, $query, $frag) = _uri_split($value); unless ( defined $scheme && length $scheme ) { $self->_error( "'$value' for '$key' does not have a URL scheme" ); return 0; } unless ( defined $auth && length $auth ) { $self->_error( "'$value' for '$key' does not have a URL authority" ); return 0; } return 1; } $value ||= ''; $self->_error( "'$value' for '$key' is not a valid URL." ); return 0; } sub urlspec { my ($self,$key,$value) = @_; if(defined $value) { return 1 if($value && $known_specs{$self->{spec}} eq $value); if($value && $known_urls{$value}) { $self->_error( 'META specification URL does not match version' ); return 0; } } $self->_error( 'Unknown META specification' ); return 0; } sub anything { return 1 } sub string { my ($self,$key,$value) = @_; if(defined $value) { return 1 if($value || $value =~ /^0$/); } $self->_error( "value is an undefined string" ); return 0; } sub string_or_undef { my ($self,$key,$value) = @_; return 1 unless(defined $value); return 1 if($value || $value =~ /^0$/); $self->_error( "No string defined for '$key'" ); return 0; } sub file { my ($self,$key,$value) = @_; return 1 if(defined $value); $self->_error( "No file defined for '$key'" ); return 0; } sub exversion { my ($self,$key,$value) = @_; if(defined $value && ($value || $value =~ /0/)) { my $pass = 1; for(split(",",$value)) { $self->version($key,$_) or ($pass = 0); } return $pass; } $value = '' unless(defined $value); $self->_error( "'$value' for '$key' is not a valid version." ); return 0; } sub version { my ($self,$key,$value) = @_; if(defined $value) { return 0 unless($value || $value =~ /0/); return 1 if($value =~ /^\s*((<|<=|>=|>|!=|==)\s*)?v?\d+((\.\d+((_|\.)\d+)?)?)/); } else { $value = ''; } $self->_error( "'$value' for '$key' is not a valid version." ); return 0; } sub boolean { my ($self,$key,$value) = @_; if(defined $value) { return 1 if($value =~ /^(0|1|true|false)$/); } else { $value = ''; } $self->_error( "'$value' for '$key' is not a boolean value." ); return 0; } my %v1_licenses = ( 'perl' => 'http://dev.perl.org/licenses/', 'gpl' => 'http://www.opensource.org/licenses/gpl-license.php', 'apache' => 'http://apache.org/licenses/LICENSE-2.0', 'artistic' => 'http://opensource.org/licenses/artistic-license.php', 'artistic_2' => 'http://opensource.org/licenses/artistic-license-2.0.php', 'lgpl' => 'http://www.opensource.org/licenses/lgpl-license.php', 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', 'gpl' => 'http://www.opensource.org/licenses/gpl-license.php', 'mit' => 'http://opensource.org/licenses/mit-license.php', 'mozilla' => 'http://opensource.org/licenses/mozilla1.1.php', 'open_source' => undef, 'unrestricted' => undef, 'restrictive' => undef, 'unknown' => undef, ); my %v2_licenses = map { $_ => 1 } qw( agpl_3 apache_1_1 apache_2_0 artistic_1 artistic_2 bsd freebsd gfdl_1_2 gfdl_1_3 gpl_1 gpl_2 gpl_3 lgpl_2_1 lgpl_3_0 mit mozilla_1_0 mozilla_1_1 openssl perl_5 qpl_1_0 ssleay sun zlib open_source restricted unrestricted unknown ); sub license { my ($self,$key,$value) = @_; my $licenses = $self->{spec} < 2 ? \%v1_licenses : \%v2_licenses; if(defined $value) { return 1 if($value && exists $licenses->{$value}); } else { $value = ''; } $self->_error( "License '$value' is invalid" ); return 0; } sub custom_1 { my ($self,$key) = @_; if(defined $key) { # a valid user defined key should be alphabetic # and contain at least one capital case letter. return 1 if($key && $key =~ /^[_a-z]+$/i && $key =~ /[A-Z]/); } else { $key = ''; } $self->_error( "Custom resource '$key' must be in CamelCase." ); return 0; } sub custom_2 { my ($self,$key) = @_; if(defined $key) { return 1 if($key && $key =~ /^x_/i); # user defined } else { $key = ''; } $self->_error( "Custom key '$key' must begin with 'x_' or 'X_'." ); return 0; } sub identifier { my ($self,$key) = @_; if(defined $key) { return 1 if($key && $key =~ /^([a-z][_a-z]+)$/i); # spec 2.0 defined } else { $key = ''; } $self->_error( "Key '$key' is not a legal identifier." ); return 0; } sub module { my ($self,$key) = @_; if(defined $key) { return 1 if($key && $key =~ /^[A-Za-z0-9_]+(::[A-Za-z0-9_]+)*$/); } else { $key = ''; } $self->_error( "Key '$key' is not a legal module name." ); return 0; } my @valid_phases = qw/ configure build test runtime develop /; sub phase { my ($self,$key) = @_; if(defined $key) { return 1 if( length $key && grep { $key eq $_ } @valid_phases ); return 1 if $key =~ /x_/i; } else { $key = ''; } $self->_error( "Key '$key' is not a legal phase." ); return 0; } my @valid_relations = qw/ requires recommends suggests conflicts /; sub relation { my ($self,$key) = @_; if(defined $key) { return 1 if( length $key && grep { $key eq $_ } @valid_relations ); return 1 if $key =~ /x_/i; } else { $key = ''; } $self->_error( "Key '$key' is not a legal prereq relationship." ); return 0; } sub _error { my $self = shift; my $mess = shift; $mess .= ' ('.join(' -> ',@{$self->{stack}}).')' if($self->{stack}); $mess .= " [Validation: $self->{spec}]"; push @{$self->{errors}}, $mess; } 1; # ABSTRACT: validate CPAN distribution metadata structures =pod =encoding UTF-8 =head1 NAME CPAN::Meta::Validator - validate CPAN distribution metadata structures =head1 VERSION version 2.150005 =head1 SYNOPSIS my $struct = decode_json_file('META.json'); my $cmv = CPAN::Meta::Validator->new( $struct ); unless ( $cmv->is_valid ) { my $msg = "Invalid META structure. Errors found:\n"; $msg .= join( "\n", $cmv->errors ); die $msg; } =head1 DESCRIPTION This module validates a CPAN Meta structure against the version of the the specification claimed in the C field of the structure. =head1 METHODS =head2 new my $cmv = CPAN::Meta::Validator->new( $struct ) The constructor must be passed a metadata structure. =head2 is_valid if ( $cmv->is_valid ) { ... } Returns a boolean value indicating whether the metadata provided is valid. =head2 errors warn( join "\n", $cmv->errors ); Returns a list of errors seen during validation. =begin :internals =head2 Check Methods =over =item * check_map($spec,$data) Checks whether a map (or hash) part of the data structure conforms to the appropriate specification definition. =item * check_list($spec,$data) Checks whether a list (or array) part of the data structure conforms to the appropriate specification definition. =item * =back =head2 Validator Methods =over =item * header($self,$key,$value) Validates that the header is valid. Note: No longer used as we now read the data structure, not the file. =item * url($self,$key,$value) Validates that a given value is in an acceptable URL format =item * urlspec($self,$key,$value) Validates that the URL to a META specification is a known one. =item * string_or_undef($self,$key,$value) Validates that the value is either a string or an undef value. Bit of a catchall function for parts of the data structure that are completely user defined. =item * string($self,$key,$value) Validates that a string exists for the given key. =item * file($self,$key,$value) Validate that a file is passed for the given key. This may be made more thorough in the future. For now it acts like \&string. =item * exversion($self,$key,$value) Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'. =item * version($self,$key,$value) Validates a single version string. Versions of the type '5.8.8' and '0.00_00' are both valid. A leading 'v' like 'v1.2.3' is also valid. =item * boolean($self,$key,$value) Validates for a boolean value. Currently these values are '1', '0', 'true', 'false', however the latter 2 may be removed. =item * license($self,$key,$value) Validates that a value is given for the license. Returns 1 if an known license type, or 2 if a value is given but the license type is not a recommended one. =item * custom_1($self,$key,$value) Validates that the given key is in CamelCase, to indicate a user defined keyword and only has characters in the class [-_a-zA-Z]. In version 1.X of the spec, this was only explicitly stated for 'resources'. =item * custom_2($self,$key,$value) Validates that the given key begins with 'x_' or 'X_', to indicate a user defined keyword and only has characters in the class [-_a-zA-Z] =item * identifier($self,$key,$value) Validates that key is in an acceptable format for the META specification, for an identifier, i.e. any that matches the regular expression qr/[a-z][a-z_]/i. =item * module($self,$key,$value) Validates that a given key is in an acceptable module name format, e.g. 'Test::CPAN::Meta::Version'. =back =end :internals =for Pod::Coverage anything boolean check_list custom_1 custom_2 exversion file identifier license module phase relation release_status string string_or_undef url urlspec version header check_map =head1 BUGS Please report any bugs or feature using the CPAN Request Tracker. Bugs can be submitted through the web interface at L When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. =head1 AUTHORS =over 4 =item * David Golden =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by David Golden and Ricardo Signes. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut __END__ # vim: ts=2 sts=2 sw=2 et : CPAN-Meta-2.150005/lib/CPAN/Meta/History/Meta_1_0.pod000644 000765 000024 00000014521 12535707053 021466 0ustar00davidstaff000000 000000 =for :stopwords DOAP RDF =head1 NAME CPAN::Meta::History::Meta_1_0 - Version 1.0 metadata specification for META.yml =head1 PREFACE This is a historical copy of the version 1.0 specification for F files, copyright by Ken Williams and licensed under the same terms as Perl itself. Modifications from the original: =over =item * Conversion from the original HTML to POD format =item * Include list of valid licenses from L 0.17 rather than linking to the module. =back =head1 DESCRIPTION This document describes version 1.0 of the F specification. The META.yml file describes important properties of contributed Perl distributions such as the ones found on L. It is typically created by tools like L and L. The fields in the F file are meant to be helpful to people maintaining module collections (like CPAN), for people writing installation tools (like L or L), or just people who want to know some stuff about a distribution before downloading it and starting to install it. =head1 Format F files are written in the L format. The reasons we chose YAML instead of, say, XML or Data::Dumper are discussed in L on the MakeMaker mailing list. The first line of a F file should be a valid L like C<"--- #YAML:1.0"> =head1 Fields The rest of the META.yml file is one big YAML L, whose keys are described here. =over 4 =item name Example: C The name of the distribution. Often created by taking the "main module" in the distribution and changing "::" to "-". Sometimes it's completely different, however, as in the case of the L distribution. =item version Example: C<0.16> The version of the distribution to which the META.yml file refers. =item license Example: C The license under which this distribution may be used and redistributed. Must be one of the following licenses: =over 4 =item perl The distribution may be copied and redistributed under the same terms as perl itself (this is by far the most common licensing option for modules on CPAN). This is a dual license, in which the user may choose between either the GPL or the Artistic license. =item gpl The distribution is distributed under the terms of the Gnu General Public License (L). =item lgpl The distribution is distributed under the terms of the Gnu Lesser General Public License (L). =item artistic The distribution is licensed under the Artistic License, as specified by the Artistic file in the standard perl distribution. =item bsd The distribution is licensed under the BSD License (L). =item open_source The distribution is licensed under some other Open Source Initiative-approved license listed at L. =item unrestricted The distribution is licensed under a license that is B approved by L but that allows distribution without restrictions. =item restrictive The distribution may not be redistributed without special permission from the author and/or copyright holder. =back =item distribution_type Example: C What kind of stuff is contained in this distribution. Most things on CPAN are Cs (which can also mean a collection of modules), but some things are C