diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-04-29 03:17:05 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2015-04-29 03:17:05 +0000 |
commit | 2ca9db53e3e8164ecf0c95bf93fa289019e1b92c (patch) | |
tree | 5cc19083935ae762133417625e80a5329e36d8ee | |
download | Dist-Metadata-tarball-2ca9db53e3e8164ecf0c95bf93fa289019e1b92c.tar.gz |
Dist-Metadata-0.926HEADDist-Metadata-0.926master
88 files changed, 6436 insertions, 0 deletions
@@ -0,0 +1,124 @@ +Revision history for Dist-Metadata + +0.926 2015-04-29T03:16:55Z + + - Always add local, perl5, and fatlib to "no_index.directory" + for consistency with PAUSE. Closes gh-12 and gh-14. + Thanks to Sawyer X for the pull-req and the prodding. + +0.925 2013-02-08T02:40:09Z + + - Specify 1.03 as minimum required version of Digest + to ensure that it tries Digest::SHA. Closes gh-6. + +0.924 2012-11-10T17:38:33Z + + - Add 'module_info' method for getting additional data (like checksums) + with the provided module hashref. Thanks to Jeffrey Ryan Thalhammer + for the suggestion. + - Add 'file_checksum' method to the Dist::Metadata::Dist base class. + +0.923 2012-06-19T03:13:55Z + + - By default, when determining packages, filter out packages + that don't match the file name (ones that can't be loaded via use/require). + This mimics the behavior of PAUSE. + If you want the old behavior of including "inner" packages in the meta + "provides" set "include_inner_packages" to true in the constructor. + Thanks to Jeffrey Ryan Thalhammer for finding and fixing this + (and including tests)! + +0.922 2011-10-19T22:30:53Z + + - Let CPAN::Meta set release_status instead of defaulting to 'stable'. + Fixes an issue with dev/alpha versions. + Thanks to Jeffrey Ryan Thalhammer (thaljef) for reporting and fixing. + +0.921 2011-09-09T23:10:21Z + + - Fix 'no_index' checking with non-unix paths. + +0.920 2011-08-18T04:11:45Z + + [API Change] + - Dist::extract_into() and Dist::physical_directory() now return just $dir + in scalar context (and continue to return ($dir, @files) in list context) + + [Enhancements] + - Support zip archives (in addition to tar files). + (Thanks to thaljef for reporting.) + + [Fixes] + - Always include inc/, t/, and xt/ in meta/no_index. + (Thanks to thaljef for reporting.) + - Make return value of Dir::physical_directory() consistent with + other subclasses. + +0.915 2011-08-16T18:52:01Z + + - Remove warning for no packages found (thaljef). + +0.914 2011-08-02T16:01:46Z + + - Use Path::Class::Dir's mkpath for simplicity/compatibility. + Closes RT 69961. Thanks to MELEZHIK for reporting. + +0.913 2011-07-19T21:15:24Z + + - Pass paths to CPAN::DistnameInfo in Unix format. + Thanks to jeroenl for figuring out that test failure on Win32. + Closes RT 69585. + + - Remove unnecessary build file from release tarball + +0.912 2011-07-14T23:38:40Z + + - Use CPAN::DistnameInfo to parse name/version from file name + +0.911 2011-07-04T22:10:24Z + + - Fix test to use non-os specific paths in regexp + +0.910 2011-07-03T00:06:00Z + + [Fixes] + - Work around weird, possible perl bug (described at http://bit.ly/mhaQ4x) + that made Struct->file_content return undef for IO-like objects + + [Prereqs] + - use Path::Class instead of File::Spec + - ensure File::Spec::Native is available + + [Documentation] + - Clarify details of module's purpose in Pod Description + + [Testing] + - Add dist format tests + - Report version of JSON::PP (if any) installed to help debug + troublesome smoke testing environments + +0.904 2011-06-24T06:09:23Z + + - Fix path mismatch for "provides" when using Module::Metadata on Win32 + - Add more TODO ideas + +0.903 2011-06-23T05:59:41Z + + - Load File::Spec (and subclasses) consistently + +0.902 2011-06-23T05:51:42Z + + [Fixes] + - Change determine_packages to always return paths in unix format + (as required by CPAN::Meta::Spec) + - Fix regexp path bugs on windows + + [Enhancements] + - Include 'xt/' in the default no_index:directory list + + [Documentation] + - Add items to pod TODO list + +0.901 2011-06-22T01:22:07Z + + - Initial release @@ -0,0 +1,379 @@ +This software is copyright (c) 2011 by Randy Stauner. + +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) 2011 by Randy Stauner. + +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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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. + + <signature of Ty Coon>, 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) 2011 by Randy Stauner. + +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 + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..4fef4f1 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,89 @@ +# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.035. +Changes +LICENSE +MANIFEST +MANIFEST.SKIP +META.json +META.yml +Makefile.PL +README +corpus/Dist-Metadata-Test-LikePause-0.1.tar.gz +corpus/Dist-Metadata-Test-LikePause-0.1.zip +corpus/Dist-Metadata-Test-LikePause-0.1/README +corpus/Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm +corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gz +corpus/Dist-Metadata-Test-MetaFile-2.2.zip +corpus/Dist-Metadata-Test-MetaFile-2.2/META.json +corpus/Dist-Metadata-Test-MetaFile-2.2/META.yml +corpus/Dist-Metadata-Test-MetaFile-2.2/README +corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm +corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gz +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/README +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm +corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm +corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gz +corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip +corpus/Dist-Metadata-Test-NoMetaFile-0.1/README +corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm +corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm +corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gz +corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip +corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README +corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm +corpus/Dist-Metadata-Test-SubDir-1.5.tar.gz +corpus/Dist-Metadata-Test-SubDir-1.5.zip +corpus/make_dists +corpus/noroot.tar.gz +corpus/noroot.zip +corpus/noroot/README +corpus/noroot/lib/Dist/Metadata/Test/NoRoot.pm +corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm +corpus/structs.pl +corpus/subdir/Dist-Metadata-Test-SubDir-1.5/README +corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm +corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm +dist.ini +lib/Dist/Metadata.pm +lib/Dist/Metadata/Archive.pm +lib/Dist/Metadata/Dir.pm +lib/Dist/Metadata/Dist.pm +lib/Dist/Metadata/Struct.pm +lib/Dist/Metadata/Tar.pm +lib/Dist/Metadata/Zip.pm +t/00-compile.t +t/00-report-prereqs.dd +t/00-report-prereqs.t +t/archive.t +t/determine.t +t/dir.t +t/dists.t +t/file_spec.t +t/load_meta.t +t/module_info.t +t/no_index.t +t/package_versions.t +t/struct.t +t/tar.t +t/zip.t +xt/author/critic.t +xt/author/eol.t +xt/author/no-tabs.t +xt/author/pod-spell.t +xt/release/cpan-changes.t +xt/release/dist-manifest.t +xt/release/distmeta.t +xt/release/kwalitee.t +xt/release/meta-json.t +xt/release/minimum-version.t +xt/release/mojibake.t +xt/release/pod-coverage.t +xt/release/pod-linkcheck.t +xt/release/pod-syntax.t +xt/release/synopsis.t +xt/release/test-version.t +xt/release/unused-vars.t diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP new file mode 100644 index 0000000..856b389 --- /dev/null +++ b/MANIFEST.SKIP @@ -0,0 +1,10 @@ + +\B\.git\b +\B\.gitignore$ +^[\._]build +^blib/ +^(Build|Makefile)$ +\bpm_to_blib$ +^MYMETA\. + + diff --git a/META.json b/META.json new file mode 100644 index 0000000..24600cd --- /dev/null +++ b/META.json @@ -0,0 +1,858 @@ +{ + "abstract" : "Information about a perl module distribution", + "author" : [ + "Randy Stauner <rwstauner@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "Dist::Zilla version 5.035, CPAN::Meta::Converter version 2.150001", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "Dist-Metadata", + "no_index" : { + "directory" : [ + "t", + "xt", + "inc", + "local", + "perl5", + "fatlib", + "corpus", + "examples", + "share" + ], + "namespace" : [ + "Local", + "t::lib" + ], + "package" : [ + "DB" + ] + }, + "prereqs" : { + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0", + "perl" : "5.006" + } + }, + "develop" : { + "requires" : { + "Archive::Any::Create" : "0.03", + "Pod::Coverage::TrustPod" : "0", + "Test::CPAN::Changes" : "0.19", + "Test::CPAN::Meta" : "0", + "Test::CPAN::Meta::JSON" : "0.16", + "Test::EOL" : "0", + "Test::Kwalitee" : "1.21", + "Test::More" : "0.88", + "Test::NoTabs" : "0", + "Test::Pod" : "1.41", + "Test::Pod::Coverage" : "1.08", + "Test::Spelling" : "0.12", + "Test::Synopsis" : "0", + "Test::Version" : "1" + } + }, + "runtime" : { + "requires" : { + "Archive::Tar" : "1", + "Archive::Zip" : "1.30", + "CPAN::DistnameInfo" : "0.12", + "CPAN::Meta" : "2.1", + "Carp" : "0", + "Digest" : "1.03", + "Digest::MD5" : "2", + "Digest::SHA" : "5", + "File::Basename" : "0", + "File::Find" : "0", + "File::Spec::Native" : "1.002", + "File::Temp" : "0.19", + "List::Util" : "0", + "Module::Metadata" : "0", + "Path::Class" : "0.24", + "Try::Tiny" : "0.09", + "parent" : "0", + "perl" : "5.006", + "strict" : "0", + "warnings" : "0" + } + }, + "test" : { + "recommends" : { + "CPAN::Meta" : "2.120900" + }, + "requires" : { + "ExtUtils::MakeMaker" : "0", + "File::Spec" : "0", + "File::Temp" : "0.19", + "IO::Handle" : "0", + "IPC::Open3" : "0", + "Test::Fatal" : "0", + "Test::MockObject" : "1.09", + "Test::More" : "0.96", + "perl" : "5.006" + } + } + }, + "provides" : { + "Dist::Metadata" : { + "file" : "lib/Dist/Metadata.pm", + "version" : "0.926" + }, + "Dist::Metadata::Archive" : { + "file" : "lib/Dist/Metadata/Archive.pm", + "version" : "0.926" + }, + "Dist::Metadata::Dir" : { + "file" : "lib/Dist/Metadata/Dir.pm", + "version" : "0.926" + }, + "Dist::Metadata::Dist" : { + "file" : "lib/Dist/Metadata/Dist.pm", + "version" : "0.926" + }, + "Dist::Metadata::Struct" : { + "file" : "lib/Dist/Metadata/Struct.pm", + "version" : "0.926" + }, + "Dist::Metadata::Tar" : { + "file" : "lib/Dist/Metadata/Tar.pm", + "version" : "0.926" + }, + "Dist::Metadata::Zip" : { + "file" : "lib/Dist/Metadata/Zip.pm", + "version" : "0.926" + } + }, + "release_status" : "stable", + "resources" : { + "bugtracker" : { + "mailto" : "bug-Dist-Metadata@rt.cpan.org", + "web" : "https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Metadata" + }, + "homepage" : "https://github.com/rwstauner/Dist-Metadata", + "repository" : { + "type" : "git", + "url" : "https://github.com/rwstauner/Dist-Metadata.git", + "web" : "https://github.com/rwstauner/Dist-Metadata" + } + }, + "version" : "0.926", + "x_Dist_Zilla" : { + "perl" : { + "version" : "5.020000" + }, + "plugins" : [ + { + "class" : "Dist::Zilla::Plugin::Git::NextVersion", + "config" : { + "Dist::Zilla::Plugin::Git::NextVersion" : { + "first_version" : "0.001", + "version_by_branch" : "0", + "version_regexp" : "(?^:^v(.+)$)" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Author::RWSTAUNER/Git::NextVersion", + "version" : "2.033" + }, + { + "class" : "Dist::Zilla::Plugin::GenerateFile", + "name" : "@Author::RWSTAUNER/GenerateManifestSkip", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::GatherDir", + "config" : { + "Dist::Zilla::Plugin::GatherDir" : { + "exclude_filename" : [ + "LICENSE" + ], + "exclude_match" : [], + "follow_symlinks" : "0", + "include_dotfiles" : "0", + "prefix" : "", + "prune_directory" : [], + "root" : "." + } + }, + "name" : "@Author::RWSTAUNER/GatherDir", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::PruneCruft", + "name" : "@Author::RWSTAUNER/PruneCruft", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::ManifestSkip", + "name" : "@Author::RWSTAUNER/ManifestSkip", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::PruneFiles", + "name" : "@Author::RWSTAUNER/PruneDevelCoverDatabase", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::PruneFiles", + "name" : "@Author::RWSTAUNER/PruneCodeStatCollection", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::PruneFiles", + "name" : "@Author::RWSTAUNER/PruneTags", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::PkgVersion", + "name" : "@Author::RWSTAUNER/PkgVersion", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Authority", + "name" : "@Author::RWSTAUNER/Authority", + "version" : "1.009" + }, + { + "class" : "Dist::Zilla::Plugin::NextRelease", + "name" : "@Author::RWSTAUNER/NextRelease", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Describe", + "name" : "@Author::RWSTAUNER/Git::Describe", + "version" : "0.005" + }, + { + "class" : "Dist::Zilla::Plugin::Prepender", + "name" : "@Author::RWSTAUNER/Prepender", + "version" : "2.001" + }, + { + "class" : "Dist::Zilla::Plugin::PodWeaver", + "config" : { + "Dist::Zilla::Plugin::PodWeaver" : { + "config_plugins" : [ + "@Author::RWSTAUNER" + ], + "finder" : [ + ":InstallModules", + ":ExecFiles" + ], + "plugins" : [ + { + "class" : "Pod::Weaver::Plugin::SingleEncoding", + "name" : "@Author::RWSTAUNER/SingleEncoding", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Plugin::WikiDoc", + "name" : "@Author::RWSTAUNER/WikiDoc", + "version" : "0.093004" + }, + { + "class" : "Pod::Weaver::Plugin::EnsurePod5", + "name" : "@CorePrep/EnsurePod5", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Plugin::H1Nester", + "name" : "@CorePrep/H1Nester", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Name", + "name" : "@Author::RWSTAUNER/Name", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Version", + "name" : "@Author::RWSTAUNER/Version", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Region", + "name" : "@Author::RWSTAUNER/Prelude", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "@Author::RWSTAUNER/Synopsis", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "@Author::RWSTAUNER/Description", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "@Author::RWSTAUNER/Overview", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "@Author::RWSTAUNER/Usage", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "@Author::RWSTAUNER/Class Methods", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "@Author::RWSTAUNER/Attributes", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "@Author::RWSTAUNER/Methods", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "@Author::RWSTAUNER/Functions", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Leftovers", + "name" : "@Author::RWSTAUNER/Leftovers", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Region", + "name" : "@Author::RWSTAUNER/Postlude", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Support", + "name" : "@Author::RWSTAUNER/Support", + "version" : "1.007" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "@Author::RWSTAUNER/Acknowledgements", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Authors", + "name" : "@Author::RWSTAUNER/Authors", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Section::Contributors", + "name" : "@Author::RWSTAUNER/Contributors", + "version" : "0.009" + }, + { + "class" : "Pod::Weaver::Section::Legal", + "name" : "@Author::RWSTAUNER/Legal", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Plugin::Transformer", + "name" : "@Author::RWSTAUNER/List", + "version" : "4.011" + }, + { + "class" : "Pod::Weaver::Plugin::StopWords", + "name" : "@Author::RWSTAUNER/StopWords", + "version" : "1.010" + } + ] + } + }, + "name" : "@Author::RWSTAUNER/PodWeaver", + "version" : "4.006" + }, + { + "class" : "Dist::Zilla::Plugin::License", + "name" : "@Author::RWSTAUNER/License", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Readme", + "name" : "@Author::RWSTAUNER/Readme", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", + "name" : "@Author::RWSTAUNER/ReadmeAnyFromPod", + "version" : "0.150250" + }, + { + "class" : "Dist::Zilla::Plugin::CopyFilesFromRelease", + "config" : { + "Dist::Zilla::Plugin::CopyFilesFromRelease" : { + "filename" : [ + "LICENSE" + ], + "match" : [] + } + }, + "name" : "@Author::RWSTAUNER/CopyFilesFromRelease", + "version" : "0.005" + }, + { + "class" : "Dist::Zilla::Plugin::AutoMetaResources", + "name" : "@Author::RWSTAUNER/AutoMetaResources", + "version" : "1.20" + }, + { + "class" : "Dist::Zilla::Plugin::GithubMeta", + "name" : "@Author::RWSTAUNER/GithubMeta", + "version" : "0.48" + }, + { + "class" : "Dist::Zilla::Plugin::ContributorsFromGit", + "name" : "@Author::RWSTAUNER/ContributorsFromGit", + "version" : "0.013" + }, + { + "class" : "Dist::Zilla::Plugin::AutoPrereqs", + "name" : "@Author::RWSTAUNER/AutoPrereqs", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::MetaNoIndex", + "name" : "@Author::RWSTAUNER/MetaNoIndex", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::MetaProvides::Package", + "config" : { + "Dist::Zilla::Plugin::MetaProvides::Package" : { + "finder_objects" : [ + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "@Author::RWSTAUNER/MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "5.035" + } + ] + }, + "Dist::Zilla::Role::MetaProvider::Provider" : { + "inherit_missing" : "1", + "inherit_version" : "1", + "meta_noindex" : "1" + } + }, + "name" : "@Author::RWSTAUNER/MetaProvides::Package", + "version" : "2.003001" + }, + { + "class" : "Dist::Zilla::Plugin::MinimumPerl", + "name" : "@Author::RWSTAUNER/MinimumPerl", + "version" : "1.006" + }, + { + "class" : "Dist::Zilla::Plugin::MetaConfig", + "name" : "@Author::RWSTAUNER/MetaConfig", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::MetaYAML", + "name" : "@Author::RWSTAUNER/MetaYAML", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::MetaJSON", + "name" : "@Author::RWSTAUNER/MetaJSON", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::ExecDir", + "name" : "@Author::RWSTAUNER/ExecDir", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::ShareDir", + "name" : "@Author::RWSTAUNER/ShareDir", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::MakeMaker", + "config" : { + "Dist::Zilla::Role::TestRunner" : { + "default_jobs" : 1 + } + }, + "name" : "@Author::RWSTAUNER/MakeMaker", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Test::PodSpelling", + "name" : "@Author::RWSTAUNER/Test::PodSpelling", + "version" : "2.006008" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Compile", + "config" : { + "Dist::Zilla::Plugin::Test::Compile" : { + "bail_out_on_fail" : "0", + "fail_on_warning" : "author", + "fake_home" : "1", + "filename" : "t/00-compile.t", + "module_finder" : [ + ":InstallModules" + ], + "needs_display" : "0", + "phase" : "test", + "script_finder" : [ + ":ExecFiles" + ], + "skips" : [] + } + }, + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Compile", + "version" : "2.052" + }, + { + "class" : "Dist::Zilla::Plugin::Test::CPAN::Meta::JSON", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::CPAN::Meta::JSON", + "version" : "0.004" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Perl::Critic", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Perl::Critic", + "version" : "3.000" + }, + { + "class" : "Dist::Zilla::Plugin::Test::EOL", + "config" : { + "Dist::Zilla::Plugin::Test::EOL" : { + "filename" : "xt/author/eol.t", + "finder" : [ + ":InstallModules", + ":ExecFiles", + ":TestFiles" + ], + "trailing_whitespace" : "1" + } + }, + "name" : "@Author::RWSTAUNER/@TestingMania/Test::EOL", + "version" : "0.18" + }, + { + "class" : "Dist::Zilla::Plugin::Test::MinimumVersion", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::MinimumVersion", + "version" : "2.000006" + }, + { + "class" : "Dist::Zilla::Plugin::MojibakeTests", + "name" : "@Author::RWSTAUNER/@TestingMania/MojibakeTests", + "version" : "0.7" + }, + { + "class" : "Dist::Zilla::Plugin::Test::DistManifest", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::DistManifest", + "version" : "2.000005" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Pod::LinkCheck", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Pod::LinkCheck", + "version" : "1.001" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Version", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Version", + "version" : "0.003001" + }, + { + "class" : "Dist::Zilla::Plugin::Test::NoTabs", + "config" : { + "Dist::Zilla::Plugin::Test::NoTabs" : { + "filename" : "xt/author/no-tabs.t", + "finder" : [ + ":InstallModules", + ":ExecFiles", + ":TestFiles" + ] + } + }, + "name" : "@Author::RWSTAUNER/@TestingMania/Test::NoTabs", + "version" : "0.14" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Synopsis", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Synopsis", + "version" : "2.000006" + }, + { + "class" : "Dist::Zilla::Plugin::Test::UnusedVars", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::UnusedVars", + "version" : "2.000007" + }, + { + "class" : "Dist::Zilla::Plugin::PodCoverageTests", + "name" : "@Author::RWSTAUNER/@TestingMania/PodCoverageTests", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", + "name" : "@Author::RWSTAUNER/@TestingMania/Test::CPAN::Changes", + "version" : "0.009" + }, + { + "class" : "Dist::Zilla::Plugin::PodSyntaxTests", + "name" : "@Author::RWSTAUNER/@TestingMania/PodSyntaxTests", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Test::Kwalitee", + "config" : { + "Dist::Zilla::Plugin::Test::Kwalitee" : { + "filename" : "xt/release/kwalitee.t", + "skiptest" : [] + } + }, + "name" : "@Author::RWSTAUNER/@TestingMania/Test::Kwalitee", + "version" : "2.11" + }, + { + "class" : "Dist::Zilla::Plugin::MetaTests", + "name" : "@Author::RWSTAUNER/@TestingMania/MetaTests", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Manifest", + "name" : "@Author::RWSTAUNER/Manifest", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::CheckExtraTests", + "name" : "@Author::RWSTAUNER/CheckExtraTests", + "version" : "0.026" + }, + { + "class" : "Dist::Zilla::Plugin::CheckChangesHasContent", + "name" : "@Author::RWSTAUNER/CheckChangesHasContent", + "version" : "0.008" + }, + { + "class" : "Dist::Zilla::Plugin::CheckMetaResources", + "name" : "@Author::RWSTAUNER/CheckMetaResources", + "version" : "0.001" + }, + { + "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", + "name" : "@Author::RWSTAUNER/CheckPrereqsIndexed", + "version" : "0.015" + }, + { + "class" : "Dist::Zilla::Plugin::TestRelease", + "name" : "@Author::RWSTAUNER/TestRelease", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Check", + "config" : { + "Dist::Zilla::Plugin::Git::Check" : { + "untracked_files" : "die" + }, + "Dist::Zilla::Role::Git::DirtyFiles" : { + "allow_dirty" : [ + "Changes", + "README.mkdn", + "README.pod", + "LICENSE" + ], + "allow_dirty_match" : [], + "changelog" : "Changes" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Author::RWSTAUNER/@Git/Check", + "version" : "2.033" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Commit", + "config" : { + "Dist::Zilla::Plugin::Git::Commit" : { + "add_files_in" : [], + "commit_msg" : "v%v%t%n%n%c", + "time_zone" : "local" + }, + "Dist::Zilla::Role::Git::DirtyFiles" : { + "allow_dirty" : [ + "Changes", + "README.mkdn", + "README.pod", + "LICENSE" + ], + "allow_dirty_match" : [], + "changelog" : "Changes" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Author::RWSTAUNER/@Git/Commit", + "version" : "2.033" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Tag", + "config" : { + "Dist::Zilla::Plugin::Git::Tag" : { + "branch" : null, + "signed" : 0, + "tag" : "v0.926", + "tag_format" : "v%v", + "tag_message" : "v%v", + "time_zone" : "local" + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Author::RWSTAUNER/@Git/Tag", + "version" : "2.033" + }, + { + "class" : "Dist::Zilla::Plugin::Git::Push", + "config" : { + "Dist::Zilla::Plugin::Git::Push" : { + "push_to" : [ + "origin" + ], + "remotes_must_exist" : 1 + }, + "Dist::Zilla::Role::Git::Repo" : { + "repo_root" : "." + } + }, + "name" : "@Author::RWSTAUNER/@Git/Push", + "version" : "2.033" + }, + { + "class" : "Dist::Zilla::Plugin::ConfirmRelease", + "name" : "@Author::RWSTAUNER/ConfirmRelease", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::UploadToCPAN", + "name" : "@Author::RWSTAUNER/UploadToCPAN", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::InstallRelease", + "name" : "@Author::RWSTAUNER/InstallRelease", + "version" : "0.008" + }, + { + "class" : "Dist::Zilla::Plugin::Encoding", + "name" : "BinaryFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Prereqs", + "config" : { + "Dist::Zilla::Plugin::Prereqs" : { + "phase" : "runtime", + "type" : "requires" + } + }, + "name" : "Prereqs", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Prereqs", + "config" : { + "Dist::Zilla::Plugin::Prereqs" : { + "phase" : "develop", + "type" : "requires" + } + }, + "name" : "DevelopRequires", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::Run::BeforeBuild", + "config" : { + "Dist::Zilla::Plugin::Run::Role::Runner" : { + "fatal_errors" : 1, + "run" : [ + "%x corpus/make_dists" + ] + } + }, + "name" : "Run::BeforeBuild", + "version" : "0.035" + }, + { + "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", + "name" : "Test::ReportPrereqs", + "version" : "0.021" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":InstallModules", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":IncModules", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":TestFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":ExecFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":ShareFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":MainModule", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":AllFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : ":NoFiles", + "version" : "5.035" + }, + { + "class" : "Dist::Zilla::Plugin::FinderCode", + "name" : "@Author::RWSTAUNER/MetaProvides::Package/AUTOVIV/:InstallModulesPM", + "version" : "5.035" + } + ], + "zilla" : { + "class" : "Dist::Zilla::Dist::Builder", + "config" : { + "is_trial" : "" + }, + "version" : "5.035" + } + }, + "x_authority" : "cpan:RWSTAUNER", + "x_contributors" : [ + "David Steinbrunner <dsteinbrunner@pobox.com>", + "Jeffrey Ryan Thalhammer <thaljef@cpan.org>", + "Sawyer X <xsawyerx@cpan.org>" + ] +} + diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..ad7bc0a --- /dev/null +++ b/META.yml @@ -0,0 +1,636 @@ +--- +abstract: 'Information about a perl module distribution' +author: + - 'Randy Stauner <rwstauner@cpan.org>' +build_requires: + ExtUtils::MakeMaker: '0' + File::Spec: '0' + File::Temp: '0.19' + IO::Handle: '0' + IPC::Open3: '0' + Test::Fatal: '0' + Test::MockObject: '1.09' + Test::More: '0.96' + perl: '5.006' +configure_requires: + ExtUtils::MakeMaker: '0' + perl: '5.006' +dynamic_config: 0 +generated_by: 'Dist::Zilla version 5.035, 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: Dist-Metadata +no_index: + directory: + - t + - xt + - inc + - local + - perl5 + - fatlib + - corpus + - examples + - share + namespace: + - Local + - t::lib + package: + - DB +provides: + Dist::Metadata: + file: lib/Dist/Metadata.pm + version: '0.926' + Dist::Metadata::Archive: + file: lib/Dist/Metadata/Archive.pm + version: '0.926' + Dist::Metadata::Dir: + file: lib/Dist/Metadata/Dir.pm + version: '0.926' + Dist::Metadata::Dist: + file: lib/Dist/Metadata/Dist.pm + version: '0.926' + Dist::Metadata::Struct: + file: lib/Dist/Metadata/Struct.pm + version: '0.926' + Dist::Metadata::Tar: + file: lib/Dist/Metadata/Tar.pm + version: '0.926' + Dist::Metadata::Zip: + file: lib/Dist/Metadata/Zip.pm + version: '0.926' +requires: + Archive::Tar: '1' + Archive::Zip: '1.30' + CPAN::DistnameInfo: '0.12' + CPAN::Meta: '2.1' + Carp: '0' + Digest: '1.03' + Digest::MD5: '2' + Digest::SHA: '5' + File::Basename: '0' + File::Find: '0' + File::Spec::Native: '1.002' + File::Temp: '0.19' + List::Util: '0' + Module::Metadata: '0' + Path::Class: '0.24' + Try::Tiny: '0.09' + parent: '0' + perl: '5.006' + strict: '0' + warnings: '0' +resources: + bugtracker: https://rt.cpan.org/Public/Dist/Display.html?Name=Dist-Metadata + homepage: https://github.com/rwstauner/Dist-Metadata + repository: https://github.com/rwstauner/Dist-Metadata.git +version: '0.926' +x_Dist_Zilla: + perl: + version: '5.020000' + plugins: + - + class: Dist::Zilla::Plugin::Git::NextVersion + config: + Dist::Zilla::Plugin::Git::NextVersion: + first_version: '0.001' + version_by_branch: '0' + version_regexp: (?^:^v(.+)$) + Dist::Zilla::Role::Git::Repo: + repo_root: . + name: '@Author::RWSTAUNER/Git::NextVersion' + version: '2.033' + - + class: Dist::Zilla::Plugin::GenerateFile + name: '@Author::RWSTAUNER/GenerateManifestSkip' + version: '5.035' + - + class: Dist::Zilla::Plugin::GatherDir + config: + Dist::Zilla::Plugin::GatherDir: + exclude_filename: + - LICENSE + exclude_match: [] + follow_symlinks: '0' + include_dotfiles: '0' + prefix: '' + prune_directory: [] + root: . + name: '@Author::RWSTAUNER/GatherDir' + version: '5.035' + - + class: Dist::Zilla::Plugin::PruneCruft + name: '@Author::RWSTAUNER/PruneCruft' + version: '5.035' + - + class: Dist::Zilla::Plugin::ManifestSkip + name: '@Author::RWSTAUNER/ManifestSkip' + version: '5.035' + - + class: Dist::Zilla::Plugin::PruneFiles + name: '@Author::RWSTAUNER/PruneDevelCoverDatabase' + version: '5.035' + - + class: Dist::Zilla::Plugin::PruneFiles + name: '@Author::RWSTAUNER/PruneCodeStatCollection' + version: '5.035' + - + class: Dist::Zilla::Plugin::PruneFiles + name: '@Author::RWSTAUNER/PruneTags' + version: '5.035' + - + class: Dist::Zilla::Plugin::PkgVersion + name: '@Author::RWSTAUNER/PkgVersion' + version: '5.035' + - + class: Dist::Zilla::Plugin::Authority + name: '@Author::RWSTAUNER/Authority' + version: '1.009' + - + class: Dist::Zilla::Plugin::NextRelease + name: '@Author::RWSTAUNER/NextRelease' + version: '5.035' + - + class: Dist::Zilla::Plugin::Git::Describe + name: '@Author::RWSTAUNER/Git::Describe' + version: '0.005' + - + class: Dist::Zilla::Plugin::Prepender + name: '@Author::RWSTAUNER/Prepender' + version: '2.001' + - + class: Dist::Zilla::Plugin::PodWeaver + config: + Dist::Zilla::Plugin::PodWeaver: + config_plugins: + - '@Author::RWSTAUNER' + finder: + - ':InstallModules' + - ':ExecFiles' + plugins: + - + class: Pod::Weaver::Plugin::SingleEncoding + name: '@Author::RWSTAUNER/SingleEncoding' + version: '4.011' + - + class: Pod::Weaver::Plugin::WikiDoc + name: '@Author::RWSTAUNER/WikiDoc' + version: '0.093004' + - + class: Pod::Weaver::Plugin::EnsurePod5 + name: '@CorePrep/EnsurePod5' + version: '4.011' + - + class: Pod::Weaver::Plugin::H1Nester + name: '@CorePrep/H1Nester' + version: '4.011' + - + class: Pod::Weaver::Section::Name + name: '@Author::RWSTAUNER/Name' + version: '4.011' + - + class: Pod::Weaver::Section::Version + name: '@Author::RWSTAUNER/Version' + version: '4.011' + - + class: Pod::Weaver::Section::Region + name: '@Author::RWSTAUNER/Prelude' + version: '4.011' + - + class: Pod::Weaver::Section::Generic + name: '@Author::RWSTAUNER/Synopsis' + version: '4.011' + - + class: Pod::Weaver::Section::Generic + name: '@Author::RWSTAUNER/Description' + version: '4.011' + - + class: Pod::Weaver::Section::Generic + name: '@Author::RWSTAUNER/Overview' + version: '4.011' + - + class: Pod::Weaver::Section::Generic + name: '@Author::RWSTAUNER/Usage' + version: '4.011' + - + class: Pod::Weaver::Section::Collect + name: '@Author::RWSTAUNER/Class Methods' + version: '4.011' + - + class: Pod::Weaver::Section::Collect + name: '@Author::RWSTAUNER/Attributes' + version: '4.011' + - + class: Pod::Weaver::Section::Collect + name: '@Author::RWSTAUNER/Methods' + version: '4.011' + - + class: Pod::Weaver::Section::Collect + name: '@Author::RWSTAUNER/Functions' + version: '4.011' + - + class: Pod::Weaver::Section::Leftovers + name: '@Author::RWSTAUNER/Leftovers' + version: '4.011' + - + class: Pod::Weaver::Section::Region + name: '@Author::RWSTAUNER/Postlude' + version: '4.011' + - + class: Pod::Weaver::Section::Support + name: '@Author::RWSTAUNER/Support' + version: '1.007' + - + class: Pod::Weaver::Section::Generic + name: '@Author::RWSTAUNER/Acknowledgements' + version: '4.011' + - + class: Pod::Weaver::Section::Authors + name: '@Author::RWSTAUNER/Authors' + version: '4.011' + - + class: Pod::Weaver::Section::Contributors + name: '@Author::RWSTAUNER/Contributors' + version: '0.009' + - + class: Pod::Weaver::Section::Legal + name: '@Author::RWSTAUNER/Legal' + version: '4.011' + - + class: Pod::Weaver::Plugin::Transformer + name: '@Author::RWSTAUNER/List' + version: '4.011' + - + class: Pod::Weaver::Plugin::StopWords + name: '@Author::RWSTAUNER/StopWords' + version: '1.010' + name: '@Author::RWSTAUNER/PodWeaver' + version: '4.006' + - + class: Dist::Zilla::Plugin::License + name: '@Author::RWSTAUNER/License' + version: '5.035' + - + class: Dist::Zilla::Plugin::Readme + name: '@Author::RWSTAUNER/Readme' + version: '5.035' + - + class: Dist::Zilla::Plugin::ReadmeAnyFromPod + name: '@Author::RWSTAUNER/ReadmeAnyFromPod' + version: '0.150250' + - + class: Dist::Zilla::Plugin::CopyFilesFromRelease + config: + Dist::Zilla::Plugin::CopyFilesFromRelease: + filename: + - LICENSE + match: [] + name: '@Author::RWSTAUNER/CopyFilesFromRelease' + version: '0.005' + - + class: Dist::Zilla::Plugin::AutoMetaResources + name: '@Author::RWSTAUNER/AutoMetaResources' + version: '1.20' + - + class: Dist::Zilla::Plugin::GithubMeta + name: '@Author::RWSTAUNER/GithubMeta' + version: '0.48' + - + class: Dist::Zilla::Plugin::ContributorsFromGit + name: '@Author::RWSTAUNER/ContributorsFromGit' + version: '0.013' + - + class: Dist::Zilla::Plugin::AutoPrereqs + name: '@Author::RWSTAUNER/AutoPrereqs' + version: '5.035' + - + class: Dist::Zilla::Plugin::MetaNoIndex + name: '@Author::RWSTAUNER/MetaNoIndex' + version: '5.035' + - + class: Dist::Zilla::Plugin::MetaProvides::Package + config: + Dist::Zilla::Plugin::MetaProvides::Package: + finder_objects: + - + class: Dist::Zilla::Plugin::FinderCode + name: '@Author::RWSTAUNER/MetaProvides::Package/AUTOVIV/:InstallModulesPM' + version: '5.035' + Dist::Zilla::Role::MetaProvider::Provider: + inherit_missing: '1' + inherit_version: '1' + meta_noindex: '1' + name: '@Author::RWSTAUNER/MetaProvides::Package' + version: '2.003001' + - + class: Dist::Zilla::Plugin::MinimumPerl + name: '@Author::RWSTAUNER/MinimumPerl' + version: '1.006' + - + class: Dist::Zilla::Plugin::MetaConfig + name: '@Author::RWSTAUNER/MetaConfig' + version: '5.035' + - + class: Dist::Zilla::Plugin::MetaYAML + name: '@Author::RWSTAUNER/MetaYAML' + version: '5.035' + - + class: Dist::Zilla::Plugin::MetaJSON + name: '@Author::RWSTAUNER/MetaJSON' + version: '5.035' + - + class: Dist::Zilla::Plugin::ExecDir + name: '@Author::RWSTAUNER/ExecDir' + version: '5.035' + - + class: Dist::Zilla::Plugin::ShareDir + name: '@Author::RWSTAUNER/ShareDir' + version: '5.035' + - + class: Dist::Zilla::Plugin::MakeMaker + config: + Dist::Zilla::Role::TestRunner: + default_jobs: 1 + name: '@Author::RWSTAUNER/MakeMaker' + version: '5.035' + - + class: Dist::Zilla::Plugin::Test::PodSpelling + name: '@Author::RWSTAUNER/Test::PodSpelling' + version: '2.006008' + - + class: Dist::Zilla::Plugin::Test::Compile + config: + Dist::Zilla::Plugin::Test::Compile: + bail_out_on_fail: '0' + fail_on_warning: author + fake_home: '1' + filename: t/00-compile.t + module_finder: + - ':InstallModules' + needs_display: '0' + phase: test + script_finder: + - ':ExecFiles' + skips: [] + name: '@Author::RWSTAUNER/@TestingMania/Test::Compile' + version: '2.052' + - + class: Dist::Zilla::Plugin::Test::CPAN::Meta::JSON + name: '@Author::RWSTAUNER/@TestingMania/Test::CPAN::Meta::JSON' + version: '0.004' + - + class: Dist::Zilla::Plugin::Test::Perl::Critic + name: '@Author::RWSTAUNER/@TestingMania/Test::Perl::Critic' + version: '3.000' + - + class: Dist::Zilla::Plugin::Test::EOL + config: + Dist::Zilla::Plugin::Test::EOL: + filename: xt/author/eol.t + finder: + - ':InstallModules' + - ':ExecFiles' + - ':TestFiles' + trailing_whitespace: '1' + name: '@Author::RWSTAUNER/@TestingMania/Test::EOL' + version: '0.18' + - + class: Dist::Zilla::Plugin::Test::MinimumVersion + name: '@Author::RWSTAUNER/@TestingMania/Test::MinimumVersion' + version: '2.000006' + - + class: Dist::Zilla::Plugin::MojibakeTests + name: '@Author::RWSTAUNER/@TestingMania/MojibakeTests' + version: '0.7' + - + class: Dist::Zilla::Plugin::Test::DistManifest + name: '@Author::RWSTAUNER/@TestingMania/Test::DistManifest' + version: '2.000005' + - + class: Dist::Zilla::Plugin::Test::Pod::LinkCheck + name: '@Author::RWSTAUNER/@TestingMania/Test::Pod::LinkCheck' + version: '1.001' + - + class: Dist::Zilla::Plugin::Test::Version + name: '@Author::RWSTAUNER/@TestingMania/Test::Version' + version: '0.003001' + - + class: Dist::Zilla::Plugin::Test::NoTabs + config: + Dist::Zilla::Plugin::Test::NoTabs: + filename: xt/author/no-tabs.t + finder: + - ':InstallModules' + - ':ExecFiles' + - ':TestFiles' + name: '@Author::RWSTAUNER/@TestingMania/Test::NoTabs' + version: '0.14' + - + class: Dist::Zilla::Plugin::Test::Synopsis + name: '@Author::RWSTAUNER/@TestingMania/Test::Synopsis' + version: '2.000006' + - + class: Dist::Zilla::Plugin::Test::UnusedVars + name: '@Author::RWSTAUNER/@TestingMania/Test::UnusedVars' + version: '2.000007' + - + class: Dist::Zilla::Plugin::PodCoverageTests + name: '@Author::RWSTAUNER/@TestingMania/PodCoverageTests' + version: '5.035' + - + class: Dist::Zilla::Plugin::Test::CPAN::Changes + name: '@Author::RWSTAUNER/@TestingMania/Test::CPAN::Changes' + version: '0.009' + - + class: Dist::Zilla::Plugin::PodSyntaxTests + name: '@Author::RWSTAUNER/@TestingMania/PodSyntaxTests' + version: '5.035' + - + class: Dist::Zilla::Plugin::Test::Kwalitee + config: + Dist::Zilla::Plugin::Test::Kwalitee: + filename: xt/release/kwalitee.t + skiptest: [] + name: '@Author::RWSTAUNER/@TestingMania/Test::Kwalitee' + version: '2.11' + - + class: Dist::Zilla::Plugin::MetaTests + name: '@Author::RWSTAUNER/@TestingMania/MetaTests' + version: '5.035' + - + class: Dist::Zilla::Plugin::Manifest + name: '@Author::RWSTAUNER/Manifest' + version: '5.035' + - + class: Dist::Zilla::Plugin::CheckExtraTests + name: '@Author::RWSTAUNER/CheckExtraTests' + version: '0.026' + - + class: Dist::Zilla::Plugin::CheckChangesHasContent + name: '@Author::RWSTAUNER/CheckChangesHasContent' + version: '0.008' + - + class: Dist::Zilla::Plugin::CheckMetaResources + name: '@Author::RWSTAUNER/CheckMetaResources' + version: '0.001' + - + class: Dist::Zilla::Plugin::CheckPrereqsIndexed + name: '@Author::RWSTAUNER/CheckPrereqsIndexed' + version: '0.015' + - + class: Dist::Zilla::Plugin::TestRelease + name: '@Author::RWSTAUNER/TestRelease' + version: '5.035' + - + class: Dist::Zilla::Plugin::Git::Check + config: + Dist::Zilla::Plugin::Git::Check: + untracked_files: die + Dist::Zilla::Role::Git::DirtyFiles: + allow_dirty: + - Changes + - README.mkdn + - README.pod + - LICENSE + allow_dirty_match: [] + changelog: Changes + Dist::Zilla::Role::Git::Repo: + repo_root: . + name: '@Author::RWSTAUNER/@Git/Check' + version: '2.033' + - + class: Dist::Zilla::Plugin::Git::Commit + config: + Dist::Zilla::Plugin::Git::Commit: + add_files_in: [] + commit_msg: v%v%t%n%n%c + time_zone: local + Dist::Zilla::Role::Git::DirtyFiles: + allow_dirty: + - Changes + - README.mkdn + - README.pod + - LICENSE + allow_dirty_match: [] + changelog: Changes + Dist::Zilla::Role::Git::Repo: + repo_root: . + name: '@Author::RWSTAUNER/@Git/Commit' + version: '2.033' + - + class: Dist::Zilla::Plugin::Git::Tag + config: + Dist::Zilla::Plugin::Git::Tag: + branch: ~ + signed: 0 + tag: v0.926 + tag_format: v%v + tag_message: v%v + time_zone: local + Dist::Zilla::Role::Git::Repo: + repo_root: . + name: '@Author::RWSTAUNER/@Git/Tag' + version: '2.033' + - + class: Dist::Zilla::Plugin::Git::Push + config: + Dist::Zilla::Plugin::Git::Push: + push_to: + - origin + remotes_must_exist: 1 + Dist::Zilla::Role::Git::Repo: + repo_root: . + name: '@Author::RWSTAUNER/@Git/Push' + version: '2.033' + - + class: Dist::Zilla::Plugin::ConfirmRelease + name: '@Author::RWSTAUNER/ConfirmRelease' + version: '5.035' + - + class: Dist::Zilla::Plugin::UploadToCPAN + name: '@Author::RWSTAUNER/UploadToCPAN' + version: '5.035' + - + class: Dist::Zilla::Plugin::InstallRelease + name: '@Author::RWSTAUNER/InstallRelease' + version: '0.008' + - + class: Dist::Zilla::Plugin::Encoding + name: BinaryFiles + version: '5.035' + - + class: Dist::Zilla::Plugin::Prereqs + config: + Dist::Zilla::Plugin::Prereqs: + phase: runtime + type: requires + name: Prereqs + version: '5.035' + - + class: Dist::Zilla::Plugin::Prereqs + config: + Dist::Zilla::Plugin::Prereqs: + phase: develop + type: requires + name: DevelopRequires + version: '5.035' + - + class: Dist::Zilla::Plugin::Run::BeforeBuild + config: + Dist::Zilla::Plugin::Run::Role::Runner: + fatal_errors: 1 + run: + - '%x corpus/make_dists' + name: Run::BeforeBuild + version: '0.035' + - + class: Dist::Zilla::Plugin::Test::ReportPrereqs + name: Test::ReportPrereqs + version: '0.021' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':InstallModules' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':IncModules' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':TestFiles' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':ExecFiles' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':ShareFiles' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':MainModule' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':AllFiles' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: ':NoFiles' + version: '5.035' + - + class: Dist::Zilla::Plugin::FinderCode + name: '@Author::RWSTAUNER/MetaProvides::Package/AUTOVIV/:InstallModulesPM' + version: '5.035' + zilla: + class: Dist::Zilla::Dist::Builder + config: + is_trial: '' + version: '5.035' +x_authority: cpan:RWSTAUNER +x_contributors: + - 'David Steinbrunner <dsteinbrunner@pobox.com>' + - 'Jeffrey Ryan Thalhammer <thaljef@cpan.org>' + - 'Sawyer X <xsawyerx@cpan.org>' diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..12b1813 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,105 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.035. +use strict; +use warnings; + +use 5.006; + +use ExtUtils::MakeMaker; + +my %WriteMakefileArgs = ( + "ABSTRACT" => "Information about a perl module distribution", + "AUTHOR" => "Randy Stauner <rwstauner\@cpan.org>", + "CONFIGURE_REQUIRES" => { + "ExtUtils::MakeMaker" => 0 + }, + "DISTNAME" => "Dist-Metadata", + "EXE_FILES" => [], + "LICENSE" => "perl", + "MIN_PERL_VERSION" => "5.006", + "NAME" => "Dist::Metadata", + "PREREQ_PM" => { + "Archive::Tar" => 1, + "Archive::Zip" => "1.30", + "CPAN::DistnameInfo" => "0.12", + "CPAN::Meta" => "2.1", + "Carp" => 0, + "Digest" => "1.03", + "Digest::MD5" => 2, + "Digest::SHA" => 5, + "File::Basename" => 0, + "File::Find" => 0, + "File::Spec::Native" => "1.002", + "File::Temp" => "0.19", + "List::Util" => 0, + "Module::Metadata" => 0, + "Path::Class" => "0.24", + "Try::Tiny" => "0.09", + "parent" => 0, + "strict" => 0, + "warnings" => 0 + }, + "TEST_REQUIRES" => { + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "File::Temp" => "0.19", + "IO::Handle" => 0, + "IPC::Open3" => 0, + "Test::Fatal" => 0, + "Test::MockObject" => "1.09", + "Test::More" => "0.96" + }, + "VERSION" => "0.926", + "test" => { + "TESTS" => "t/*.t" + } +); + + +my %FallbackPrereqs = ( + "Archive::Tar" => 1, + "Archive::Zip" => "1.30", + "CPAN::DistnameInfo" => "0.12", + "CPAN::Meta" => "2.1", + "Carp" => 0, + "Digest" => "1.03", + "Digest::MD5" => 2, + "Digest::SHA" => 5, + "ExtUtils::MakeMaker" => 0, + "File::Basename" => 0, + "File::Find" => 0, + "File::Spec" => 0, + "File::Spec::Native" => "1.002", + "File::Temp" => "0.19", + "IO::Handle" => 0, + "IPC::Open3" => 0, + "List::Util" => 0, + "Module::Metadata" => 0, + "Path::Class" => "0.24", + "Test::Fatal" => 0, + "Test::MockObject" => "1.09", + "Test::More" => "0.96", + "Try::Tiny" => "0.09", + "parent" => 0, + "strict" => 0, + "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) }; + +WriteMakefile(%WriteMakefileArgs); @@ -0,0 +1,15 @@ + + +This archive contains the distribution Dist-Metadata, +version 0.926: + + Information about a perl module distribution + +This software is copyright (c) 2011 by Randy Stauner. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + + +This README file was generated by Dist::Zilla::Plugin::Readme v5.035. + diff --git a/corpus/Dist-Metadata-Test-LikePause-0.1.tar.gz b/corpus/Dist-Metadata-Test-LikePause-0.1.tar.gz Binary files differnew file mode 100644 index 0000000..beebbc6 --- /dev/null +++ b/corpus/Dist-Metadata-Test-LikePause-0.1.tar.gz diff --git a/corpus/Dist-Metadata-Test-LikePause-0.1.zip b/corpus/Dist-Metadata-Test-LikePause-0.1.zip Binary files differnew file mode 100644 index 0000000..42bfd87 --- /dev/null +++ b/corpus/Dist-Metadata-Test-LikePause-0.1.zip diff --git a/corpus/Dist-Metadata-Test-LikePause-0.1/README b/corpus/Dist-Metadata-Test-LikePause-0.1/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/Dist-Metadata-Test-LikePause-0.1/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm b/corpus/Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm new file mode 100644 index 0000000..1fe631b --- /dev/null +++ b/corpus/Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm @@ -0,0 +1,18 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::LikePause; + +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = '0.1'; + +# This should be excluded unless "include_inner_packages" is true +package ExtraPackage; + +our $VERSION = '0.2'; diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gz b/corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gz Binary files differnew file mode 100644 index 0000000..5e0b38a --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gz diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2.zip b/corpus/Dist-Metadata-Test-MetaFile-2.2.zip Binary files differnew file mode 100644 index 0000000..31e9509 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2.zip diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2/META.json b/corpus/Dist-Metadata-Test-MetaFile-2.2/META.json new file mode 100644 index 0000000..a9dcc64 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2/META.json @@ -0,0 +1,39 @@ +{ + "abstract" : "Fake dist for testing metadata determination", + "author" : [ + "Randy Stauner <rwstauner@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "hand", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Dist-Metadata-Test-MetaFile", + "no_index" : { + "directory" : [ + "corpus", + "examples", + "inc", + "share", + "t", + "xt" + ] + }, + "provides" : { + "Dist::Metadata::Test::MetaFile" : { + "file" : "lib/Dist/Metadata/Test/MetaFile.pm", + "version" : "2.1" + }, + "Dist::Metadata::Test::MetaFile::PM" : { + "file" : "lib/Dist/Metadata/Test/MetaFile/PM.pm", + "version" : "2.0" + } + }, + "release_status" : "stable", + "version" : "2.2" +} + diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2/META.yml b/corpus/Dist-Metadata-Test-MetaFile-2.2/META.yml new file mode 100644 index 0000000..1ceb7ac --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2/META.yml @@ -0,0 +1,29 @@ +--- +abstract: Fake dist for testing metadata determination +author: +- Randy Stauner <rwstauner@cpan.org> +dynamic_config: 0 +generated_by: hand +license: +- perl_5 +meta-spec: + url: http://search.cpan.org/perldoc?CPAN::Meta::Spec + version: '2' +name: Dist-Metadata-Test-MetaFile +no_index: + directory: + - corpus + - examples + - inc + - share + - t + - xt +provides: + Dist::Metadata::Test::MetaFile: + file: lib/Dist/Metadata/Test/MetaFile.pm + version: '2.05' + Dist::Metadata::Test::MetaFile::PM: + file: lib/Dist/Metadata/Test/MetaFile/PM.pm + version: '2.04' +release_status: stable +version: '2.2' diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2/README b/corpus/Dist-Metadata-Test-MetaFile-2.2/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm b/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm new file mode 100644 index 0000000..eba4f29 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm @@ -0,0 +1,13 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::MetaFile; +# ABSTRACT: Fake dist for testing metadata determination + +# does not match META file but we trust the META file +our $VERSION = '1.5'; diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm b/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm new file mode 100644 index 0000000..042cfd0 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::MetaFile::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = '1.1'; diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gz b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gz Binary files differnew file mode 100644 index 0000000..0d77ac6 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gz diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip Binary files differnew file mode 100644 index 0000000..cdf4b36 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json new file mode 100644 index 0000000..08dc97f --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json @@ -0,0 +1,27 @@ +{ + "abstract" : "Fake dist for testing metadata determination", + "author" : [ + "Randy Stauner <rwstauner@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "hand", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Dist-Metadata-Test-MetaFile-Incomplete", + "no_index" : { + "directory" : [ + "examples", + "share", + "xt" + ] + }, + "provides" : {}, + "release_status" : "stable", + "version" : "2.1" +} + diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml new file mode 100644 index 0000000..d131cfb --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml @@ -0,0 +1,20 @@ +--- +abstract: Fake dist for testing metadata determination +author: +- Randy Stauner <rwstauner@cpan.org> +dynamic_config: 0 +generated_by: hand +license: +- perl_5 +meta-spec: + url: http://search.cpan.org/perldoc?CPAN::Meta::Spec + version: '2' +name: Dist-Metadata-Test-MetaFile-Incomplete +no_index: + directory: + - examples + - share + - xt +provides: {} +release_status: stable +version: '2.2' diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/README b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm new file mode 100644 index 0000000..1926433 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm @@ -0,0 +1,11 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package NotThis; +# ABSTRACT: Not to be indexed +1; diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm new file mode 100644 index 0000000..bf4b650 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::MetaFile::Incomplete; +# ABSTRACT: Just a file to be indexed + +our $VERSION = '2.1'; diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm new file mode 100644 index 0000000..e50e495 --- /dev/null +++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Never; +# ABSTRACT: Never index this + +1; diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gz b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gz Binary files differnew file mode 100644 index 0000000..b90010a --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gz diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip Binary files differnew file mode 100644 index 0000000..11049e0 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1/README b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm new file mode 100644 index 0000000..588d1a9 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::NoMetaFile; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = '0.1'; diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm new file mode 100644 index 0000000..6275167 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::NoMetaFile::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = '0.1'; diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gz b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gz Binary files differnew file mode 100644 index 0000000..ba91360 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gz diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip Binary files differnew file mode 100644 index 0000000..0f3e19e --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm new file mode 100644 index 0000000..6182ea4 --- /dev/null +++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::NoMetaFile::DevRelease; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = '0.1_1'; diff --git a/corpus/Dist-Metadata-Test-SubDir-1.5.tar.gz b/corpus/Dist-Metadata-Test-SubDir-1.5.tar.gz Binary files differnew file mode 100644 index 0000000..ba56dbb --- /dev/null +++ b/corpus/Dist-Metadata-Test-SubDir-1.5.tar.gz diff --git a/corpus/Dist-Metadata-Test-SubDir-1.5.zip b/corpus/Dist-Metadata-Test-SubDir-1.5.zip Binary files differnew file mode 100644 index 0000000..df48916 --- /dev/null +++ b/corpus/Dist-Metadata-Test-SubDir-1.5.zip diff --git a/corpus/make_dists b/corpus/make_dists new file mode 100755 index 0000000..09d7c72 --- /dev/null +++ b/corpus/make_dists @@ -0,0 +1,94 @@ +#!/usr/bin/env perl +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# + +# This script is used for generating test data when the dist is built + +use strict; +use warnings; +use FindBin; # core +use Archive::Any::Create; +use File::Find; # core +use Path::Class 0.24; +use IO::File; # core +use Data::Dumper (); # core + +my $work_dir = $FindBin::Bin; +my $structs; +my $dists = { + metafile => { + dir => 'Dist-Metadata-Test-MetaFile-2.2', + }, + metafile_incomplete => { + dir => 'Dist-Metadata-Test-MetaFile-Incomplete-2.1', + }, + nometafile => { + dir => 'Dist-Metadata-Test-NoMetaFile-0.1', + }, + nometafile_dev_release => { + dir => 'Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1', + }, + index_like_pause => { + dir => 'Dist-Metadata-Test-LikePause-0.1', + }, + subdir => { + dir => 'Dist-Metadata-Test-SubDir-1.5', + cd => 'subdir', + }, + noroot => { + dir => '.', + cd => 'noroot', + file => 'noroot', + }, +}; + +while( my ($name, $dist) = each %$dists ){ + my $archive = Archive::Any::Create->new; + my $struct = {}; + + my $wd = $dist->{cd} + ? dir( $work_dir, $dist->{cd} ) + : $work_dir; + my $fd = dir( $wd, $dist->{dir} ); + + my @files; + find({ + wanted => sub { + push @files, $_ + if -f $_; + }, + no_chdir => 1, + }, + $fd + ); + + foreach my $file ( @files ){ + my $rel = file($file)->relative($wd); + my $content = slurp($file); + $archive->add_file( $rel => $content ); + # convert relative file path from Native to Unix since DM Struct defaults to Unix. + $struct->{ $rel->as_foreign('Unix') } = $content; + } + + my $base = $dist->{file} || $dist->{dir}; + $archive->write_file(file($work_dir, "$base.$_")->stringify) + for qw(tar.gz zip); + $structs->{$name} = $struct; +} + +{ + local $Data::Dumper::Indent = 1; + spit( + file($work_dir, 'structs.pl'), + Data::Dumper->Dump( [$structs], ['Dist::Metadata::Test::Structs'] ) + ); +} + +sub slurp { local $/; IO::File->new($_[0], 'r')->getline } +sub spit { IO::File->new($_[0], 'w')->print($_[1]) } diff --git a/corpus/noroot.tar.gz b/corpus/noroot.tar.gz Binary files differnew file mode 100644 index 0000000..e549848 --- /dev/null +++ b/corpus/noroot.tar.gz diff --git a/corpus/noroot.zip b/corpus/noroot.zip Binary files differnew file mode 100644 index 0000000..50ef6f4 --- /dev/null +++ b/corpus/noroot.zip diff --git a/corpus/noroot/README b/corpus/noroot/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/noroot/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/noroot/lib/Dist/Metadata/Test/NoRoot.pm b/corpus/noroot/lib/Dist/Metadata/Test/NoRoot.pm new file mode 100644 index 0000000..99ad713 --- /dev/null +++ b/corpus/noroot/lib/Dist/Metadata/Test/NoRoot.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::NoRoot; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = '3.3'; diff --git a/corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm b/corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm new file mode 100644 index 0000000..2ab16bd --- /dev/null +++ b/corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::NoRoot::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = '3.25'; diff --git a/corpus/structs.pl b/corpus/structs.pl new file mode 100644 index 0000000..177ab2c --- /dev/null +++ b/corpus/structs.pl @@ -0,0 +1,228 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +$Dist::Metadata::Test::Structs = { + 'nometafile' => { + 'Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm' => 'package Dist::Metadata::Test::NoMetaFile; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = \'0.1\'; +', + 'Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm' => 'package Dist::Metadata::Test::NoMetaFile::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = \'0.1\'; +', + 'Dist-Metadata-Test-NoMetaFile-0.1/README' => 'This "dist" is for testing Dist::Metadata. +' + }, + 'noroot' => { + 'lib/Dist/Metadata/Test/NoRoot.pm' => 'package Dist::Metadata::Test::NoRoot; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = \'3.3\'; +', + 'README' => 'This "dist" is for testing Dist::Metadata. +', + 'lib/Dist/Metadata/Test/NoRoot/PM.pm' => 'package Dist::Metadata::Test::NoRoot::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = \'3.25\'; +' + }, + 'subdir' => { + 'Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm' => 'package Dist::Metadata::Test::SubDir; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = \'1.1\'; +', + 'Dist-Metadata-Test-SubDir-1.5/README' => 'This "dist" is for testing Dist::Metadata. +', + 'Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm' => 'package Dist::Metadata::Test::SubDir::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = \'1.0\'; +' + }, + 'nometafile_dev_release' => { + 'Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README' => 'This "dist" is for testing Dist::Metadata. +', + 'Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm' => 'package Dist::Metadata::Test::NoMetaFile::DevRelease; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = \'0.1_1\'; +' + }, + 'index_like_pause' => { + 'Dist-Metadata-Test-LikePause-0.1/README' => 'This "dist" is for testing Dist::Metadata. +', + 'Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm' => 'package Dist::Metadata::Test::LikePause; + +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = \'0.1\'; + +# This should be excluded unless "include_inner_packages" is true +package ExtraPackage; + +our $VERSION = \'0.2\'; +' + }, + 'metafile_incomplete' => { + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/README' => 'This "dist" is for testing Dist::Metadata. +', + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm' => 'package Dist::Metadata::Test::MetaFile::Incomplete; +# ABSTRACT: Just a file to be indexed + +our $VERSION = \'2.1\'; +', + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml' => '--- +abstract: Fake dist for testing metadata determination +author: +- Randy Stauner <rwstauner@cpan.org> +dynamic_config: 0 +generated_by: hand +license: +- perl_5 +meta-spec: + url: http://search.cpan.org/perldoc?CPAN::Meta::Spec + version: \'2\' +name: Dist-Metadata-Test-MetaFile-Incomplete +no_index: + directory: + - examples + - share + - xt +provides: {} +release_status: stable +version: \'2.2\' +', + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm' => 'package Never; +# ABSTRACT: Never index this + +1; +', + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json' => '{ + "abstract" : "Fake dist for testing metadata determination", + "author" : [ + "Randy Stauner <rwstauner@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "hand", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Dist-Metadata-Test-MetaFile-Incomplete", + "no_index" : { + "directory" : [ + "examples", + "share", + "xt" + ] + }, + "provides" : {}, + "release_status" : "stable", + "version" : "2.1" +} + +', + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm' => 'package NotThis; +# ABSTRACT: Not to be indexed +1; +' + }, + 'metafile' => { + 'Dist-Metadata-Test-MetaFile-2.2/META.yml' => '--- +abstract: Fake dist for testing metadata determination +author: +- Randy Stauner <rwstauner@cpan.org> +dynamic_config: 0 +generated_by: hand +license: +- perl_5 +meta-spec: + url: http://search.cpan.org/perldoc?CPAN::Meta::Spec + version: \'2\' +name: Dist-Metadata-Test-MetaFile +no_index: + directory: + - corpus + - examples + - inc + - share + - t + - xt +provides: + Dist::Metadata::Test::MetaFile: + file: lib/Dist/Metadata/Test/MetaFile.pm + version: \'2.05\' + Dist::Metadata::Test::MetaFile::PM: + file: lib/Dist/Metadata/Test/MetaFile/PM.pm + version: \'2.04\' +release_status: stable +version: \'2.2\' +', + 'Dist-Metadata-Test-MetaFile-2.2/README' => 'This "dist" is for testing Dist::Metadata. +', + 'Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm' => 'package Dist::Metadata::Test::MetaFile; +# ABSTRACT: Fake dist for testing metadata determination + +# does not match META file but we trust the META file +our $VERSION = \'1.5\'; +', + 'Dist-Metadata-Test-MetaFile-2.2/META.json' => '{ + "abstract" : "Fake dist for testing metadata determination", + "author" : [ + "Randy Stauner <rwstauner@cpan.org>" + ], + "dynamic_config" : 0, + "generated_by" : "hand", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Dist-Metadata-Test-MetaFile", + "no_index" : { + "directory" : [ + "corpus", + "examples", + "inc", + "share", + "t", + "xt" + ] + }, + "provides" : { + "Dist::Metadata::Test::MetaFile" : { + "file" : "lib/Dist/Metadata/Test/MetaFile.pm", + "version" : "2.1" + }, + "Dist::Metadata::Test::MetaFile::PM" : { + "file" : "lib/Dist/Metadata/Test/MetaFile/PM.pm", + "version" : "2.0" + } + }, + "release_status" : "stable", + "version" : "2.2" +} + +', + 'Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm' => 'package Dist::Metadata::Test::MetaFile::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = \'1.1\'; +' + } +}; diff --git a/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/README b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/README new file mode 100644 index 0000000..0d67857 --- /dev/null +++ b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/README @@ -0,0 +1 @@ +This "dist" is for testing Dist::Metadata. diff --git a/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm new file mode 100644 index 0000000..1933083 --- /dev/null +++ b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::SubDir; +# ABSTRACT: Fake dist for testing metadata determination + +our $VERSION = '1.1'; diff --git a/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm new file mode 100644 index 0000000..8b8d47e --- /dev/null +++ b/corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm @@ -0,0 +1,12 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +package Dist::Metadata::Test::SubDir::PM; +# ABSTRACT: Just a file to be indexed + +our $VERSION = '1.0'; diff --git a/dist.ini b/dist.ini new file mode 100644 index 0000000..76053c2 --- /dev/null +++ b/dist.ini @@ -0,0 +1,47 @@ +name = Dist-Metadata +author = Randy Stauner <rwstauner@cpan.org> +license = Perl_5 +copyright_holder = Randy Stauner +copyright_year = 2011 + +[@Author::RWSTAUNER] +:version = 4.201 +-remove = Test::ReportPrereqs +; TODO: remove this after releasing a new author bundle +-remove = ReportVersions::Tiny +;PortabilityTests.options = test_mac_length = 0, test_one_dot = 0 +-remove = Test::Portability + +[%PodWeaver] +-StopWords.include = TODO dist dists dir unix checksum checksums + +[Encoding / BinaryFiles] +encoding = bytes +match = \.(zip|tar\.gz)$ + +[Prereqs] +; File::Temp->newdir +File::Temp = 0.19 +File::Spec::Native = 1.002 + +; These Digest mods are in core as of 5.8/5.10. +Digest = 1.03 +Digest::MD5 = 2 +Digest::SHA = 5 + +; Needed for dzil build, too. +; authordep Archive::Any::Create +[Prereqs / DevelopRequires] +Archive::Any::Create = 0.03 + +[Run::BeforeBuild] +; generate test data +run = %x corpus/make_dists + +; CPAN::Meta requires Parse::CPAN::Meta which requires JSON::PP +; but in some smoke test environments it seems to be missing. +; JSON-2.27 bundled it's own JSON:PP (2.27008) which may be the culprit. +[Test::ReportPrereqs] +:version = 0.004 +include = JSON::PP +include = JSON diff --git a/lib/Dist/Metadata.pm b/lib/Dist/Metadata.pm new file mode 100644 index 0000000..a05414e --- /dev/null +++ b/lib/Dist/Metadata.pm @@ -0,0 +1,677 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata; +# git description: v0.925-17-g08a6891 + +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Information about a perl module distribution +$Dist::Metadata::VERSION = '0.926'; +use Carp qw(croak carp); +use CPAN::Meta 2.1 (); +use List::Util qw(first); # core in perl v5.7.3 + +# something that is obviously not a real value +sub UNKNOWN () { '- unknown -' } # constant + + +sub new { + my $class = shift; + my $self = { + determine_packages => 1, + @_ == 1 ? %{ $_[0] } : @_ + }; + + my @formats = qw( dist file dir struct ); + croak(qq[A dist must be specified (one of ] . + join(', ', map { "'$_'" } @formats) . ')') + unless first { $self->{$_} } @formats; + + bless $self, $class; +} + + +sub dist { + my ($self) = @_; + return $self->{dist} ||= do { + my $dist; + if( my $struct = $self->{struct} ){ + require Dist::Metadata::Struct; + $dist = Dist::Metadata::Struct->new(%$struct); + } + elsif( my $dir = $self->{dir} ){ + require Dist::Metadata::Dir; + $dist = Dist::Metadata::Dir->new(dir => $dir); + } + elsif ( my $file = $self->{file} ){ + require Dist::Metadata::Archive; + $dist = Dist::Metadata::Archive->new(file => $file); + } + else { + # new() checks for one and dies without so we shouldn't get here + croak q[No dist format parameters found!]; + } + $dist; # return + }; +} + + +sub default_metadata { + my ($self) = @_; + + return { + # required + abstract => UNKNOWN, + author => [], + dynamic_config => 0, + generated_by => ( ref($self) || $self ) . ' version ' . ( $self->VERSION || 0 ), + license => ['unknown'], # this 'unknown' comes from CPAN::Meta::Spec + 'meta-spec' => { + version => '2', + url => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec', + }, + name => UNKNOWN, + + # strictly speaking, release_status is also required but + # CPAN::Meta will figure it out based on the version number. if + # we were to set it explicitly, then we would first need to + # examine the version number for '_' or 'TRIAL' or 'RC' etc. + + version => 0, + + # optional + no_index => { + # Ignore the same directories as PAUSE (https://github.com/andk/pause/blob/master/lib/PAUSE/dist.pm#L758): + # skip "t" - libraries in ./t are test libraries! + # skip "xt" - libraries in ./xt are author test libraries! + # skip "inc" - libraries in ./inc are usually install libraries + # skip "local" - somebody shipped his carton setup! + # skip 'perl5" - somebody shipped her local::lib! + # skip 'fatlib' - somebody shipped their fatpack lib! + directory => [qw( inc t xt local perl5 fatlib )], + }, + # provides => { package => { file => $file, version => $version } } + }; +} + + +sub determine_metadata { + my ($self) = @_; + + my $dist = $self->dist; + my $meta = $self->default_metadata; + + # get name and version from dist if dist was able to parse them + foreach my $att (qw(name version)) { + my $val = $dist->$att; + # if the dist could determine it that's better than the default + # but undef won't validate. value in $self will still override. + $meta->{$att} = $val + if defined $val; + } + + # any passed in values should take priority + foreach my $field ( keys %$meta ){ + $meta->{$field} = $self->{$field} + if exists $self->{$field}; + } + + return $meta; +} + + +sub determine_packages { + # meta must be passed to avoid infinite loop + my ( $self, $meta ) = @_; + # if not passed in, use defaults (we just want the 'no_index' property) + $meta ||= $self->meta_from_struct( $self->determine_metadata ); + + # should_index_file() expects unix paths + my @files = grep { + $meta->should_index_file( + $self->dist->path_classify_file($_)->as_foreign('Unix')->stringify + ); + } + $self->dist->perl_files; + + # TODO: should we limit packages to lib/ if it exists? + # my @lib = grep { m#^lib/# } @files; @files = @lib if @lib; + + return {} if not @files; + + my $packages = $self->dist->determine_packages(@files); + + + foreach my $pack ( keys %$packages ) { + + # Remove any packages that should not be indexed + if ( !$meta->should_index_package($pack) ) { + delete $packages->{$pack}; + next; + } + + unless( $self->{include_inner_packages} ){ + # PAUSE only considers packages that match the basename of the + # containing file. For example, file Foo.pm may only contain a + # package that matches /\bFoo$/. This is what PAUSE calls a + # "simile". All other packages in the file will be ignored. + + # capture file basename (without the extension) + my ($base) = ($packages->{$pack}->{file} =~ m!([^/]+)\.pm(?:\.PL)?$!); + # remove if file didn't match regexp or package doesn't match basename + delete $packages->{$pack} + if !$base || $pack !~ m{\b\Q$base\E$}; + } + } + + return $packages; +} + + +sub load_meta { + my ($self) = @_; + + my $dist = $self->dist; + my @files = $dist->list_files; + my ( $meta, $metafile ); + my $default_meta = $self->determine_metadata; + + # prefer json file (spec v2) + if ( $metafile = first { m#^META\.json$# } @files ) { + $meta = CPAN::Meta->load_json_string( $dist->file_content($metafile) ); + } + # fall back to yaml file (spec v1) + elsif ( $metafile = first { m#^META\.ya?ml$# } @files ) { + $meta = CPAN::Meta->load_yaml_string( $dist->file_content($metafile) ); + } + # no META file found in dist + else { + $meta = $self->meta_from_struct( $default_meta ); + } + + { + # always include (never index) the default no_index dirs + my $dir = ($meta->{no_index} ||= {})->{directory} ||= []; + my %seen = map { ($_ => 1) } @$dir; + unshift @$dir, + grep { !$seen{$_}++ } + @{ $default_meta->{no_index}->{directory} }; + } + + # Something has to be indexed, so if META has no (or empty) 'provides' + # attempt to determine packages unless specifically configured not to + if ( !keys %{ $meta->provides || {} } && $self->{determine_packages} ) { + # respect api/encapsulation + my $struct = $meta->as_struct; + $struct->{provides} = $self->determine_packages($meta); + $meta = $self->meta_from_struct($struct); + } + + return $meta; +} + + +sub meta { + my ($self) = @_; + return $self->{meta} ||= $self->load_meta; +} + + +sub meta_from_struct { + my ($self, $struct) = @_; + return CPAN::Meta->create( $struct, { lazy_validation => 1 } ); +} + + +sub package_versions { + my ($self) = shift; + my $provides = @_ ? shift : $self->provides; # || {} + return { + map { ($_ => $provides->{$_}{version}) } keys %$provides + }; +} + + +sub module_info { + my ($self, $opts) = @_; + my $provides = $opts->{provides} || $self->provides; + $provides = { %$provides }; # break reference + + my $checksums = $opts->{checksum} || $opts->{digest} || []; + $checksums = [ $checksums ] + unless ref($checksums) eq 'ARRAY'; + + my $digest_cache = {}; + foreach my $mod ( keys %$provides ){ + my $data = { %{ $provides->{ $mod } } }; # break reference + + foreach my $checksum ( @$checksums ){ + $data->{ $checksum } = + $digest_cache->{ $data->{file} }->{ $checksum } ||= + $self->dist->file_checksum($data->{file}, $checksum); + } + + # TODO: $opts->{callback}->($self, $mod, $data, sub { $self->dist->file_content($data->{file}) }); + + $provides->{ $mod } = $data; + } + + return $provides; +} + + +{ + no strict 'refs'; ## no critic (NoStrict) + foreach my $method ( qw( + name + provides + version + ) ){ + *$method = sub { $_[0]->meta->$method }; + } +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X cpan testmatrix url +annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata +placeholders metacpan + +=head1 NAME + +Dist::Metadata - Information about a perl module distribution + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dist = Dist::Metadata->new(file => $path_to_archive); + + my $description = sprintf "Dist %s (%s)", $dist->name, $dist->version; + + my $provides = $dist->package_versions; + while( my ($package, $version) = each %$provides ){ + print "$description includes $package $version\n"; + } + +=head1 DESCRIPTION + +This module provides an easy interface for getting various metadata +about a Perl module distribution. + +It takes care of the common logic of: + +=over 4 + +=item * + +reading a tar file (L<Archive::Tar>) + +=item * + +finding and reading the correct META file if the distribution contains one (L<CPAN::Meta>) + +=item * + +and determining some of the metadata if there is no META file (L<Module::Metadata>, L<CPAN::DistnameInfo>) + +=back + +This is mostly a wrapper around L<CPAN::Meta> providing an easy interface +to find and load the meta file from a F<tar.gz> file. +A dist can also be represented by a directory or merely a structure of data. + +If the dist does not contain a meta file +the module will attempt to determine some of that data from the dist. + +B<NOTE>: This interface is still being defined. +Please submit any suggestions or concerns. + +=head1 METHODS + +=head2 new + + Dist::Metadata->new(file => $path); + +A dist can be represented by +a tar file, +a directory, +or a data structure. + +The format will be determined by the presence of the following options +(checked in this order): + +=over 4 + +=item * + +C<struct> - hash of data to build a mock dist; See L<Dist::Metadata::Struct>. + +=item * + +C<dir> - path to the root directory of a dist + +=item * + +C<file> - the path to a F<.tar.gz> file + +=back + +You can also slyly pass in your own object as a C<dist> parameter +in which case this module will just use that. +This can be useful if you need to use your own subclass +(perhaps while developing a new format). + +Other options that can be specified: + +=over 4 + +=item * + +C<name> - dist name + +=item * + +C<version> - dist version + +=item * + +C<determine_packages> - boolean to indicate whether dist should be searched +for packages if no META file is found. Defaults to true. + +=item * + +C<include_inner_packages> - When determining provided packages +the default behavior is to only include packages that match the name +of the file that defines them (like C<Foo::Bar> matches C<*/Bar.pm>). +This way only modules that can be loaded (via C<use> or C<require>) +will be returned (and "inner" packages will be ignored). +This mimics the behavior of PAUSE. +Set this to true to include any "inner" packages provided by the dist +(that are not otherwise excluded by another mechanism (such as C<no_index>)). + +=back + +=head2 dist + +Returns the dist object (subclass of L<Dist::Metadata::Dist>). + +=head2 default_metadata + +Returns a hashref of default values +used to initialize a L<CPAN::Meta> object +when a META file is not found. +Called from L</determine_metadata>. + +=head2 determine_metadata + +Examine the dist and try to determine metadata. +Returns a hashref which can be passed to L<CPAN::Meta/new>. +This is used when the dist does not contain a META file. + +=head2 determine_packages + + my $provides = $dm->determine_packages($meta); + +Attempt to determine packages provided by the dist. +This is used when the META file does not include a C<provides> +section and C<determine_packages> is not set to false in the constructor. + +If a L<CPAN::Meta> object is not provided a default one will be used. +Files contained in the dist and packages found therein will be checked against +the meta object's C<no_index> attribute +(see L<CPAN::Meta/should_index_file> +and L<CPAN::Meta/should_index_package>). +By default this ignores any files found in +F<inc/>, +F<t/>, +or F<xt/> +directories. + +=head2 load_meta + +Loads the metadata from the L</dist>. + +=head2 meta + +Returns the L<CPAN::Meta> instance in use. + +=head2 meta_from_struct + + $meta = $dm->meta_from_struct(\%struct); + +Passes the provided C<\%struct> to L<CPAN::Meta/create> +and returns the result. + +=head2 package_versions + + $pv = $dm->package_versions(); + # { 'Package::Name' => '1.0', 'Module::2' => '2.1' } + +Returns a simplified version of C<provides>: +a hashref with package names as keys and versions as values. + +This can also be called as a class method +which will operate on a passed in hashref. + + $pv = Dist::Metadata->package_versions(\%provides); + +=head2 module_info + +Returns a hashref of meta data for each of the packages provided by this dist. + +The hashref starts with the same data as L</provides> +but additional data can be added to the output by specifying options in a hashref: + +=over 4 + +=item C<checksum> + +Use the specified algorithm to compute a hex digest of the file. +The type you specify will be the key in the returned hashref. +You can use an arrayref to specify more than one type. + + $dm->module_info({checksum => ['sha256', 'md5']}); + # returns: + { + 'Mod::Name' => { + file => 'lib/Mod/Name.pm', + version => '0.1', + md5 => '258e88dcbd3cd44d8e7ab43f6ecb6af0', + sha256 => 'f22136124cd3e1d65a48487cecf310771b2fd1e83dc032e3d19724160ac0ff71', + }, + } + +See L<Dist::Metadata::Dist/file_checksum> for more information. + +=item C<provides> + +The default is to start with the hashref returned from L</provides> +but you can pass in an alternate hashref using this key. + +=back + +Other options may be added in the future. + +=head1 INHERITED METHODS + +The following methods are available on this object +and simply call the corresponding method on the L<CPAN::Meta> object. + +=over 4 + +=item * + +X<name> name + +=item * + +X<provides> provides + +=item * + +X<version> version + +=back + +=for Pod::Coverage name version provides +UNKNOWN + +=for test_synopsis my $path_to_archive; + +=head1 TODO + +=over 4 + +=item * + +More tests + +=item * + +C<trust_meta> option (to allow setting it to false) + +=item * + +Guess main module from dist name if no packages can be found + +=item * + +Determine abstract? + +=item * + +Add change log info (L<CPAN::Changes>)? + +=item * + +Subclass as C<CPAN::Dist::Metadata> just so that it has C<CPAN> in the name? + +=item * + +Use L<File::Find::Rule::Perl>? + +=back + +=head1 SEE ALSO + +=head2 Dependencies + +=over 4 + +=item * + +L<CPAN::Meta> + +=item * + +L<Module::Metadata> + +=item * + +L<CPAN::DistnameInfo> + +=back + +=head2 Related Modules + +=over 4 + +=item * + +L<MyCPAN::Indexer> + +=item * + +L<CPAN::ParseDistribution> + +=back + +=head1 SUPPORT + +=head2 Perldoc + +You can find documentation for this module with the perldoc command. + + perldoc Dist::Metadata + +=head2 Websites + +The following websites have more information about this module, and may be of help to you. As always, +in addition to those websites please use your favorite search engine to discover more resources. + +=over 4 + +=item * + +MetaCPAN + +A modern, open-source CPAN search engine, useful to view POD in HTML format. + +L<http://metacpan.org/release/Dist-Metadata> + +=back + +=head2 Bugs / Feature Requests + +Please report any bugs or feature requests by email to C<bug-dist-metadata at rt.cpan.org>, or through +the web interface at L<https://rt.cpan.org/Public/Bug/Report.html?Queue=Dist-Metadata>. You will be automatically notified of any +progress on the request by the system. + +=head2 Source Code + + +L<https://github.com/rwstauner/Dist-Metadata> + + git clone https://github.com/rwstauner/Dist-Metadata.git + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 CONTRIBUTORS + +=for stopwords David Steinbrunner Jeffrey Ryan Thalhammer Sawyer X + +=over 4 + +=item * + +David Steinbrunner <dsteinbrunner@pobox.com> + +=item * + +Jeffrey Ryan Thalhammer <thaljef@cpan.org> + +=item * + +Sawyer X <xsawyerx@cpan.org> + +=back + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Archive.pm b/lib/Dist/Metadata/Archive.pm new file mode 100644 index 0000000..cb0bb60 --- /dev/null +++ b/lib/Dist/Metadata/Archive.pm @@ -0,0 +1,171 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Archive; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Base class for Dist::Metadata archive files +$Dist::Metadata::Archive::VERSION = '0.926'; +use Carp (); # core +use parent 'Dist::Metadata::Dist'; + +push(@Dist::Metadata::CARP_NOT, __PACKAGE__); + + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + + if( $class eq __PACKAGE__ ){ + my $subclass = 'Dist::Metadata::' . + ( $self->{file} =~ /\.zip$/ ? 'Zip' : 'Tar' ); + + eval "require $subclass" + or Carp::croak $@; + + # rebless into format specific subclass + bless $self, $subclass; + } + + return $self; +} + +sub required_attribute { 'file' } + + +sub archive { + my ($self) = @_; + return $self->{archive} ||= do { + my $file = $self->file; + + Carp::croak "File '$file' does not exist" + unless -e $file; + + $self->read_archive($file); # return + }; +} + + +sub default_file_spec { 'Unix' } + + +sub determine_name_and_version { + my ($self) = @_; + $self->set_name_and_version( $self->parse_name_and_version( $self->file ) ); + return $self->SUPER::determine_name_and_version(@_); +} + + +sub file { + return $_[0]->{file}; +} + + +sub read_archive { + Carp::croak q[Method 'read_archive' not defined]; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Archive - Base class for Dist::Metadata archive files + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dist = Dist::Metadata->new(file => $path_to_archive); + +=head1 DESCRIPTION + +This is a subclass of L<Dist::Metadata::Dist> +to enable determining the metadata from an archive file. + +It is a base class for archive file formats: + +=over 4 + +=item * + +L<Dist::Metadata::Tar> + +=item * + +L<Dist::Metadata::Zip> + +=back + +It's not useful on it's own +and should be used from L<Dist::Metadata/new>. + +=head1 METHODS + +=head2 new + + $dist = Dist::Metadata::Archive->new(file => $path); + +Accepts a single C<file> argument that should be a path to a file. + +If called from this base class +C<new()> will delegate to a subclass based on the filename +and return a blessed instance of that subclass. + +=head2 archive + +Returns an object representing the archive file. + +=head2 default_file_spec + +Returns C<Unix> since most archive files are be in unix format. + +=head2 determine_name_and_version + +Attempts to parse name and version from file name. + +=head2 file + +The C<file> attribute passed to the constructor, +used to load L</archive>. + +=head2 read_archive + + $dist->read_archive($file); + +Returns a format-specific object representing the specified file. + +This B<must> be defined by subclasses. + +=for test_synopsis my $path_to_archive; + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Dir.pm b/lib/Dist/Metadata/Dir.pm new file mode 100644 index 0000000..78812a2 --- /dev/null +++ b/lib/Dist/Metadata/Dir.pm @@ -0,0 +1,186 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Dir; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Enable Dist::Metadata for a directory +$Dist::Metadata::Dir::VERSION = '0.926'; +use Carp qw(croak carp); # core +use File::Find (); # core +use Path::Class 0.24 (); +use parent 'Dist::Metadata::Dist'; + +push(@Dist::Metadata::CARP_NOT, __PACKAGE__); + + +sub new { + my $class = shift; + my $self = $class->SUPER::new(@_); + + # fix up dir (for example chop trailing slash if present) + $self->{dir} = $self->path_class_dir->new($self->{dir})->stringify; + + # TODO: croak if not -d $self->dir + + return $self; +} + +sub required_attribute { 'dir' } + + +sub determine_name_and_version { + my ($self) = @_; + # 'root' may be more accurate than 'dir' + $self->SUPER::determine_name_and_version(); + $self->set_name_and_version( $self->parse_name_and_version( $self->dir ) ); + return; +} + + +sub dir { + $_[0]->{dir}; +} + +# this shouldn't be called +sub extract_into { + croak q[A directory doesn't need to be extracted]; +} + + +sub file_content { + my ($self, $file) = @_; + # This is a directory so file spec will always be native + my $path = $self->path_class_file + ->new( $self->{dir}, $self->full_path($file) )->stringify; + + open(my $fh, '<', $path) + or croak "Failed to open file '$path': $!"; + + return do { local $/; <$fh> }; +} + + +sub find_files { + my ($self) = @_; + + my $dir = $self->{dir}; + my @files; + + File::Find::find( + { + wanted => sub { + push @files, $self->path_class_file->new($_)->relative($dir)->stringify + if -f $_; + }, + no_chdir => 1 + }, + $dir + ); + + return @files; +} + + +sub physical_directory { + my ($self, @files) = @_; + + # TODO: return absolute_path? + my @parts = $self->{dir}; + # go into root dir if there is one + push @parts, $self->root + if $self->root; + + my $dir = $self->path_class_dir->new(@parts)->absolute; + + return $dir->stringify unless wantarray; + + return map { $_->stringify } + ($dir, map { $dir->file( $_ ) } @files); +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Dir - Enable Dist::Metadata for a directory + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dm = Dist::Metadata->new(dir => $path_to_dir); + +=head1 DESCRIPTION + +This is a subclass of L<Dist::Metadata::Dist> +to enable getting the dists metadata from a directory. + +This can be useful if you already have a dist extracted into a directory. + +It's probably not very useful on it's own though, +and should be used from L<Dist::Metadata/new>. + +=head1 METHODS + +=head2 new + + $dist = Dist::Metadata::Struct->new(dir => $path); + +Accepts a single 'dir' argument that should be a path to a directory. + +=head2 determine_name_and_version + +Attempts to parse name and version from directory name. + +=head2 dir + +Returns the C<dir> attribute specified in the constructor. + +=head2 file_content + +Returns the content for the specified file. + +=head2 find_files + +Returns a list of the file names beneath the directory +(relative to the directory). + +=head2 physical_directory + +Returns the C<dir> attribute since this is already a directory +containing the desired files. + +=for test_synopsis my $path_to_dir; + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Dist.pm b/lib/Dist/Metadata/Dist.pm new file mode 100644 index 0000000..063affd --- /dev/null +++ b/lib/Dist/Metadata/Dist.pm @@ -0,0 +1,623 @@ +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Dist; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Base class for format-specific implementations +$Dist::Metadata::Dist::VERSION = '0.926'; +use Carp qw(croak carp); # core +use CPAN::DistnameInfo 0.12 (); +use Path::Class 0.24 (); +use Try::Tiny 0.09; + + +sub new { + my $class = shift; + my $self = { + @_ == 1 ? %{ $_[0] } : @_ + }; + + bless $self, $class; + + my $req = $class->required_attribute; + croak qq['$req' parameter required] + if $req && !$self->{$req}; + + if ( exists $self->{file_spec} ) { + # we just want the OS name ('Unix' or '') + $self->{file_spec} =~ s/^File::Spec(::)?// + if $self->{file_spec}; + # blank is no good, use "Native" hack + $self->{file_spec} = 'Native' + if !$self->{file_spec}; + } + + return $self; +} + + +sub default_file_spec { 'Native' } + + +sub determine_name_and_version { + my ($self) = @_; + $self->set_name_and_version( $self->parse_name_and_version( $self->root ) ); + return; +} + + +sub determine_packages { + my ($self, @files) = @_; + + my $determined = try { + my @dir_and_files = $self->physical_directory(@files); + + # return + $self->packages_from_directory(@dir_and_files); + } + catch { + carp("Error determining packages: $_[0]"); + +{}; # return + }; + + return $determined; +} + + +sub extract_into { + my ($self, $dir, @files) = @_; + + @files = $self->list_files + unless @files; + + require File::Basename; + + my @disk_files; + foreach my $file (@files) { + my $ff = $self->path_class_file->new_foreign( $self->file_spec, $file ); + # Translate dist format (relative path) to disk/OS format and prepend $dir. + # This dir_list + basename hack is probably ok because the paths in a dist + # should always be relative (if there *was* a volume we wouldn't want it). + my $path = $self->path_class_file + ->new( $dir, $ff->dir->dir_list, $ff->basename ); + + $path->dir->mkpath(0, oct(700)); + + my $full_path = $path->stringify; + open(my $fh, '>', $full_path) + or croak "Failed to open '$full_path' for writing: $!"; + print $fh $self->file_content($file); + + # do we really want full path or do we want relative? + push(@disk_files, $full_path); + } + + return (wantarray ? ($dir, @disk_files) : $dir); +} + + +sub file_content { + croak q[Method 'file_content' not defined]; +} + + +sub file_checksum { + my ($self, $file, $type) = @_; + $type ||= 'md5'; + + require Digest; # core + + # md5 => MD5, sha256 => SHA-256 + (my $impl = uc $type) =~ s/^(SHA|CRC)([0-9]+)$/$1-$2/; + + my $digest = Digest->new($impl); + + $digest->add( $self->file_content($file) ); + return $digest->hexdigest; +} + + +sub find_files { + croak q[Method 'find_files' not defined]; +} + + +sub file_spec { + my ($self) = @_; + + $self->{file_spec} = $self->default_file_spec + if !exists $self->{file_spec}; + + return $self->{file_spec}; +} + + +sub full_path { + my ($self, $file) = @_; + + return $file + unless my $root = $self->root; + + # don't re-add the root if it's already there + return $file + # FIXME: this regexp is probably not cross-platform... + # FIXME: is there a way to do this with File::Spec? + if $file =~ m@^\Q${root}\E[\\/]@; + + # FIXME: does this foreign_file work w/ Dir ? + return $self->path_class_file + ->new_foreign($self->file_spec, $root, $file)->stringify; +} + + +sub list_files { + my ($self) = @_; + + $self->{_list_files} = do { + my @files = sort $self->find_files; + my ($root, @rel) = $self->remove_root_dir(@files); + $self->{root} = $root; + \@rel; # return + } + unless $self->{_list_files}; + + return @{ $self->{_list_files} }; +} + + +{ + no strict 'refs'; ## no critic (NoStrict) + foreach my $method ( qw( + name + version + ) ){ + *$method = sub { + my ($self) = @_; + + $self->determine_name_and_version + if !exists $self->{ $method }; + + return $self->{ $method }; + }; + } +} + + +sub packages_from_directory { + my ($self, $dir, @files) = @_; + + my @pvfd = ($dir); + # M::M::p_v_f_d expects full paths for \@files + push @pvfd, [map { + $self->path_class_file->new($_)->is_absolute + ? $_ : $self->path_class_file->new($dir, $_)->stringify + } @files] + if @files; + + require Module::Metadata; + + my $provides = try { + my $packages = Module::Metadata->package_versions_from_directory(@pvfd); + while ( my ($pack, $pv) = each %$packages ) { + # M::M::p_v_f_d returns files in native OS format (obviously); + # CPAN::Meta expects file paths in Unix format + $pv->{file} = $self->path_class_file + ->new($pv->{file})->as_foreign('Unix')->stringify; + } + $packages; # return + } + catch { + carp("Failed to determine packages: $_[0]"); + +{}; # return + }; + return $provides || {}; +} + + +sub parse_name_and_version { + my ($self, $path) = @_; + my ( $name, $version ); + if ( $path ){ + # try a simple regexp first + $path =~ m! + ([^\\/]+) # name (anything below final directory) + - # separator + (v?[0-9._]+) # version + (?: # possible file extensions + \.t(?:ar\.)?gz + )? + $ + !x and + ( $name, $version ) = ( $1, $2 ); + + # attempt to improve data with CPAN::DistnameInfo (but ignore any errors) + # TODO: also grab maturity and cpanid ? + # release_status = $dist->maturity eq 'released' ? 'stable' : 'unstable'; + # -(TRIAL|RC) => 'testing', '_' => 'unstable' + eval { + # DistnameInfo expects any directories in unix format (thanks jeroenl) + my $dnifile = $self->path_class_file + ->new($path)->as_foreign('Unix')->stringify; + # if it doesn't appear to have an extension fake one to help DistnameInfo + $dnifile .= '.tar.gz' unless $dnifile =~ /\.[a-z]\w+$/; + + my $dni = CPAN::DistnameInfo->new($dnifile); + my $dni_name = $dni->dist; + my $dni_version = $dni->version; + # if dni matched both name and version, or previous regexp didn't match + if ( $dni_name && $dni_version || !$name ) { + $name = $dni_name if $dni_name; + $version = $dni_version if $dni_version; + } + }; + warn $@ if $@; + } + return ($name, $version); +} + + +sub path_class_dir { $_[0]->{path_class_dir} ||= 'Path::Class::Dir' } +sub path_class_file { $_[0]->{path_class_file} ||= 'Path::Class::File' } + + +sub path_classify_dir { + my ($self, $dir) = @_; + $self->path_class_dir->new_foreign($self->file_spec, $dir) +} + +sub path_classify_file { + my ($self, $file) = @_; + $self->path_class_file->new_foreign($self->file_spec, $file) +} + + +sub perl_files { + return + grep { /\.pm$/ } + $_[0]->list_files; +} + + +sub physical_directory { + my ($self, @files) = @_; + + require File::Temp; + # dir will be removed when return value goes out of scope (in caller) + my $dir = File::Temp->newdir(); + + return $self->extract_into($dir, @files); +} + + +sub remove_root_dir { + my ($self, @files) = @_; + return unless @files; + + # FIXME: can we use File::Spec for these regexp's instead of [\\/] ? + + # grab the root dir from the first file + $files[0] =~ m{^([^\\/]+)[\\/]} + # if not matched quit now + or return (undef, @files); + + my $dir = $1; + my @rel; + + # strip $dir from each file + for (@files) { + + m{^\Q$dir\E[\\/](.+)$} + # if the match failed they're not all under the same root so just return now + or return (undef, @files); + + push @rel, $1; + } + + return ($dir, @rel); + +} + + +sub required_attribute { return } + + +sub root { + my ($self) = @_; + + # call list_files instead of find_files so that it caches the result + $self->list_files + unless exists $self->{root}; + + return $self->{root}; +} + + +sub set_name_and_version { + my ($self, @values) = @_; + my @fields = qw( name version ); + + foreach my $i ( 0 .. $#fields ){ + $self->{ $fields[$i] } = $values[$i] + if !exists $self->{ $fields[$i] } && defined $values[$i]; + } + return; +} + + +# version() defined with name() + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Dist - Base class for format-specific implementations + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + # don't use this, use a subclass + +=head1 DESCRIPTION + +This is a base class for different dist formats. + +The following methods B<must> be defined by subclasses: + +=over 4 + +=item * + +L</file_content> + +=item * + +L</find_files> + +=back + +=head1 METHODS + +=head2 new + +Simple constructor that subclasses can inherit. +Ensures the presence of L</required_attribute> +if defined by the subclass. + +=head2 default_file_spec + +Defaults to C<'Native'> in the base class +which will let L<File::Spec> determine the value. + +=head2 determine_name_and_version + +Some dist formats may define a way to determine the name and version. + +=head2 determine_packages + + $packages = $dist->determine_packages(@files); + +Search the specified files (or all files if unspecified) +for perl packages. + +Extracts the files to a temporary directory if necessary +and uses L<Module::Metadata> to discover package names and versions. + +=head2 extract_into + + $ddir = $dist->extract_into($dir); + ($ddir, @dfiles) = $dist->extract_into($dir, @files); + +Extracts the specified files (or all files if not specified) +into the specified directory. + +In list context this returns a list of the directory +(which may be a subdirectory of the C<$dir> passed in) +and the files extracted (in native OS (on-disk) format). + +In scalar context just the directory is returned. + +=head2 file_content + +Returns the content for the specified file from the dist. + +This B<must> be defined by subclasses. + +=head2 file_checksum + + $dist->file_checksum('lib/Mod/Name.pm', 'sha256'); + +Returns a checksum (hex digest) of the file content. + +The L<Digest> module is used to generate the checksums. +The value specified should be one accepted by C<< Digest->new >>. +A small effort is made to translate simpler names like +C<md5> into C<MD5> and C<sha1> into C<SHA-1> +(which are the names L<Digest> expects). + +If the type of checksum is not specified C<md5> will be used. + +=head2 find_files + +Determine the files contained in the dist. + +This is called from L</list_files> and cached on the object. + +This B<must> be defined by subclasses. + +=head2 file_spec + +Returns the OS name of the L<File::Spec> module used for this format. +This is mostly so subclasses can define a specific one +(as L</default_file_spec>) if necessary. + +A C<file_spec> attribute can be passed to the constructor +to override the default. + +B<NOTE>: This is used for the internal format of the dist. +Tar archives, for example, are always in unix format. +For operations outside of the dist, +the format determined by L<File::Spec> will always be used. + +=head2 full_path + + $dist->full_path("lib/Mod.pm"); # "root-dir/lib/Mod.pm" + +Used internally to put the L</root> directory back onto the file. + +=head2 list_files + +Returns a list of the files in the dist starting at the dist root. + +This calls L</find_files> to get a listing of the contents of the dist, +determines (and caches) the root directory (if any), +caches and returns the list of files with the root dir stripped. + + @files = $dist->list_files; + # something like qw( README META.yml lib/Mod.pm ) + +=head2 name + +The dist name if it could be determined. + +=head2 packages_from_directory + + $provides = $dist->packages_from_directory($dir, @files); + +Determines the packages provided by the perl modules found in a directory. +This is thin wrapper around +L<Module::Metadata/package_versions_from_directory>. +It returns a hashref like L<CPAN::Meta::Spec/provides>. + +B<NOTE>: C<$dir> must be a physical directory on the disk, +therefore C<@files> (if specified) must be in native OS format. +This function is called internally from L</determine_packages> +(which calls L<physical_directory> (which calls L</extract_into>)) +which manages these requirements. + +=head2 parse_name_and_version + + ($name, $version) = $dist->parse_name_and_version($path); + +Attempt to parse name and version from the provided string. +This will work for dists named like "Dist-Name-1.0". + +=head2 path_class_dir + +Returns the class name used for L<Path::Class::Dir> objects. + +=head2 path_class_file + +Returns the class name used for L<Path::Class::File> objects. + +=head2 path_classify_dir + +This is a shortcut for returning an object representing the provided +dir utilizing L</path_class_dir> and L</file_spec>. + +=head2 path_classify_file + +This is a shortcut for returning an object representing the provided +file utilizing L</path_class_file> and L</file_spec>. + +=head2 perl_files + +Returns the subset of L</list_files> that look like perl files. +Currently returns anything matching C</\.pm$/> + +B<TODO>: This should probably be customizable. + +=head2 physical_directory + + $dir = $dist->physical_directory(); + ($dir, @dir_files) = $dist->physical_directory(@files); + +Returns the path to a physical directory on the disk +where the specified files (if any) can be found. + +For in-memory formats this will make a temporary directory +and write the specified files (or all files) into it. + +The return value is the same as L</extract_into>: +In scalar context the path to the directory is returned. +In list context the (possibly adjusted) paths to any specified files +are appended to the return value. + +=head2 remove_root_dir + + my ($dir, @rel) = $dm->remove_root_dir(@files); + +If all the C<@files> are beneath the same root directory +(as is normally the case) this will strip the root directory off of each file +and return a list of the root directory and the stripped files. + +If there is no root directory the first element of the list will be C<undef>. + +=head2 required_attribute + +A single attribute that is required by the class. +Subclasses can define this to make L</new> C<croak> if it isn't present. + +=head2 root + +Returns the root directory of the dist (if there is one). + +=head2 set_name_and_version + +This is a convenience method for setting the name and version +if they haven't already been set. +This is often called by L</determine_name_and_version>. + +=head2 version + +Returns the version if it could be determined from the dist. + +=head1 SEE ALSO + +=over 4 + +=item * + +L<Dist::Metadata::Tar> - for examining a tar file + +=item * + +L<Dist::Metadata::Dir> - for a directory already on the disk + +=item * + +L<Dist::Metadata::Struct> - for mocking up a dist with perl data structures + +=back + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Struct.pm b/lib/Dist/Metadata/Struct.pm new file mode 100644 index 0000000..bca5578 --- /dev/null +++ b/lib/Dist/Metadata/Struct.pm @@ -0,0 +1,131 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Struct; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Enable Dist::Metadata for a data structure +$Dist::Metadata::Struct::VERSION = '0.926'; +use Carp qw(croak carp); # core +use parent 'Dist::Metadata::Dist'; + +push(@Dist::Metadata::CARP_NOT, __PACKAGE__); + + +sub required_attribute { 'files' } + + +sub default_file_spec { 'Unix' } + + +sub file_content { + my ($self, $file) = @_; + # TODO: should we croak if not found? would be consistent with Dir + my $content = $self->{files}{ $self->full_path($file) }; + + # 5.10: given(ref($content)) + + if( my $ref = ref $content ){ + local $/; # do this here because of perl bug prior to perl 5.15 (7c2d9d0) + return $ref eq 'SCALAR' + # allow a scalar ref + ? $$content + # or an IO-like object + : $content->getline; + } + # else a simple string + return $content; +} + + +sub find_files { + my ($self) = @_; + + return keys %{ $self->{files} }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Struct - Enable Dist::Metadata for a data structure + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dm = Dist::Metadata->new(struct => { + files => { + 'lib/Mod.pm' => 'package Mod; sub something { ... }', + 'README' => 'this is a fake dist, useful for testing', + } + }); + +=head1 DESCRIPTION + +This is a subclass of L<Dist::Metadata::Dist> +to enable mocking up a dist from perl data structures. + +This is mostly used for testing +but might be useful if you already have an in-memory representation +of a dist that you'd like to examine. + +It's probably not very useful on it's own though, +and should be used from L<Dist::Metadata/new>. + +=head1 METHODS + +=head2 new + + $dist = Dist::Metadata::Struct->new(files => { + 'lib/Mod.pm' => 'package Mod; sub something { ... }', + }); + +Accepts a C<files> parameter that should be a hash of +C<< { name => content, } >>. +Content can be a string, a reference to a string, or an IO object. + +=head2 default_file_spec + +C<Unix> is the default for consistency/simplicity +but C<file_spec> can be overridden in the constructor. + +=head2 file_content + +Returns the string content for the specified name. + +=head2 find_files + +Returns the keys of the C<files> hash. + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Tar.pm b/lib/Dist/Metadata/Tar.pm new file mode 100644 index 0000000..bc89f49 --- /dev/null +++ b/lib/Dist/Metadata/Tar.pm @@ -0,0 +1,99 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Tar; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Enable Dist::Metadata for tar files +$Dist::Metadata::Tar::VERSION = '0.926'; +use Archive::Tar 1 (); # 0.07 isn't good enough +use Carp (); # core +use parent 'Dist::Metadata::Archive'; + +push(@Dist::Metadata::CARP_NOT, __PACKAGE__); + +sub file_content { + my ( $self, $file ) = @_; + return $self->archive->get_content( $self->full_path($file) ); +} + +sub find_files { + my ($self) = @_; + return + map { $_->full_path } + grep { $_->is_file } + $self->archive->get_files; +} + +sub read_archive { + my ($self, $file) = @_; + + my $archive = Archive::Tar->new(); + $archive->read($file); + + return $archive; +} + +sub tar { + warn __PACKAGE__ . '::tar() is deprecated. Use archive() instead.'; + return $_[0]->archive; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Tar - Enable Dist::Metadata for tar files + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dist = Dist::Metadata->new(file => $path_to_archive); + +=head1 DESCRIPTION + +This is a subclass of L<Dist::Metadata::Dist> +(actually of L<Dist::Metadata::Archive>) +to enable determining the metadata from a tar file. + +This is probably the most useful subclass. + +It's probably not very useful on it's own though, +and should be used from L<Dist::Metadata/new>. + +=for Pod::Coverage tar + +=for test_synopsis my $path_to_archive; + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/lib/Dist/Metadata/Zip.pm b/lib/Dist/Metadata/Zip.pm new file mode 100644 index 0000000..ba136b2 --- /dev/null +++ b/lib/Dist/Metadata/Zip.pm @@ -0,0 +1,95 @@ +# vim: set ts=2 sts=2 sw=2 expandtab smarttab: +# +# This file is part of Dist-Metadata +# +# This software is copyright (c) 2011 by Randy Stauner. +# +# This is free software; you can redistribute it and/or modify it under +# the same terms as the Perl 5 programming language system itself. +# +use strict; +use warnings; + +package Dist::Metadata::Zip; +our $AUTHORITY = 'cpan:RWSTAUNER'; +# ABSTRACT: Enable Dist::Metadata for zip files +$Dist::Metadata::Zip::VERSION = '0.926'; +use Archive::Zip 1.30 (); +use Carp (); # core + +use parent 'Dist::Metadata::Archive'; + +push(@Dist::Metadata::CARP_NOT, __PACKAGE__); + +sub file_content { + my ($self, $file) = @_; + my ($content, $status) = $self->archive->contents( $self->full_path($file) ); + Carp::croak "Failed to get content of '$file' from archive" + if $status != Archive::Zip::AZ_OK(); + return $content; +} + +sub find_files { + my ($self) = @_; + return + map { $_->fileName } + grep { !$_->isDirectory } + $self->archive->members; +} + +sub read_archive { + my ($self, $file) = @_; + + my $archive = Archive::Zip->new(); + $archive->read($file) == Archive::Zip::AZ_OK() + or Carp::croak "Failed to read zip file!"; + + return $archive; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=for :stopwords Randy Stauner ACKNOWLEDGEMENTS TODO dist dists dir unix checksum checksums +David Jeffrey Ryan Sawyer Steinbrunner Thalhammer X + +=head1 NAME + +Dist::Metadata::Zip - Enable Dist::Metadata for zip files + +=head1 VERSION + +version 0.926 + +=head1 SYNOPSIS + + my $dist = Dist::Metadata->new(file => $path_to_archive); + +=head1 DESCRIPTION + +This is a subclass of L<Dist::Metadata::Dist> +(actually of L<Dist::Metadata::Archive>) +to enable determining the metadata from a zip file. + +It's probably not very useful on it's own +and should be used from L<Dist::Metadata/new>. + +=for test_synopsis my $path_to_archive; + +=head1 AUTHOR + +Randy Stauner <rwstauner@cpan.org> + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2011 by Randy Stauner. + +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 diff --git a/t/00-compile.t b/t/00-compile.t new file mode 100644 index 0000000..e16fa2d --- /dev/null +++ b/t/00-compile.t @@ -0,0 +1,60 @@ +use 5.006; +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.052 + +use Test::More; + +plan tests => 7 + ($ENV{AUTHOR_TESTING} ? 1 : 0); + +my @module_files = ( + 'Dist/Metadata.pm', + 'Dist/Metadata/Archive.pm', + 'Dist/Metadata/Dir.pm', + 'Dist/Metadata/Dist.pm', + 'Dist/Metadata/Struct.pm', + 'Dist/Metadata/Tar.pm', + 'Dist/Metadata/Zip.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<perlfaq8/How can I capture STDERR from an external command?> + 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"); + + 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) ) if $ENV{AUTHOR_TESTING}; + + diff --git a/t/00-report-prereqs.dd b/t/00-report-prereqs.dd new file mode 100644 index 0000000..c378a45 --- /dev/null +++ b/t/00-report-prereqs.dd @@ -0,0 +1,68 @@ +do { my $x = { + 'configure' => { + 'requires' => { + 'ExtUtils::MakeMaker' => '0', + 'perl' => '5.006' + } + }, + 'develop' => { + 'requires' => { + 'Archive::Any::Create' => '0.03', + 'Pod::Coverage::TrustPod' => '0', + 'Test::CPAN::Changes' => '0.19', + 'Test::CPAN::Meta' => '0', + 'Test::CPAN::Meta::JSON' => '0.16', + 'Test::EOL' => '0', + 'Test::Kwalitee' => '1.21', + 'Test::More' => '0.88', + 'Test::NoTabs' => '0', + 'Test::Pod' => '1.41', + 'Test::Pod::Coverage' => '1.08', + 'Test::Spelling' => '0.12', + 'Test::Synopsis' => '0', + 'Test::Version' => '1' + } + }, + 'runtime' => { + 'requires' => { + 'Archive::Tar' => '1', + 'Archive::Zip' => '1.30', + 'CPAN::DistnameInfo' => '0.12', + 'CPAN::Meta' => '2.1', + 'Carp' => '0', + 'Digest' => '1.03', + 'Digest::MD5' => '2', + 'Digest::SHA' => '5', + 'File::Basename' => '0', + 'File::Find' => '0', + 'File::Spec::Native' => '1.002', + 'File::Temp' => '0.19', + 'List::Util' => '0', + 'Module::Metadata' => '0', + 'Path::Class' => '0.24', + 'Try::Tiny' => '0.09', + 'parent' => '0', + 'perl' => '5.006', + 'strict' => '0', + 'warnings' => '0' + } + }, + 'test' => { + 'recommends' => { + 'CPAN::Meta' => '2.120900' + }, + 'requires' => { + 'ExtUtils::MakeMaker' => '0', + 'File::Spec' => '0', + 'File::Temp' => '0.19', + 'IO::Handle' => '0', + 'IPC::Open3' => '0', + 'Test::Fatal' => '0', + 'Test::MockObject' => '1.09', + 'Test::More' => '0.96', + 'perl' => '5.006' + } + } + }; + $x; + }
\ No newline at end of file diff --git a/t/00-report-prereqs.t b/t/00-report-prereqs.t new file mode 100644 index 0000000..cce9245 --- /dev/null +++ b/t/00-report-prereqs.t @@ -0,0 +1,184 @@ +#!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( + JSON::PP + JSON +); + +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: diff --git a/t/archive.t b/t/archive.t new file mode 100644 index 0000000..f75539b --- /dev/null +++ b/t/archive.t @@ -0,0 +1,91 @@ +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; + +my $mod = 'Dist::Metadata::Archive'; +eval "require $mod" or die $@; + +# default_file_spec +is( $mod->default_file_spec, 'Unix', 'most archive files use unix paths' ); + +test_constructor_errors($mod); + +# test file type determination +my $base = 'corpus/Dist-Metadata-Test-NoMetaFile-0.1'; +foreach my $test ( + [Zip => "$base.zip"], + [Tar => "$base.tar.gz"], +){ + my ($type, $file) = @$test; + + my $distclass = "Dist::Metadata::$type"; + + # instantiate using base 'Archive' class which will determine subclass + my $archive = new_ok($mod => [file => $file]); + + isa_ok($archive, $distclass); + isa_ok($archive->archive, "Archive::$type"); + + # file + is($archive->file, $file, 'dumb accessor works'); + + # determine_name_and_version + $archive->determine_name_and_version(); + is($archive->name, 'Dist-Metadata-Test-NoMetaFile', 'name from file'); + is($archive->version, '0.1', 'version from file'); + + # file_content + is( + $archive->file_content('README'), + qq[This "dist" is for testing Dist::Metadata.\n], + 'got file content without specifying root dir' + ); + + # perllocale says, "By default Perl ignores the current locale." + + # find_files + is_deeply( + [sort $archive->find_files], + [qw( + Dist-Metadata-Test-NoMetaFile-0.1/README + Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm + Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm + )], + 'find_files' + ); + + # list_files (no root) + is_deeply( + [sort $archive->list_files], + [qw( + README + lib/Dist/Metadata/Test/NoMetaFile.pm + lib/Dist/Metadata/Test/NoMetaFile/PM.pm + )], + 'files listed without root directory' + ); + + # root + is($archive->root, 'Dist-Metadata-Test-NoMetaFile-0.1', 'root dir'); + + # do this last so that successful new() has already loaded the distclass + test_constructor_errors($distclass); +} + +done_testing; + +# required_attribute +# file doesn't exist +sub test_constructor_errors { + my $mod = shift; + + my $att = 'file'; + is( $mod->required_attribute, $att, "'$att' attribute required" ); + my $ex = exception { $mod->new() }; + like($ex, qr/'$att' parameter required/, "new dies without '$att'"); + + my $dist = new_ok( $mod, [ file => 'does-not._exist_' ] ); + $ex = exception { $dist->archive }; + like($ex, qr/does not exist/, 'file does not exist'); +} diff --git a/t/determine.t b/t/determine.t new file mode 100644 index 0000000..4f9f49b --- /dev/null +++ b/t/determine.t @@ -0,0 +1,129 @@ +use strict; +use warnings; +use Test::More 0.96; + +my $mod = 'Dist::Metadata'; +my $smod = "${mod}::Struct"; +eval "require $_" || die $@ + for $mod, $smod; + +$Dist::Metadata::VERSION ||= 0; # avoid undef warnings + +{ + foreach my $test ( + [ + '/tmp/No-Existy-1.01', + [], + ['No-Existy', '1.01'], + undef # same + ], + [ + # main module: No::Existy::3 (like perl5i::2) + 'No-Existy-3-v2.1.3', + [], + ['No-Existy-3', 'v2.1.3'], + undef # same + ], + [ + # constructor args override + 'No-Existy-3-v2.1.3', + [ + name => 'Who-Cares' + ], + ['No-Existy-3', 'v2.1.3'], + ['Who-Cares', 'v2.1.3'], + ], + [ + # constructor args override + 'No-Existy-3-v2.1.3', + [ + name => 'Who-Cares', + version => 5, + ], + ['No-Existy-3', 'v2.1.3'], + ['Who-Cares', '5'], + ], + ){ + my ($base, $args, $parsed, $att) = @$test; + $att ||= $parsed; + # test dir name and tar file name + foreach my $path ( $base, "$base.tar.gz", "$base.tgz" ){ + my $dm = new_ok($smod, [files => {}, @$args]); + + my @nv = $dm->parse_name_and_version($path); + is_deeply(\@nv, $parsed, 'parsed name and version'); + + $dm->set_name_and_version(@nv); + is_deeply([$dm->name, $dm->version], $att, "set dist name and version"); + } + } +} + +{ + my $struct = { + files => { + 'README' => 'we need a file to establish the root dir', + 'lib/Bunnies.pm' => <<'BUNNIES', +package Bunnies; +our $VERSION = 2.3; + +package # comment + HiddenBunnies; +our $VERSION = 2.4; + +package TooManyBunnies; +our $VERSION = 2.5; +BUNNIES + 'lib/Rabbit/Hole.pm' => <<'HOLE', +package Rabbit::Hole; +our $VERSION = '1.1'; + +package Rabbit::Hole::Cover; +our $VERSION = '1.1'; +HOLE + # Test something that doesn't match the "simile" regexp in DM:determine_packages. + # Module::Metadata 1.000009 will find this but for obvious reasons PAUSE would not index it. + # If MM stops finding this we'll have to determine if there are + # any other possible file names that wouldn't match the regexp. + 'lib/.pm' => <<'GOOFY', +package Goofy; +our $VERSION = '0.1'; +GOOFY + }, + }; + + is_deeply + new_ok($mod, [struct => $struct, include_inner_packages => 1])->determine_packages, + { + Bunnies => { file => 'lib/Bunnies.pm', version => '2.3', }, + TooManyBunnies => { file => 'lib/Bunnies.pm', version => '2.5', }, + Goofy => { file => 'lib/.pm', version => '0.1', }, + 'Rabbit::Hole' => { file => 'lib/Rabbit/Hole.pm', version => '1.1' }, + 'Rabbit::Hole::Cover' => { file => 'lib/Rabbit/Hole.pm', version => '1.1' }, + }, + 'determine all (not hidden) packages'; + + is_deeply + new_ok($mod, [struct => $struct])->determine_packages, + { + Bunnies => { file => 'lib/Bunnies.pm', version => '2.3', }, + 'Rabbit::Hole' => { file => 'lib/Rabbit/Hole.pm', version => '1.1' }, + }, + 'determine only "simile" packages'; + + { + my $dm = new_ok($mod, [struct => $struct]); + my $cpan_meta = $dm->default_metadata; + push @{ $cpan_meta->{no_index}{namespace} ||= [] }, 'Rabbit'; # this is only about bunnies + + is_deeply + $dm->determine_packages($dm->meta_from_struct($cpan_meta)), + { + Bunnies => { file => 'lib/Bunnies.pm', version => '2.3', }, + }, + 'determine only loadable modules, minus no_index/namespace'; + } + +} + +done_testing; @@ -0,0 +1,115 @@ +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; +use Test::MockObject 1.09 (); +use Path::Class 0.24 qw(file dir); +use File::Spec (); + +my $tmpdir = File::Spec->tmpdir; + +my $mod = 'Dist::Metadata::Dir'; +eval "require $mod" or die $@; + +# required_attribute +# extract_into +{ + my $att = 'dir'; + is($mod->required_attribute, $att, "'$att' attribute required"); + my $ex = exception { $mod->new() }; + like($ex, qr/'$att' parameter required/, "new dies without '$att'"); + + $ex = exception { $mod->new(dir => $tmpdir)->extract_into($tmpdir) }; + like( $ex, qr/A directory doesn't need to be extracted/, 'no extraction' ); +} + +# default_file_spec + is( $mod->default_file_spec, 'Native', 'default to native file spec for dir' ); + +# dir +# file_content +# find_files +# physical_directory + +{ + # with no root dir + my $path = dir( qw(corpus noroot) ); + my $dir = $path->stringify; + my $dist = new_ok( $mod, [ dir => $dir ] ); + + test_phys_dir($dist, $dir, $path); + + my @files = ( + file( qw(lib Dist Metadata Test NoRoot PM.pm) )->stringify, + file( qw(lib Dist Metadata Test NoRoot.pm) )->stringify, + 'README' + ); + + # no root, same as below + is_deeply([sort $dist->find_files], [sort @files], 'all files listed (full paths)'); + # root stripped + is_deeply([sort $dist->list_files], [sort @files], 'all files listed (no root)'); +} +# with root dir +{ + my $path = dir( qw(corpus subdir) ); + my $dir = $path->stringify; + my $dist = new_ok( $mod, [ dir => $dir ] ); + + test_phys_dir($dist, $dir, $path->subdir($dist->root)); + + my @files = ( + file( qw(lib Dist Metadata Test SubDir PM.pm) )->stringify, + file( qw(lib Dist Metadata Test SubDir.pm) )->stringify, + 'README' + ); + + # root present + is_deeply([sort $dist->find_files], [sort map { file($dist->root, $_)->stringify } @files], 'all files listed (full paths)'); + # root stripped + is_deeply([sort $dist->list_files], [sort @files], 'all files listed (no root)'); +} + +# determine_name_and_version +{ + my %nv = (name => 'Dist-Metadata-Test-MetaFile', version => 2.2); + my $dir = dir( 'corpus', join('-', @nv{qw(name version)}) ); + my $dist = new_ok( $mod, [ dir => $dir ] ); + + ok(!exists($dist->{$_}), "no dist $_" ) + for keys %nv; + + $dist->determine_name_and_version; + + is($dist->$_, $nv{$_}, "determined dist $_" ) + for keys %nv; +} + +done_testing; + +sub test_phys_dir { + my ($dist, $dir, $subroot) = @_; + $subroot = $subroot->absolute; + + is( $dist->dir, $dir, 'dir attribute from constructor arg' ); + is( $dist->physical_directory, $subroot, 'dir + root' ); + + is_deeply( + [$dist->physical_directory('README')], + [$subroot, $subroot->file('README')], + 'physical directory with adjusted file' + ); + + is( + $dist->file_content('README'), + qq[This "dist" is for testing Dist::Metadata.\n], + 'file content' + ); + + like( + exception { $dist->file_content('missing.file') }, + qr{Failed to open file 'corpus.+\w+.+missing\.file':}, + 'die on missing file' + ); + +} diff --git a/t/dists.t b/t/dists.t new file mode 100644 index 0000000..aa79260 --- /dev/null +++ b/t/dists.t @@ -0,0 +1,219 @@ +use strict; +use warnings; +use Test::More 0.96; +use Path::Class 0.24 qw(file); + +my $mod = 'Dist::Metadata'; +eval "require $mod" or die $@; +$Dist::Metadata::VERSION ||= 0; # quiet warnings + +# we may need to prepend $FindBin::Bin +my $root = 'corpus'; +my $structs = do "$root/structs.pl"; + +# NOTE: Portability tests report issues with file names being long +# and containing periods, so there could be issues... + +foreach my $test ( + [ + [ + metafile => + 'Dist-Metadata-Test-MetaFile-2.2', + ], + { + name => 'Dist-Metadata-Test-MetaFile', + version => '2.2', + provides => { + 'Dist::Metadata::Test::MetaFile' => { + file => 'lib/Dist/Metadata/Test/MetaFile.pm', + version => '2.1', + }, + 'Dist::Metadata::Test::MetaFile::PM' => { + file => 'lib/Dist/Metadata/Test/MetaFile/PM.pm', + version => '2.0', + }, + }, + }, + ], + [ + [ + metafile_incomplete => + 'Dist-Metadata-Test-MetaFile-Incomplete-2.1', + ], + { + name => 'Dist-Metadata-Test-MetaFile-Incomplete', + version => '2.1', + provides => { + 'Dist::Metadata::Test::MetaFile::Incomplete' => { + file => 'lib/Dist/Metadata/Test/MetaFile/Incomplete.pm', + version => '2.1', + }, + }, + }, + ], + [ + [ + nometafile => + 'Dist-Metadata-Test-NoMetaFile-0.1', + ], + { + name => 'Dist-Metadata-Test-NoMetaFile', + version => '0.1', + provides => { + 'Dist::Metadata::Test::NoMetaFile' => { + file => 'lib/Dist/Metadata/Test/NoMetaFile.pm', + version => '0.1', + }, + 'Dist::Metadata::Test::NoMetaFile::PM' => { + file => 'lib/Dist/Metadata/Test/NoMetaFile/PM.pm', + version => '0.1', + }, + }, + }, + ], + + [ + [ + index_like_pause => 'Dist-Metadata-Test-LikePause-0.1', + ], + { + name => 'Dist-Metadata-Test-LikePause', + version => '0.1', + provides => { + 'Dist::Metadata::Test::LikePause' => { + file => 'lib/Dist/Metadata/Test/LikePause.pm', + version => '0.1', + }, + }, + }, + ], + + [ + [ + index_like_pause => 'Dist-Metadata-Test-LikePause-0.1', + ], + { + name => 'Dist-Metadata-Test-LikePause', + version => '0.1', + provides => { + 'Dist::Metadata::Test::LikePause' => { + file => 'lib/Dist/Metadata/Test/LikePause.pm', + version => '0.1', + }, + 'ExtraPackage' => { + file => 'lib/Dist/Metadata/Test/LikePause.pm', + version => '0.2', + }, + }, + }, + { + # this we should find the Extra (inner) package + include_inner_packages => 1, + }, + ], + + [ + [ + nometafile_dev_release => + 'Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1', + ], + { + name => 'Dist-Metadata-Test-NoMetaFile-DevRelease', + version => '0.1_1', + provides => { + 'Dist::Metadata::Test::NoMetaFile::DevRelease' => { + file => 'lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm', + version => '0.1_1', + }, + }, + }, + ], + [ + [ + subdir => + 'Dist-Metadata-Test-SubDir-1.5', + 'subdir', + ], + { + name => 'Dist-Metadata-Test-SubDir', + version => '1.5', + provides => { + 'Dist::Metadata::Test::SubDir' => { + file => 'lib/Dist/Metadata/Test/SubDir.pm', + version => '1.1', + }, + 'Dist::Metadata::Test::SubDir::PM' => { + file => 'lib/Dist/Metadata/Test/SubDir/PM.pm', + version => '1.0', + }, + }, + }, + ], + [ + 'noroot', + { + # can't guess name/version without formatted file name or root dir + name => 'noroot', # modified in loop + version => '0', + provides => { + 'Dist::Metadata::Test::NoRoot' => { + file => 'lib/Dist/Metadata/Test/NoRoot.pm', + version => '3.3', + }, + 'Dist::Metadata::Test::NoRoot::PM' => { + file => 'lib/Dist/Metadata/Test/NoRoot/PM.pm', + version => '3.25', + }, + }, + }, + ], +){ + my ( $dists, $exp, $opts ) = @$test; + $exp->{package_versions} = do { + my $p = $exp->{provides}; + +{ map { ($_ => $p->{$_}{version}) } keys %$p }; + }; + + $dists = [ ($dists) x 2 ] + unless ref $dists; + + my ($key, $file, $dir) = @$dists; + + $dir ||= $file; + $_ = "corpus/$_" for ($file, $dir); + + $_ = file($root, $_)->stringify + for @$dists; + + + + foreach my $args ( + [file => "$file.tar.gz"], + [file => "$file.zip"], + [dir => $dir], + [struct => { files => $structs->{$key} }], + ){ + + push @{ $args }, %{ $opts || {} }; + + my $dm = new_ok( $mod, $args ); + # minimal name can be determined from file or dir but not struct + $exp->{name} = Dist::Metadata::UNKNOWN() if $key eq 'noroot' && $args->[0] eq 'struct'; + + # FIXME: perl 5.6.2 weirdness: http://www.cpantesters.org/cpan/report/4297a762-a314-11e0-b62c-be5be1de4735 + # # Failed test 'verify corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm for dir corpus/noroot' + # # at t/dists.t line 124. + # # Structures begin differing at: + # # $got = HASH(0x11c22d0) + # # $expected = undef + is_deeply( $dm->$_, $exp->{$_}, "verify $_ for @$args" ) || dump_if_automated([$dm, $_, $exp]) + for keys %$exp; + } +} + +done_testing; + +sub dump_if_automated { + diag(explain(@_)) + if $ENV{AUTOMATED_TESTING}; +} diff --git a/t/file_spec.t b/t/file_spec.t new file mode 100644 index 0000000..a8c0ab3 --- /dev/null +++ b/t/file_spec.t @@ -0,0 +1,32 @@ +use strict; +use warnings; +use Test::More 0.96; + +my $mod = 'Dist::Metadata::Struct'; +eval "require $mod" or die $@; + +# all these translate into "Native" +foreach my $test ( + [ '' => 'Native' ], + [ qw( File::Spec Native ) ], + [ qw( File::Spec::Native Native ) ], + [ qw( Native Native ) ], + [ qw( Win32 Win32 ) ], + [ qw( File::Spec::Win32 Win32 ) ], +) { + my ( $spec, $exp ) = @$test; + my $dist = new_ok( $mod, [ file_spec => $spec, files => {} ] ); + is( $dist->file_spec, $exp, "spec '$spec' => '$exp'" ); +} + +# test using default File::Spec +{ + my $dist = new_ok( $mod, [ file_spec => '', files => { + README => 'read me', + 'Module.pm' => \"package Some::Module;\nour \$VERSION = 2;", + } ] ); + is_deeply( $dist->determine_packages, {'Some::Module' => { file => 'Module.pm', version => 2 }}, + 'found package in root' ); +} + +done_testing; diff --git a/t/load_meta.t b/t/load_meta.t new file mode 100644 index 0000000..e19fcdc --- /dev/null +++ b/t/load_meta.t @@ -0,0 +1,55 @@ +use strict; +use warnings; +use Test::More 0.96; +use Test::MockObject 1.09; + +my ( $default, $loaded, $created ) = (-1) x 3; + +Test::MockObject->new->fake_module('CPAN::Meta', + VERSION => sub { 2 }, + new => sub { bless { %{ $_[1] } }, $_[0] }, + create => sub { $created = $_[1]; shift->new(@_) }, + #as_struct => sub { +{ %{ $_[0] } } }, # unbless + (map { ( $_ => sub { undef } ) } qw(name version provides)), + map { + ( "load_${_}_string" => sub { $loaded = $_[1]; $_[0]->new({loaded => $_[1]}); } ) + } qw(json yaml) +); + +my $mod = 'Dist::Metadata'; +eval "require $mod" or die $@; +$Dist::Metadata::VERSION ||= 0; # quiet warnings + +foreach my $test ( + [ json => j => { 'META.json' => 'j' } ], + [ yaml => y => { 'META.yml' => 'y' } ], + + # usually it's spelled .yml but yaml spec suggests .yaml + [ yaml => y => { 'tar/META.yaml' => 'y' } ], + + # json preferred + [ json => j => { 'tar/META.json' => 'j', 'tar/META.yaml' => 'y' } ], + ) +{ + my ( $type, $content, $files ) = @$test; + my $struct = { files => $files }; + + new_ok( $mod, [ struct => $struct, determine_packages => 0 ] )->load_meta; + is( $loaded, $content, "loaded $type" ); + is( $created, $default, "loaded not created" ); +} + +reset_vars(); + +new_ok( $mod, + [ struct => { files => { 'README' => 'nevermind' } }, determine_packages => 0 ] +)->load_meta; + +is( $loaded, $default, 'meta file not found, not loaded' ); +is( ref($created), 'HASH', 'hash passed to create()' ); + +done_testing; + +sub reset_vars { + ( $loaded, $created ) = ($default) x 2; +} diff --git a/t/module_info.t b/t/module_info.t new file mode 100644 index 0000000..1fb8bc3 --- /dev/null +++ b/t/module_info.t @@ -0,0 +1,126 @@ +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; +use Path::Class; + +my $mod = 'Dist::Metadata'; +eval "require $mod" or die $@; + +test_module_info( + [file => file(qw(corpus Dist-Metadata-Test-NoMetaFile-0.1.tar.gz))->stringify], + { + 'Dist::Metadata::Test::NoMetaFile' => { + file => 'lib/Dist/Metadata/Test/NoMetaFile.pm', + version => '0.1', + md5 => 'd4a5a07d20dd1fdad6191d5950287609', + sha1 => '99d1aa7e3dbaa54dc16f178a8a4d2a9ba4d33da2', + sha256 => '7d888a6c321041adbc1225b3ca12ae22ebfccdf221e5e3f0ccb2dec1a9c0a71a', + }, + 'Dist::Metadata::Test::NoMetaFile::PM' => { + file => 'lib/Dist/Metadata/Test/NoMetaFile/PM.pm', + version => '0.1', + md5 => '6e8845e06e7297bc913ebf3f1447c89a', + sha1 => '843ce5cd5443c7ae2792f7b58e069fcab64963c8', + sha256 => 'bc61da45e576a43155fcf296d03f74532bfe3a410f88aeaa75ade9155f67d049', + }, + }, +); + +test_module_info( + [file => file(qw(corpus Dist-Metadata-Test-MetaFile-2.2.zip))->stringify], + { + 'Dist::Metadata::Test::MetaFile' => { + file => 'lib/Dist/Metadata/Test/MetaFile.pm', + version => '2.1', + md5 => '95fe72abee727b584941eda6da89f049', + sha1 => '2c4341d7778a78702e364f2c38c6c97b8410387d', + sha256 => '17dbde0b5b534d2a9ff9d188133da11670e3909ce853ac333aaa6973b348701e', + }, + 'Dist::Metadata::Test::MetaFile::PM' => { + file => 'lib/Dist/Metadata/Test/MetaFile/PM.pm', + version => '2.0', + md5 => '873b2db91af4418020350d3337f6c173', + sha1 => '29553e76693b13b1e3d9f4493ee9d05c4cd4f6fb', + sha256 => '53c79b083cb731e2f642ae409459756a483b6912b99ed61c34edbbfb483ea7d1', + }, + } +); + +{ + my $args = [ + struct => { + files => { + 'fb/lib/Foo/Bar.pm' => "package Foo::Bar;\nour \$VERSION = 13;\n", + 'fb/README.txt' => "anything\n", + } + } + ]; + my $exp = { + 'Foo::Bar' => { + file => 'lib/Foo/Bar.pm', + version => '13', + md5 => '8642ef750b6ca0d9c9afe5db4174e009', + sha1 => '2a4899cefacd1defd114731fec0e58c747eb9471', + sha256 => '368e2f18d80a866537153885807ddf6e0733168b683b0a7ecac6d257943ac894', + }, + }; + + test_module_info($args, $exp); + + my $dm = new_ok($mod => $args); + my $provides = { + 'Who::Cares' => { + file => 'README.txt', + version => 0, + }, + }; + + # specify our own 'provides' + my $mi = $dm->module_info({digest => ['MD5', 'SHA-256'], provides => $provides}); + + # use official names + my $checksums = { + 'MD5' => 'f5b1321af715fbd4866590170ddbe8f6', + 'SHA-256' => 'ce32b18ae7f79e70f7cde4cf6077ae8b4195044307a78a4ea8761ddfedf9badc', + }; + + @{ $provides->{'Who::Cares'} }{ keys %$checksums } = values %$checksums; + + is_deeply $provides, $mi, 'module info with official checksum names'; +} + +done_testing; + +sub test_module_info { + my ($args, $info) = @_; + my $dm = new_ok($mod => $args); + + my $p = $dm->provides; + { + my $m = $dm->module_info; + is_deeply $p, $m, 'provides and module_info have the same'; + is_deeply limit_keys($info), $m, 'sanity check - no checksums'; + } + + foreach my $checksums ( + 'md5', + ['sha1'], + [qw(md5 sha256)], + ){ + is_deeply limit_keys($info, $checksums), $dm->module_info({checksum => $checksums}); + } +} + +sub limit_keys { + my $hash = { %{ shift() } }; + my @keys = map { ref($_) eq 'ARRAY' ? @$_ : $_ } (qw(file version), @_); + + foreach my $mod ( keys %$hash ){ + my $info = delete $hash->{ $mod }; + my $new = $hash->{ $mod } = {}; + @$new{ @keys } = @$info{ @keys }; + } + + return $hash; +} diff --git a/t/no_index.t b/t/no_index.t new file mode 100644 index 0000000..0443244 --- /dev/null +++ b/t/no_index.t @@ -0,0 +1,86 @@ +use strict; +use warnings; +use Test::More 0.96; +use Path::Class qw( foreign_file ); + +my $mod = 'Dist::Metadata'; +eval "require $mod" or die $@; +$Dist::Metadata::VERSION ||= 0; # quiet warnings + +# specifically test that expected paths are not indexed on various platforms +foreach my $spec ( qw(Unix Win32 Mac) ){ + my $dm = new_ok($mod, [struct => { + file_spec => $spec, + files => { + README => 'nevermind', + foreign_file($spec => qw(lib Mod Name.pm)) => "package Mod::Name;\nour \$VERSION = 0.11;", + foreign_file($spec => qw(inc No.pm)) => "package No;\nour \$VERSION = 0.11;", + foreign_file($spec => qw(t lib YU.pm)) => "package YU;\nour \$VERSION = 0.11;", + } + }]); + + is $dm->dist->file_spec, $spec, "dist faking file spec: $spec"; + + is_deeply + [sort $dm->dist->perl_files], + [sort grep { !/README/ } keys %{ $dm->dist->{files} }], + 'perl files listed'; + + is_deeply + $dm->package_versions, + {'Mod::Name' => '0.11'}, + 't and inc not indexed'; + + is_deeply + $dm->determine_packages, + {'Mod::Name' => {file => 'lib/Mod/Name.pm', version => '0.11'}}, + 'determined package with translated path'; +} + +sub indexed_ok { + my ($files, $exp, $desc) = @_; + + my $dm = new_ok($mod, [struct => { + file_spec => 'Unix', + files => $files, + }]); + + is_deeply $dm->package_versions, $exp, $desc; +} + +sub _pkg { + my ($name, $version) = @_; + return "package $name;\nour \$VERSION = 0.$version;\n"; +} + + +indexed_ok + { + 'META.json' => <<JSON, +{ + "name": "X", + "version": "1.1", + "no_index": { + "directory": [ "notthis" ] + } +} +JSON + 'lib/A/B.pm' => _pkg('A::B' => 2), + 't/T.pm' => _pkg('T' => 3), + 'xt/XT.pm' => _pkg('XT' => 4), + 'inc/Inc.pm' => _pkg('Inc' => 5), + 'local/Local.pm' => _pkg('Local' => 6), + 'perl5/Perl5.pm' => _pkg('Perl5' => 7), + 'fatlib/FatLib.pm' => _pkg('FatLib' => 8), + 'Root.pm' => _pkg('Some::Root' => 9), + 'notthis/More.pm' => _pkg('Some::More' => 10), + 'butthis/Moar.pm' => _pkg('Moar' => 11), + }, + { + 'A::B' => '0.2', + 'Some::Root' => '0.9', + 'Moar' => '0.11', + }, + q[Merge 'always' no_index dirs with specified no_index dirs]; + +done_testing; diff --git a/t/package_versions.t b/t/package_versions.t new file mode 100644 index 0000000..8af1be9 --- /dev/null +++ b/t/package_versions.t @@ -0,0 +1,55 @@ +use strict; +use warnings; +use Test::More 0.96; + +my $mod = 'Dist::Metadata'; +eval "require $mod" or die $@; + +{ + foreach my $test ( + [ + { + buzzwords => { + file => 'lib/buzzwords.pm', + version => '0.1', + }, + }, + { + buzzwords => '0.1', + } + ], + [ + { + fulfillment_issues => { + file => 'lib/fulfillment_issues.pm' + } + }, + { + fulfillment_issues => undef, + } + ], + [ + { + 'Design::Patterns' => { + file => 'lib/Design/Patterns.pm', + version => 0.2 + }, + 'Paradigm::Shift' => { + file => 'lib/Paradigm/Shift.pm', + version => 'v1.3.5', + } + }, + { + 'Design::Patterns' => 0.2, + 'Paradigm::Shift' => 'v1.3.5', + }, + ], + ){ + + my ($provides, $exp) = @$test; + + is_deeply($mod->package_versions($provides), $exp, 'package_versions'); + } +} + +done_testing; diff --git a/t/struct.t b/t/struct.t new file mode 100644 index 0000000..7eb265c --- /dev/null +++ b/t/struct.t @@ -0,0 +1,69 @@ +use strict; +use warnings; +use Test::More 0.96; +use Test::Fatal; +use Test::MockObject 1.09 (); +use Path::Class 0.24 qw(file dir); + +my $mod = 'Dist::Metadata::Struct'; +eval "require $mod" or die $@; + +# required_attribute +{ + my $att = 'files'; + is( $mod->required_attribute, $att, "'$att' attribute required" ); + my $ex = exception { $mod->new() }; + like( $ex, qr/'$att' parameter required/, "new dies without '$att'" ); +} + +# don't create a dependency on IO::String or IO::Scalar for this simple test. +my $io = Test::MockObject->new({}); +$io->mock(getline => sub { 'read me' }); + +# file_content +# find_files +foreach my $test ( + [ string => 'read me' ], + [ scalar_ref => \'read me' ], + [ io => $io ], +) { + my ( $type, $content ) = @$test; + my $dist = new_ok( $mod, [ files => { README => $content } ] ); + is( $dist->file_content('README'), 'read me', "content returned for $type" ); + is_deeply( [ $dist->find_files ], ['README'], 'all files listed' ); +} + +{ + my $dist = new_ok( $mod, [ files => { 'root/README' => 'please', 'root/SECRET' => 'shhhh' } ] ); + { + my $dir = $dist->physical_directory('README'); + ok( -d $dir, 'phyiscal directory exists' ); + } + my @dir_and_files = $dist->physical_directory('README'); + is(scalar @dir_and_files, 2, 'list returned'); + is($dir_and_files[1], file($dir_and_files[0], 'README'), 'full path to file'); + ok(-e $dir_and_files[1], 'extracted file exists'); +} + +# default_file_spec +# file_spec +# find_files +# determine_packages +{ + my $defspec = 'Unix'; + my $spec = 'Win32'; + my $dist = new_ok($mod, [file_spec => $spec, files => { + README => 'nevermind', + 'lib\\Mod\\Name.pm' => "package Mod::Name;\nour \$VERSION = 0.11;" + }]); + is( $dist->default_file_spec, $defspec, "struct defaults to $defspec" ); + is( $dist->file_spec, $spec, "struct has custom spec: $spec" ); + + # TODO: should paths always come out in unix format? perhaps not if you specify an alternate... + is_deeply( [sort $dist->find_files], ['README', 'lib\\Mod\\Name.pm'], 'all files listed' ); + + is_deeply( $dist->determine_packages, {'Mod::Name' => {file => 'lib/Mod/Name.pm', version => '0.11'}}, + 'determined package with translated path' ); +} + +done_testing; @@ -0,0 +1,29 @@ +use strict; +use warnings; +use Test::More 0.96; + +my $mod = 'Dist::Metadata::Tar'; +eval "require $mod" or die $@; + +my $base = 'corpus/Dist-Metadata-Test-NoMetaFile-0.1'; + +# test that instantiating this class directly does not negotiate type +new_ok($mod => [file => "$base.zip"]); + +my $file = "$base.tar.gz"; +my $tar = new_ok($mod => [file => $file]); + +# file_content, and find_files tested in t/archive.t + +# read_archive +isa_ok($tar->read_archive($file), 'Archive::Tar'); + +# tar +{ + my $warning; + local $SIG{__WARN__} = sub { $warning = $_[0] }; + isa_ok($tar->tar, 'Archive::Tar'); + like($warning, qr/deprecated/, 'tar() works but is deprecated'); +} + +done_testing; @@ -0,0 +1,21 @@ +use strict; +use warnings; +use Test::More 0.96; + +my $mod = 'Dist::Metadata::Zip'; +eval "require $mod" or die $@; + +my $base = 'corpus/Dist-Metadata-Test-NoMetaFile-0.1'; + +# test that instantiating this class directly does not negotiate type +new_ok($mod => [file => "$base.tgz"]); + +my $file = "$base.zip"; +my $zip = new_ok($mod => [file => $file]); + +# file_content, and find_files tested in t/archive.t + +# read_archive +isa_ok($zip->read_archive($file), 'Archive::Zip'); + +done_testing; diff --git a/xt/author/critic.t b/xt/author/critic.t new file mode 100644 index 0000000..d5b4c96 --- /dev/null +++ b/xt/author/critic.t @@ -0,0 +1,12 @@ +#!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(); diff --git a/xt/author/eol.t b/xt/author/eol.t new file mode 100644 index 0000000..6442dbc --- /dev/null +++ b/xt/author/eol.t @@ -0,0 +1,35 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.18 + +use Test::More 0.88; +use Test::EOL; + +my @files = ( + 'lib/Dist/Metadata.pm', + 'lib/Dist/Metadata/Archive.pm', + 'lib/Dist/Metadata/Dir.pm', + 'lib/Dist/Metadata/Dist.pm', + 'lib/Dist/Metadata/Struct.pm', + 'lib/Dist/Metadata/Tar.pm', + 'lib/Dist/Metadata/Zip.pm', + 't/00-compile.t', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/archive.t', + 't/determine.t', + 't/dir.t', + 't/dists.t', + 't/file_spec.t', + 't/load_meta.t', + 't/module_info.t', + 't/no_index.t', + 't/package_versions.t', + 't/struct.t', + 't/tar.t', + 't/zip.t' +); + +eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; +done_testing; diff --git a/xt/author/no-tabs.t b/xt/author/no-tabs.t new file mode 100644 index 0000000..26f32ef --- /dev/null +++ b/xt/author/no-tabs.t @@ -0,0 +1,35 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.14 + +use Test::More 0.88; +use Test::NoTabs; + +my @files = ( + 'lib/Dist/Metadata.pm', + 'lib/Dist/Metadata/Archive.pm', + 'lib/Dist/Metadata/Dir.pm', + 'lib/Dist/Metadata/Dist.pm', + 'lib/Dist/Metadata/Struct.pm', + 'lib/Dist/Metadata/Tar.pm', + 'lib/Dist/Metadata/Zip.pm', + 't/00-compile.t', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/archive.t', + 't/determine.t', + 't/dir.t', + 't/dists.t', + 't/file_spec.t', + 't/load_meta.t', + 't/module_info.t', + 't/no_index.t', + 't/package_versions.t', + 't/struct.t', + 't/tar.t', + 't/zip.t' +); + +notabs_ok($_) foreach @files; +done_testing; diff --git a/xt/author/pod-spell.t b/xt/author/pod-spell.t new file mode 100644 index 0000000..a862583 --- /dev/null +++ b/xt/author/pod-spell.t @@ -0,0 +1,32 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006008 +use Test::Spelling 0.12; +use Pod::Wordlist; + + +add_stopwords(<DATA>); +all_pod_files_spelling_ok( qw( bin lib ) ); +__DATA__ +Randy +Stauner +rwstauner +David +Steinbrunner +dsteinbrunner +Jeffrey +Ryan +Thalhammer +thaljef +Sawyer +xsawyerx +lib +Dist +Metadata +Archive +Dir +Struct +Tar +Zip diff --git a/xt/release/cpan-changes.t b/xt/release/cpan-changes.t new file mode 100644 index 0000000..8e6e413 --- /dev/null +++ b/xt/release/cpan-changes.t @@ -0,0 +1,11 @@ +#!perl + +use strict; +use warnings; + +use Test::More 0.96 tests => 2; +use_ok('Test::CPAN::Changes'); +subtest 'changes_ok' => sub { + changes_file_ok('Changes'); +}; +done_testing(); diff --git a/xt/release/dist-manifest.t b/xt/release/dist-manifest.t new file mode 100644 index 0000000..a567fb7 --- /dev/null +++ b/xt/release/dist-manifest.t @@ -0,0 +1,8 @@ +#!perl + +use Test::More; + +eval "use Test::DistManifest"; +plan skip_all => "Test::DistManifest required for testing the manifest" + if $@; +manifest_ok(); diff --git a/xt/release/distmeta.t b/xt/release/distmeta.t new file mode 100644 index 0000000..c2280dc --- /dev/null +++ b/xt/release/distmeta.t @@ -0,0 +1,6 @@ +#!perl +# This file was automatically generated by Dist::Zilla::Plugin::MetaTests. + +use Test::CPAN::Meta; + +meta_yaml_ok(); diff --git a/xt/release/kwalitee.t b/xt/release/kwalitee.t new file mode 100644 index 0000000..bcbce84 --- /dev/null +++ b/xt/release/kwalitee.t @@ -0,0 +1,9 @@ +# this test was generated with Dist::Zilla::Plugin::Test::Kwalitee 2.11 +use strict; +use warnings; +use Test::More 0.88; +use Test::Kwalitee 1.21 'kwalitee_ok'; + +kwalitee_ok(); + +done_testing; diff --git a/xt/release/meta-json.t b/xt/release/meta-json.t new file mode 100644 index 0000000..5ddad73 --- /dev/null +++ b/xt/release/meta-json.t @@ -0,0 +1,4 @@ +#!perl + +use Test::CPAN::Meta::JSON; +meta_json_ok(); diff --git a/xt/release/minimum-version.t b/xt/release/minimum-version.t new file mode 100644 index 0000000..5f3cae8 --- /dev/null +++ b/xt/release/minimum-version.t @@ -0,0 +1,8 @@ +#!perl + +use Test::More; + +eval "use Test::MinimumVersion"; +plan skip_all => "Test::MinimumVersion required for testing minimum versions" + if $@; +all_minimum_version_ok( qq{5.008} ); diff --git a/xt/release/mojibake.t b/xt/release/mojibake.t new file mode 100644 index 0000000..390c632 --- /dev/null +++ b/xt/release/mojibake.t @@ -0,0 +1,12 @@ +#!perl + +use strict; +use warnings qw(all); + +use Test::More; + +## no critic (ProhibitStringyEval, RequireCheckingReturnValueOfEval) +eval q(use Test::Mojibake); +plan skip_all => q(Test::Mojibake required for source encoding testing) if $@; + +all_files_encoding_ok(); diff --git a/xt/release/pod-coverage.t b/xt/release/pod-coverage.t new file mode 100644 index 0000000..66b3b64 --- /dev/null +++ b/xt/release/pod-coverage.t @@ -0,0 +1,7 @@ +#!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' }); diff --git a/xt/release/pod-linkcheck.t b/xt/release/pod-linkcheck.t new file mode 100644 index 0000000..00602db --- /dev/null +++ b/xt/release/pod-linkcheck.t @@ -0,0 +1,20 @@ +#!perl + +use strict; +use warnings; +use Test::More; + +foreach my $env_skip ( qw( + SKIP_POD_LINKCHECK +) ){ + plan skip_all => "\$ENV{$env_skip} is set, skipping" + if $ENV{$env_skip}; +} + +eval "use Test::Pod::LinkCheck"; +if ( $@ ) { + plan skip_all => 'Test::Pod::LinkCheck required for testing POD'; +} +else { + Test::Pod::LinkCheck->new->all_pod_ok; +} diff --git a/xt/release/pod-syntax.t b/xt/release/pod-syntax.t new file mode 100644 index 0000000..f0468f1 --- /dev/null +++ b/xt/release/pod-syntax.t @@ -0,0 +1,6 @@ +#!perl +# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. +use Test::More; +use Test::Pod 1.41; + +all_pod_files_ok(); diff --git a/xt/release/synopsis.t b/xt/release/synopsis.t new file mode 100644 index 0000000..3e03427 --- /dev/null +++ b/xt/release/synopsis.t @@ -0,0 +1,5 @@ +#!perl + +use Test::Synopsis; + +all_synopsis_ok(); diff --git a/xt/release/test-version.t b/xt/release/test-version.t new file mode 100644 index 0000000..9bccdf0 --- /dev/null +++ b/xt/release/test-version.t @@ -0,0 +1,22 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::Version 0.003001 +use Test::Version; + +my @imports = ( '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; diff --git a/xt/release/unused-vars.t b/xt/release/unused-vars.t new file mode 100644 index 0000000..e601076 --- /dev/null +++ b/xt/release/unused-vars.t @@ -0,0 +1,14 @@ +#!perl + +use Test::More 0.96 tests => 1; +eval { require Test::Vars }; + +SKIP: { + skip 1 => 'Test::Vars required for testing for unused vars' + if $@; + Test::Vars->import; + + subtest 'unused vars' => sub { +all_vars_ok(); + }; +}; |