summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-04-29 03:17:05 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-04-29 03:17:05 +0000
commit2ca9db53e3e8164ecf0c95bf93fa289019e1b92c (patch)
tree5cc19083935ae762133417625e80a5329e36d8ee
downloadDist-Metadata-tarball-2ca9db53e3e8164ecf0c95bf93fa289019e1b92c.tar.gz
-rw-r--r--Changes124
-rw-r--r--LICENSE379
-rw-r--r--MANIFEST89
-rw-r--r--MANIFEST.SKIP10
-rw-r--r--META.json858
-rw-r--r--META.yml636
-rw-r--r--Makefile.PL105
-rw-r--r--README15
-rw-r--r--corpus/Dist-Metadata-Test-LikePause-0.1.tar.gzbin0 -> 341 bytes
-rw-r--r--corpus/Dist-Metadata-Test-LikePause-0.1.zipbin0 -> 665 bytes
-rw-r--r--corpus/Dist-Metadata-Test-LikePause-0.1/README1
-rw-r--r--corpus/Dist-Metadata-Test-LikePause-0.1/lib/Dist/Metadata/Test/LikePause.pm18
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gzbin0 -> 876 bytes
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2.zipbin0 -> 2726 bytes
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2/META.json39
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2/META.yml29
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2/README1
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile.pm13
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-2.2/lib/Dist/Metadata/Test/MetaFile/PM.pm12
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gzbin0 -> 806 bytes
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zipbin0 -> 2400 bytes
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.json27
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/META.yml20
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/README1
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/inc/NotThis.pm11
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/lib/Dist/Metadata/Test/MetaFile/Incomplete.pm12
-rw-r--r--corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1/t/lib/Never.pm12
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gzbin0 -> 333 bytes
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-0.1.zipbin0 -> 888 bytes
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-0.1/README1
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile.pm12
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-0.1/lib/Dist/Metadata/Test/NoMetaFile/PM.pm12
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gzbin0 -> 298 bytes
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zipbin0 -> 647 bytes
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/README1
-rw-r--r--corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1/lib/Dist/Metadata/Test/NoMetaFile/DevRelease.pm12
-rw-r--r--corpus/Dist-Metadata-Test-SubDir-1.5.tar.gzbin0 -> 334 bytes
-rw-r--r--corpus/Dist-Metadata-Test-SubDir-1.5.zipbin0 -> 840 bytes
-rwxr-xr-xcorpus/make_dists94
-rw-r--r--corpus/noroot.tar.gzbin0 -> 319 bytes
-rw-r--r--corpus/noroot.zipbin0 -> 661 bytes
-rw-r--r--corpus/noroot/README1
-rw-r--r--corpus/noroot/lib/Dist/Metadata/Test/NoRoot.pm12
-rw-r--r--corpus/noroot/lib/Dist/Metadata/Test/NoRoot/PM.pm12
-rw-r--r--corpus/structs.pl228
-rw-r--r--corpus/subdir/Dist-Metadata-Test-SubDir-1.5/README1
-rw-r--r--corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir.pm12
-rw-r--r--corpus/subdir/Dist-Metadata-Test-SubDir-1.5/lib/Dist/Metadata/Test/SubDir/PM.pm12
-rw-r--r--dist.ini47
-rw-r--r--lib/Dist/Metadata.pm677
-rw-r--r--lib/Dist/Metadata/Archive.pm171
-rw-r--r--lib/Dist/Metadata/Dir.pm186
-rw-r--r--lib/Dist/Metadata/Dist.pm623
-rw-r--r--lib/Dist/Metadata/Struct.pm131
-rw-r--r--lib/Dist/Metadata/Tar.pm99
-rw-r--r--lib/Dist/Metadata/Zip.pm95
-rw-r--r--t/00-compile.t60
-rw-r--r--t/00-report-prereqs.dd68
-rw-r--r--t/00-report-prereqs.t184
-rw-r--r--t/archive.t91
-rw-r--r--t/determine.t129
-rw-r--r--t/dir.t115
-rw-r--r--t/dists.t219
-rw-r--r--t/file_spec.t32
-rw-r--r--t/load_meta.t55
-rw-r--r--t/module_info.t126
-rw-r--r--t/no_index.t86
-rw-r--r--t/package_versions.t55
-rw-r--r--t/struct.t69
-rw-r--r--t/tar.t29
-rw-r--r--t/zip.t21
-rw-r--r--xt/author/critic.t12
-rw-r--r--xt/author/eol.t35
-rw-r--r--xt/author/no-tabs.t35
-rw-r--r--xt/author/pod-spell.t32
-rw-r--r--xt/release/cpan-changes.t11
-rw-r--r--xt/release/dist-manifest.t8
-rw-r--r--xt/release/distmeta.t6
-rw-r--r--xt/release/kwalitee.t9
-rw-r--r--xt/release/meta-json.t4
-rw-r--r--xt/release/minimum-version.t8
-rw-r--r--xt/release/mojibake.t12
-rw-r--r--xt/release/pod-coverage.t7
-rw-r--r--xt/release/pod-linkcheck.t20
-rw-r--r--xt/release/pod-syntax.t6
-rw-r--r--xt/release/synopsis.t5
-rw-r--r--xt/release/test-version.t22
-rw-r--r--xt/release/unused-vars.t14
88 files changed, 6436 insertions, 0 deletions
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..311bbe1
--- /dev/null
+++ b/Changes
@@ -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
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..c18c588
--- /dev/null
+++ b/LICENSE
@@ -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);
diff --git a/README b/README
new file mode 100644
index 0000000..cf51a34
--- /dev/null
+++ b/README
@@ -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
new file mode 100644
index 0000000..beebbc6
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-LikePause-0.1.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-LikePause-0.1.zip b/corpus/Dist-Metadata-Test-LikePause-0.1.zip
new file mode 100644
index 0000000..42bfd87
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-LikePause-0.1.zip
Binary files differ
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
new file mode 100644
index 0000000..5e0b38a
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-MetaFile-2.2.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-MetaFile-2.2.zip b/corpus/Dist-Metadata-Test-MetaFile-2.2.zip
new file mode 100644
index 0000000..31e9509
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-MetaFile-2.2.zip
Binary files differ
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
new file mode 100644
index 0000000..0d77ac6
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip
new file mode 100644
index 0000000..cdf4b36
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-MetaFile-Incomplete-2.1.zip
Binary files differ
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
new file mode 100644
index 0000000..b90010a
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip
new file mode 100644
index 0000000..11049e0
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-NoMetaFile-0.1.zip
Binary files differ
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
new file mode 100644
index 0000000..ba91360
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip
new file mode 100644
index 0000000..0f3e19e
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-NoMetaFile-DevRelease-0.1_1.zip
Binary files differ
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
new file mode 100644
index 0000000..ba56dbb
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-SubDir-1.5.tar.gz
Binary files differ
diff --git a/corpus/Dist-Metadata-Test-SubDir-1.5.zip b/corpus/Dist-Metadata-Test-SubDir-1.5.zip
new file mode 100644
index 0000000..df48916
--- /dev/null
+++ b/corpus/Dist-Metadata-Test-SubDir-1.5.zip
Binary files differ
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
new file mode 100644
index 0000000..e549848
--- /dev/null
+++ b/corpus/noroot.tar.gz
Binary files differ
diff --git a/corpus/noroot.zip b/corpus/noroot.zip
new file mode 100644
index 0000000..50ef6f4
--- /dev/null
+++ b/corpus/noroot.zip
Binary files differ
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;
diff --git a/t/dir.t b/t/dir.t
new file mode 100644
index 0000000..81c8a64
--- /dev/null
+++ b/t/dir.t
@@ -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;
diff --git a/t/tar.t b/t/tar.t
new file mode 100644
index 0000000..1c863cb
--- /dev/null
+++ b/t/tar.t
@@ -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;
diff --git a/t/zip.t b/t/zip.t
new file mode 100644
index 0000000..59d82d4
--- /dev/null
+++ b/t/zip.t
@@ -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();
+ };
+};