summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes336
-rw-r--r--INSTALL43
-rw-r--r--LICENSE207
-rw-r--r--MANIFEST35
-rw-r--r--META.json650
-rw-r--r--META.yml474
-rw-r--r--Makefile.PL73
-rw-r--r--README.md239
-rw-r--r--dist.ini13
-rw-r--r--lib/Devel/StackTrace.pm531
-rw-r--r--lib/Devel/StackTrace/Frame.pm216
-rw-r--r--t/00-compile.t52
-rw-r--r--t/00-report-prereqs.dd46
-rw-r--r--t/00-report-prereqs.t176
-rw-r--r--t/01-basic.t573
-rw-r--r--t/02-bad-utf8.t40
-rw-r--r--t/03-message.t34
-rw-r--r--t/04-indent.t35
-rw-r--r--t/05-back-compat.t10
-rw-r--r--t/06-dollar-at.t24
-rw-r--r--t/07-no-args.t45
-rw-r--r--t/08-filter-early.t31
-rw-r--r--t/09-skip-frames.t41
-rw-r--r--t/author-eol.t16
-rw-r--r--t/author-no-tabs.t45
-rw-r--r--t/author-pod-spell.t45
-rw-r--r--t/release-cpan-changes.t19
-rw-r--r--t/release-pod-coverage.t43
-rw-r--r--t/release-pod-linkcheck.t28
-rw-r--r--t/release-pod-no404s.t29
-rw-r--r--t/release-pod-syntax.t14
-rw-r--r--t/release-portability.t19
-rw-r--r--t/release-synopsis.t13
-rw-r--r--weaver.ini17
34 files changed, 4212 insertions, 0 deletions
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..3170913
--- /dev/null
+++ b/Changes
@@ -0,0 +1,336 @@
+2.00 2014-11-01
+
+[BACKWARDS INCOMPATIBILITIES]
+
+- The no_refs constructor parameter is now deprecated, and has been replace by
+ a new unsafe_ref_capture parameter that defaults to false, meaning no
+ references are captured by default. Capturing references by default caused
+ too many issues that couldn't be worked around, including running DESTROY
+ blocks multiple times on captured objects in the worst case.
+
+- Removed support for the long-deprecated no_object_refs constructor parameter
+ (deprecated in 2002!).
+
+
+1.34 2014-06-26
+
+- Fixed use of // operator (my use, not Graham's) in previous release.
+
+
+1.33 2014-06-26
+
+- Added a skip_frames option. This causes the stack trace to skip an arbitrary
+ number of frames. Patch by Graham Knopp. PR #5.
+
+
+1.32 2014-05-05
+
+- Added a filter_frames_early option to filter frames before arguments are
+ stringified. Added by Dagfinn Ilmari Mannsåker. PR #4.
+
+
+1.31 2014-01-16
+
+- No code changes, just doc updates, including documenting the as_string()
+ method in Devel::StackTrace::Frame. Requested by Skef. RT #91575.
+
+
+1.30 2012-11-19
+
+- There was an eval which did not first localize $@ and $SIG{__DIE__}. This
+ broke Plack::Middleware::StackTrace (and possibly other tihngs).
+
+
+1.29 2012-11-16
+
+- The Devel::StackTrace->frames() method is now read-write. This allows you to
+ do more complex filtering of frames than is easily possible with the
+ frame_filter argument to the constructor. Patch by David Cantrell.
+
+
+1.28 2012-11-16
+
+- Allow arguments to a trace's as_string method, specifically max_arg_length
+ Patch by Ricardo Signes.
+
+- Added a no_args option to the constructor in 1.26 but forgot to mention it
+ in Changes. Requested by Scott J. Miller. RT #71482.
+
+
+1.27 2011-01-16
+
+- Skip some tests on 5.13.8+ that are no longer relevant because of a change
+ in the Perl core. Reported by Andreas Koenig. RT #64828.
+
+
+1.26 2010-10-15
+
+- The as_string method did not localize $@ and $SIG{__DIE__} before doing an
+ eval. Reported and tested by Marc Mims. RT #61072.
+
+
+1.25 2010-09-06
+
+- Devel::StackTraceFrame was not actually subclassing
+ Devel::StackTrace::Frame. Patch by Tatsuhiko Miyagawa.
+
+
+1.24 2010-09-03
+
+- Version 1.23 was missing a $VERSION assignment. Reported by Sergei
+ Vyshenski.
+
+- Moved the frame object to its own file, and renamed it
+ Devel::StackTrace::Frame. The old package name, Devel::StackTraceFrame, is
+ now a subclass of the new package, to provide a backwards compatibility
+ shim.
+
+
+1.23 2010-08-27
+
+- Added message and indent constructor parameters. Based on a patch by James
+ Laver. RT #59830.
+
+
+1.22 2009-07-15
+
+- Apparently, overload::StrVal on older Perls (5.8.5, but not 5.8.8)
+ tried to call a stringification method if it existed. So now,
+ Devel::StackTrace just uses overload::AddrRef instead, which should
+ always be safe. Reported by Michael Stevens. Fixes RT #47900.
+
+
+1.21 2009-07-01
+
+- Overloaded objects which didn't provide a stringification method
+ cause Devel::StackTrace to die when respect_overload was
+ true. Reported by Laurent Dami. RT #39533.
+
+- Added a frame_filter option which allows for fine-grained control
+ over what frames are included in a trace. Based on (but expanded)
+ from a patch proposed by Florian Ragwitz. RT #47415.
+
+
+1.20 2008-10-25
+
+- The change in 1.15 to object creation broke the no_refs feature,
+ causing references to be stored until the trace's frame objects were
+ created.
+
+* Exception::Class objects are always stringified by calling
+ overload::StrVal().
+
+
+1.1902 2008-07-16
+
+- This release just contains another test fix.
+
+- The new tests for bad utf-8 apparently fail with any Perl before
+ 5.8.8. Reported by Lee Heagney. RT #37702.
+
+
+1.1901 2008-06-13
+
+- This release just contains a test fix.
+
+- The new tests for bad utf-8 fail with Perl 5.8.x where x <=
+ 6. Apparently, utf-8 was just more broken back then. Reported by
+ Andreas Koenig's smokebots.
+
+
+1.19 2008-06-13
+
+- Dropped support for Perl 5.005.
+
+- If a function was in stack trace had been called with invalid utf-8
+ bytes, this could cause stringifying a stack trace to blow up when
+ it tried to stringify that argument. We now catch those (and other)
+ errors and simply put "(bad utf-8)" or "?" in the stringified
+ argument list. Reported by Alex Vandiver.
+
+
+1.18 2008-03-31
+
+- Fix a test failure on Win32. No changes to the non-test code.
+
+
+1.17 2008-03-30
+
+- Added a max_arg_length parameter, which if set causes
+ Devel::StackTrace to truncate long strings when printing out a
+ frame. RT #33519. Patch by Ian Burrell.
+
+
+1.16 2008-02-02
+
+- A test fix for bleadperl. The value of wantarray from caller() needs
+ to be treated as a boolean, as opposed to expecting 0 (vs
+ undef). RT #32583. Patch by Jerry Hedden.
+
+
+1.15 2007-04-28
+
+- Changed how objects are created in order to greatly speed up the
+ constructor. Instead of processing all the stack trace data when the
+ object is first created, this is delayed until it is needed. This
+ was done in order to help speed up Exception::Class. There are cases
+ where code may be throwing many exceptions but never examining the
+ stack traces.
+
+ Here is a representative benchmark of object construction for the
+ old code versus the new code:
+
+ Rate old new
+ old 1764/s -- -76%
+ new 7353/s 317% --
+
+
+1.14 2007-03-16
+
+- Added a few micro-optimizations from Ruslan Zakirov, who is hoping
+ this will ultimately help speed up RT.
+
+
+1.13 2006-04-01
+
+- Add another fix for filename handling in the tests. Tests were
+ giving false failures on Win32 because the tests needed to use
+ File::Spec->canonpath(), just like Devel::StackTrace does
+ internally.
+
+
+1.12 2005-09-30
+
+- Newer versions of Perl use Unix-style filenames when reporting the
+ filename in caller(), which breaks Exception::Class tests on other
+ platforms, and is just kind of funky. This module now calls
+ File::Spec->canonpath() to clean up the filename in each frame.
+ Reported by Garret Goebel.
+
+
+1.11 2004-04-12
+
+- No code changes, just switching to including a Makefile.PL that uses
+ ExtUtils::MakeMaker instead of one that sneakily uses Module::Build.
+ Requested by Perrin Harkins.
+
+
+1.10 2004-03-10
+
+- Silence a warning from the test code if Exception::Class isn't
+ installed. Reported by Stefano Ruberti.
+
+- Localize $@ to avoid overwriting a previously set $@ while creating
+ a Devel::StackTrace object. This caused a test failure in the
+ Exception::Class tests when run with Perl 5.6.1, but not with 5.8.3.
+ I don't really know how to test for it outside of Exception::Class.
+ Reported by Jesse Erlbaum.
+
+
+1.09 2004-02-26
+
+- The overload workaround blows up if a DBI handle is anywhere in the
+ stack, because of a bad interaction between overload::Overloaded and
+ DBI's custom dispatching. This release works around that.
+
+
+1.08 2004-02-23
+
+- Some tests failed on Win32 because they were hardcoded to expect a
+ file name with forward slashes. Reported by Steve Hay.
+
+
+1.07 2004-02-21
+
+- This release includes a change to the overload handling that is
+ necessary for cooperation with Exception::Class.
+
+
+1.06 2004-02-21
+
+- Devel::StackTrace now uses overload::StrVal() to get the underlying
+ string value of an overloaded object when creating a stack frame for
+ display. This can be turned off by setting respect_overload to a
+ true value. Suggested by Matt Sisk.
+
+
+1.05 2004-02-17
+
+- Devel::StackTrace incorrectly reported that arguments were being
+ passed to eval blocks (which isn't possible). Reported by Mark
+ Dedlow.
+
+
+1.04 2003-09-25
+
+- The special handling of Exception::Class::Base objects was broken.
+ This was exposed by the fact that Exception::Class 1.15 now uses
+ Devel::StackTrace in a slightly different way than it did
+ previously.
+
+
+1.03 2003-01-22
+
+- Special handling of Exception::Class::Base objects when stringifying
+ references. This avoids infinite recursion between the two classes.
+
+
+1.02 2002-09-19
+
+- Forgot to add Test::More to PREREQ_PM for previous releases.
+
+
+1.01 2002-09-18
+
+- Change the "no object refs" feature to be a plain old "no refs"
+ feature. As was pointed out to me by Jean-Phillippe Bouchard, a
+ plain reference (to an array, for example), can easily hold
+ references to objects internally. And since I'm not going to bother
+ descending through nested data structures weeding out objects, this
+ is an easier way to handle the problem. Thanks to Jean-Phillippe
+ Bouchard for a patch for this as well.
+
+ The "no_object_refs" parameter is deprecated, and now does the same
+ thing as the "no_refs" parameter.
+
+
+1.00 2010-10-15
+
+- Add an option to not store references to objects in stack frames.
+ This can be important if you're expecting DESTROY to be called but a
+ Devel::StackTraceFrame object is still holding a reference to your
+ object(s). Based on discussion with Tatsuhiko Miyagawa.
+
+
+0.9 2001-11-24
+
+- Doc tweaks.
+
+
+0.85 2000-09-02
+
+- doc bug fix that made it seem like args method was only available
+ under Perl 5.6.0
+
+- converted objects from pseudo-hashes to regular hashes.
+
+
+0.8 2000-09-02
+
+- Should work under Perl 5.6.0+.
+
+- Added hints & bitmask methods for use under Perl 5.6.0.
+
+
+0.75 2000-06-29
+
+- Added frames method (and docs for it).
+
+- Added 'use 5.005' which I should have put in there earlier.
+
+- DOCS: explanation of 'top' and 'bottom' as they refer to the stack.
+
+
+0.7 2000-06-27
+
+- First release (I think)
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..8abeb88
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,43 @@
+This is the Perl distribution Devel-StackTrace.
+
+Installing Devel-StackTrace is straightforward.
+
+## Installation with cpanm
+
+If you have cpanm, you only need one line:
+
+ % cpanm Devel::StackTrace
+
+If you are installing into a system-wide directory, you may need to pass the
+"-S" flag to cpanm, which uses sudo to install the module:
+
+ % cpanm -S Devel::StackTrace
+
+## Installing with the CPAN shell
+
+Alternatively, if your CPAN shell is set up, you should just be able to do:
+
+ % cpan Devel::StackTrace
+
+## Manual installation
+
+As a last resort, you can manually install it. Download the tarball, untar it,
+then build it:
+
+ % perl Makefile.PL
+ % make && make test
+
+Then install it:
+
+ % make install
+
+If you are installing into a system-wide directory, you may need to run:
+
+ % sudo make install
+
+## Documentation
+
+Devel-StackTrace documentation is available as POD.
+You can run perldoc from a shell to read the documentation:
+
+ % perldoc Devel::StackTrace
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8693142
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,207 @@
+This software is Copyright (c) 2000 - 2014 by David Rolsky.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)
+
+ The Artistic License 2.0
+
+ Copyright (c) 2000-2006, The Perl Foundation.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MANIFEST b/MANIFEST
new file mode 100644
index 0000000..6d8d21e
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,35 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.023.
+Changes
+INSTALL
+LICENSE
+MANIFEST
+META.json
+META.yml
+Makefile.PL
+README.md
+dist.ini
+lib/Devel/StackTrace.pm
+lib/Devel/StackTrace/Frame.pm
+t/00-compile.t
+t/00-report-prereqs.dd
+t/00-report-prereqs.t
+t/01-basic.t
+t/02-bad-utf8.t
+t/03-message.t
+t/04-indent.t
+t/05-back-compat.t
+t/06-dollar-at.t
+t/07-no-args.t
+t/08-filter-early.t
+t/09-skip-frames.t
+t/author-eol.t
+t/author-no-tabs.t
+t/author-pod-spell.t
+t/release-cpan-changes.t
+t/release-pod-coverage.t
+t/release-pod-linkcheck.t
+t/release-pod-no404s.t
+t/release-pod-syntax.t
+t/release-portability.t
+t/release-synopsis.t
+weaver.ini
diff --git a/META.json b/META.json
new file mode 100644
index 0000000..fb878c0
--- /dev/null
+++ b/META.json
@@ -0,0 +1,650 @@
+{
+ "abstract" : "An object representing a stack trace",
+ "author" : [
+ "Dave Rolsky <autarch@urth.org>"
+ ],
+ "dynamic_config" : 0,
+ "generated_by" : "Dist::Zilla version 5.023, CPAN::Meta::Converter version 2.142690",
+ "license" : [
+ "artistic_2"
+ ],
+ "meta-spec" : {
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "version" : "2"
+ },
+ "name" : "Devel-StackTrace",
+ "prereqs" : {
+ "configure" : {
+ "requires" : {
+ "ExtUtils::MakeMaker" : "0"
+ }
+ },
+ "develop" : {
+ "requires" : {
+ "Pod::Coverage::TrustPod" : "0",
+ "Test::CPAN::Changes" : "0.19",
+ "Test::EOL" : "0",
+ "Test::More" : "0.88",
+ "Test::NoTabs" : "0",
+ "Test::Pod" : "1.41",
+ "Test::Pod::Coverage" : "1.08",
+ "Test::Spelling" : "0.12",
+ "Test::Synopsis" : "0"
+ }
+ },
+ "runtime" : {
+ "requires" : {
+ "File::Spec" : "0",
+ "Scalar::Util" : "0",
+ "overload" : "0",
+ "perl" : "5.006",
+ "strict" : "0",
+ "warnings" : "0"
+ }
+ },
+ "test" : {
+ "recommends" : {
+ "CPAN::Meta" : "2.120900"
+ },
+ "requires" : {
+ "ExtUtils::MakeMaker" : "0",
+ "File::Spec" : "0",
+ "IO::Handle" : "0",
+ "IPC::Open3" : "0",
+ "Test::More" : "0.88",
+ "base" : "0",
+ "bytes" : "0"
+ }
+ }
+ },
+ "provides" : {
+ "Devel::StackTrace" : {
+ "file" : "lib/Devel/StackTrace.pm",
+ "version" : "2.00"
+ },
+ "Devel::StackTrace::Frame" : {
+ "file" : "lib/Devel/StackTrace/Frame.pm",
+ "version" : "2.00"
+ }
+ },
+ "release_status" : "stable",
+ "resources" : {
+ "bugtracker" : {
+ "mailto" : "bug-devel-stacktrace@rt.cpan.org",
+ "web" : "http://rt.cpan.org/Public/Dist/Display.html?Name=Devel-StackTrace"
+ },
+ "homepage" : "http://metacpan.org/release/Devel-StackTrace",
+ "repository" : {
+ "type" : "git",
+ "url" : "git://github.com/autarch/Devel-StackTrace.git",
+ "web" : "https://github.com/autarch/Devel-StackTrace"
+ }
+ },
+ "version" : "2.00",
+ "x_Dist_Zilla" : {
+ "perl" : {
+ "version" : "5.016003"
+ },
+ "plugins" : [
+ {
+ "class" : "Dist::Zilla::Plugin::MakeMaker",
+ "config" : {
+ "Dist::Zilla::Role::TestRunner" : {
+ "default_jobs" : 1
+ }
+ },
+ "name" : "@DROLSKY/MakeMaker",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Authority",
+ "name" : "@DROLSKY/Authority",
+ "version" : "1.009"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::AutoPrereqs",
+ "name" : "@DROLSKY/AutoPrereqs",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::GatherDir",
+ "config" : {
+ "Dist::Zilla::Plugin::GatherDir" : {
+ "exclude_filename" : [
+ "README.md"
+ ],
+ "exclude_match" : [],
+ "follow_symlinks" : "0",
+ "include_dotfiles" : "0",
+ "prefix" : "",
+ "prune_directory" : [],
+ "root" : "."
+ }
+ },
+ "name" : "@DROLSKY/GatherDir",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::GitHub::Meta",
+ "name" : "@DROLSKY/GitHub::Meta",
+ "version" : "0.38"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::GitHub::Update",
+ "name" : "@DROLSKY/GitHub::Update",
+ "version" : "0.38"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MetaResources",
+ "name" : "@DROLSKY/MetaResources",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MetaProvides::Package",
+ "config" : {
+ "Dist::Zilla::Plugin::MetaProvides::Package" : {
+ "finder_objects" : [
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM",
+ "version" : "5.023"
+ }
+ ]
+ },
+ "Dist::Zilla::Role::MetaProvider::Provider" : {
+ "inherit_missing" : "1",
+ "inherit_version" : "1",
+ "meta_noindex" : "1"
+ }
+ },
+ "name" : "@DROLSKY/MetaProvides::Package",
+ "version" : "2.001002"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::NextRelease",
+ "name" : "@DROLSKY/NextRelease",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::PkgVersion",
+ "name" : "@DROLSKY/PkgVersion",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Prereqs",
+ "config" : {
+ "Dist::Zilla::Plugin::Prereqs" : {
+ "phase" : "test",
+ "type" : "requires"
+ }
+ },
+ "name" : "@DROLSKY/TestMoreDoneTesting",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::PromptIfStale",
+ "config" : {
+ "Dist::Zilla::Plugin::PromptIfStale" : {
+ "check_all_plugins" : "1",
+ "check_all_prereqs" : "1",
+ "modules" : [],
+ "phase" : "release",
+ "skip" : []
+ }
+ },
+ "name" : "@DROLSKY/stale modules, release",
+ "version" : "0.028"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod",
+ "name" : "@DROLSKY/ReadmeMarkdownInBuild",
+ "version" : "0.142470"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod",
+ "name" : "@DROLSKY/ReadmeMarkdownInRoot",
+ "version" : "0.142470"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable",
+ "name" : "@DROLSKY/Test::Pod::Coverage::Configurable",
+ "version" : "0.01"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::PodSpelling",
+ "name" : "@DROLSKY/Test::PodSpelling",
+ "version" : "2.006008"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs",
+ "name" : "@DROLSKY/Test::ReportPrereqs",
+ "version" : "0.019"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::PruneCruft",
+ "name" : "@DROLSKY/PruneCruft",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ManifestSkip",
+ "name" : "@DROLSKY/ManifestSkip",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MetaYAML",
+ "name" : "@DROLSKY/MetaYAML",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::License",
+ "name" : "@DROLSKY/License",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ExtraTests",
+ "name" : "@DROLSKY/ExtraTests",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ExecDir",
+ "name" : "@DROLSKY/ExecDir",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ShareDir",
+ "name" : "@DROLSKY/ShareDir",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Manifest",
+ "name" : "@DROLSKY/Manifest",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::TestRelease",
+ "name" : "@DROLSKY/TestRelease",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::ConfirmRelease",
+ "name" : "@DROLSKY/ConfirmRelease",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::UploadToCPAN",
+ "name" : "@DROLSKY/UploadToCPAN",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed",
+ "name" : "@DROLSKY/CheckPrereqsIndexed",
+ "version" : "0.012"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::CopyReadmeFromBuild",
+ "name" : "@DROLSKY/CopyReadmeFromBuild",
+ "version" : "0.0019"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::DROLSKY::Contributors",
+ "name" : "@DROLSKY/DROLSKY::Contributors",
+ "version" : "0.21"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::DROLSKY::License",
+ "name" : "@DROLSKY/DROLSKY::License",
+ "version" : "0.21"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch",
+ "config" : {
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
+ "name" : "@DROLSKY/Git::CheckFor::CorrectBranch",
+ "version" : "0.011"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts",
+ "config" : {
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
+ "name" : "@DROLSKY/Git::CheckFor::MergeConflicts",
+ "version" : "0.011"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::Contributors",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Contributors" : {
+ "include_authors" : "0",
+ "include_releaser" : "1",
+ "order_by" : "name",
+ "paths" : []
+ }
+ },
+ "name" : "@DROLSKY/Git::Contributors",
+ "version" : "0.008"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::Describe",
+ "name" : "@DROLSKY/Git::Describe",
+ "version" : "0.003"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::InstallGuide",
+ "name" : "@DROLSKY/InstallGuide",
+ "version" : "1.200005"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Meta::Contributors",
+ "name" : "@DROLSKY/Meta::Contributors",
+ "version" : "0.001"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MetaConfig",
+ "name" : "@DROLSKY/MetaConfig",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::MetaJSON",
+ "name" : "@DROLSKY/MetaJSON",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::SurgicalPodWeaver",
+ "config" : {
+ "Dist::Zilla::Plugin::PodWeaver" : {
+ "finder" : [
+ ":InstallModules",
+ ":ExecFiles"
+ ],
+ "plugins" : [
+ {
+ "class" : "Pod::Weaver::Plugin::EnsurePod5",
+ "name" : "@CorePrep/EnsurePod5",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Plugin::H1Nester",
+ "name" : "@CorePrep/H1Nester",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Name",
+ "name" : "Name",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Version",
+ "name" : "Version",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Region",
+ "name" : "prelude",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Generic",
+ "name" : "SYNOPSIS",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Generic",
+ "name" : "DESCRIPTION",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Leftovers",
+ "name" : "Leftovers",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Region",
+ "name" : "postlude",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Authors",
+ "name" : "Authors",
+ "version" : "4.006"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Contributors",
+ "name" : "Contributors",
+ "version" : "0.008"
+ },
+ {
+ "class" : "Pod::Weaver::Section::Legal",
+ "name" : "Legal",
+ "version" : "4.006"
+ }
+ ]
+ }
+ },
+ "name" : "@DROLSKY/SurgicalPodWeaver",
+ "version" : "0.0021"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::PodSyntaxTests",
+ "name" : "@DROLSKY/PodSyntaxTests",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes",
+ "name" : "@DROLSKY/Test::CPAN::Changes",
+ "version" : "0.008"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Compile",
+ "config" : {
+ "Dist::Zilla::Plugin::Test::Compile" : {
+ "bail_out_on_fail" : "0",
+ "fail_on_warning" : "author",
+ "fake_home" : "0",
+ "filename" : "t/00-compile.t",
+ "module_finder" : [
+ ":InstallModules"
+ ],
+ "needs_display" : "0",
+ "phase" : "test",
+ "script_finder" : [
+ ":ExecFiles"
+ ],
+ "skips" : []
+ }
+ },
+ "name" : "@DROLSKY/Test::Compile",
+ "version" : "2.051"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::EOL",
+ "config" : {
+ "Dist::Zilla::Plugin::Test::EOL" : {
+ "filename" : "xt/author/eol.t"
+ }
+ },
+ "name" : "@DROLSKY/Test::EOL",
+ "version" : "0.15"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::NoTabs",
+ "config" : {
+ "Dist::Zilla::Plugin::Test::NoTabs" : {
+ "filename" : "xt/author/no-tabs.t",
+ "finder" : [
+ ":InstallModules",
+ ":ExecFiles",
+ ":TestFiles"
+ ]
+ }
+ },
+ "name" : "@DROLSKY/Test::NoTabs",
+ "version" : "0.09"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Pod::LinkCheck",
+ "name" : "@DROLSKY/Test::Pod::LinkCheck",
+ "version" : "1.001"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Pod::No404s",
+ "name" : "@DROLSKY/Test::Pod::No404s",
+ "version" : "1.001"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Portability",
+ "name" : "@DROLSKY/Test::Portability",
+ "version" : "2.000005"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Test::Synopsis",
+ "name" : "@DROLSKY/Test::Synopsis",
+ "version" : "2.000005"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::Check",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Check" : {
+ "untracked_files" : "die"
+ },
+ "Dist::Zilla::Role::Git::DirtyFiles" : {
+ "allow_dirty" : [
+ "Changes",
+ "CONTRIBUTING.md",
+ "README.md"
+ ],
+ "allow_dirty_match" : [],
+ "changelog" : "Changes"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
+ "name" : "@DROLSKY/Git::Check",
+ "version" : "2.025"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::Commit",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Commit" : {
+ "add_files_in" : [],
+ "commit_msg" : "v%v%n%n%c",
+ "time_zone" : "local"
+ },
+ "Dist::Zilla::Role::Git::DirtyFiles" : {
+ "allow_dirty" : [
+ "Changes",
+ "CONTRIBUTING.md",
+ "README.md"
+ ],
+ "allow_dirty_match" : [],
+ "changelog" : "Changes"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
+ "name" : "@DROLSKY/Git::Commit",
+ "version" : "2.025"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::Git::Tag",
+ "config" : {
+ "Dist::Zilla::Plugin::Git::Tag" : {
+ "branch" : null,
+ "signed" : 0,
+ "tag" : "v2.00",
+ "tag_format" : "v%v",
+ "tag_message" : "v%v",
+ "time_zone" : "local"
+ },
+ "Dist::Zilla::Role::Git::Repo" : {
+ "repo_root" : "."
+ }
+ },
+ "name" : "@DROLSKY/Git::Tag",
+ "version" : "2.025"
+ },
+ {
+ "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" : "@DROLSKY/Git::Push",
+ "version" : "2.025"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":InstallModules",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":IncModules",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":TestFiles",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":ExecFiles",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":ShareFiles",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":MainModule",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":AllFiles",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : ":NoFiles",
+ "version" : "5.023"
+ },
+ {
+ "class" : "Dist::Zilla::Plugin::FinderCode",
+ "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM",
+ "version" : "5.023"
+ }
+ ],
+ "zilla" : {
+ "class" : "Dist::Zilla::Dist::Builder",
+ "config" : {
+ "is_trial" : "0"
+ },
+ "version" : "5.023"
+ }
+ },
+ "x_authority" : "cpan:DROLSKY",
+ "x_contributors" : [
+ "Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>",
+ "David Cantrell <david@cantrell.org.uk>",
+ "Graham Knop <haarg@haarg.org>",
+ "Ricardo Signes <rjbs@cpan.org>"
+ ]
+}
+
diff --git a/META.yml b/META.yml
new file mode 100644
index 0000000..3fc7d11
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,474 @@
+---
+abstract: 'An object representing a stack trace'
+author:
+ - 'Dave Rolsky <autarch@urth.org>'
+build_requires:
+ ExtUtils::MakeMaker: '0'
+ File::Spec: '0'
+ IO::Handle: '0'
+ IPC::Open3: '0'
+ Test::More: '0.88'
+ base: '0'
+ bytes: '0'
+configure_requires:
+ ExtUtils::MakeMaker: '0'
+dynamic_config: 0
+generated_by: 'Dist::Zilla version 5.023, CPAN::Meta::Converter version 2.142690'
+license: artistic_2
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: '1.4'
+name: Devel-StackTrace
+provides:
+ Devel::StackTrace:
+ file: lib/Devel/StackTrace.pm
+ version: '2.00'
+ Devel::StackTrace::Frame:
+ file: lib/Devel/StackTrace/Frame.pm
+ version: '2.00'
+requires:
+ File::Spec: '0'
+ Scalar::Util: '0'
+ overload: '0'
+ perl: '5.006'
+ strict: '0'
+ warnings: '0'
+resources:
+ bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=Devel-StackTrace
+ homepage: http://metacpan.org/release/Devel-StackTrace
+ repository: git://github.com/autarch/Devel-StackTrace.git
+version: '2.00'
+x_Dist_Zilla:
+ perl:
+ version: '5.016003'
+ plugins:
+ -
+ class: Dist::Zilla::Plugin::MakeMaker
+ config:
+ Dist::Zilla::Role::TestRunner:
+ default_jobs: 1
+ name: '@DROLSKY/MakeMaker'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::Authority
+ name: '@DROLSKY/Authority'
+ version: '1.009'
+ -
+ class: Dist::Zilla::Plugin::AutoPrereqs
+ name: '@DROLSKY/AutoPrereqs'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::GatherDir
+ config:
+ Dist::Zilla::Plugin::GatherDir:
+ exclude_filename:
+ - README.md
+ exclude_match: []
+ follow_symlinks: '0'
+ include_dotfiles: '0'
+ prefix: ''
+ prune_directory: []
+ root: .
+ name: '@DROLSKY/GatherDir'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::GitHub::Meta
+ name: '@DROLSKY/GitHub::Meta'
+ version: '0.38'
+ -
+ class: Dist::Zilla::Plugin::GitHub::Update
+ name: '@DROLSKY/GitHub::Update'
+ version: '0.38'
+ -
+ class: Dist::Zilla::Plugin::MetaResources
+ name: '@DROLSKY/MetaResources'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::MetaProvides::Package
+ config:
+ Dist::Zilla::Plugin::MetaProvides::Package:
+ finder_objects:
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM'
+ version: '5.023'
+ Dist::Zilla::Role::MetaProvider::Provider:
+ inherit_missing: '1'
+ inherit_version: '1'
+ meta_noindex: '1'
+ name: '@DROLSKY/MetaProvides::Package'
+ version: '2.001002'
+ -
+ class: Dist::Zilla::Plugin::NextRelease
+ name: '@DROLSKY/NextRelease'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::PkgVersion
+ name: '@DROLSKY/PkgVersion'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::Prereqs
+ config:
+ Dist::Zilla::Plugin::Prereqs:
+ phase: test
+ type: requires
+ name: '@DROLSKY/TestMoreDoneTesting'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::PromptIfStale
+ config:
+ Dist::Zilla::Plugin::PromptIfStale:
+ check_all_plugins: '1'
+ check_all_prereqs: '1'
+ modules: []
+ phase: release
+ skip: []
+ name: '@DROLSKY/stale modules, release'
+ version: '0.028'
+ -
+ class: Dist::Zilla::Plugin::ReadmeAnyFromPod
+ name: '@DROLSKY/ReadmeMarkdownInBuild'
+ version: '0.142470'
+ -
+ class: Dist::Zilla::Plugin::ReadmeAnyFromPod
+ name: '@DROLSKY/ReadmeMarkdownInRoot'
+ version: '0.142470'
+ -
+ class: Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable
+ name: '@DROLSKY/Test::Pod::Coverage::Configurable'
+ version: '0.01'
+ -
+ class: Dist::Zilla::Plugin::Test::PodSpelling
+ name: '@DROLSKY/Test::PodSpelling'
+ version: '2.006008'
+ -
+ class: Dist::Zilla::Plugin::Test::ReportPrereqs
+ name: '@DROLSKY/Test::ReportPrereqs'
+ version: '0.019'
+ -
+ class: Dist::Zilla::Plugin::PruneCruft
+ name: '@DROLSKY/PruneCruft'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::ManifestSkip
+ name: '@DROLSKY/ManifestSkip'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::MetaYAML
+ name: '@DROLSKY/MetaYAML'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::License
+ name: '@DROLSKY/License'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::ExtraTests
+ name: '@DROLSKY/ExtraTests'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::ExecDir
+ name: '@DROLSKY/ExecDir'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::ShareDir
+ name: '@DROLSKY/ShareDir'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::Manifest
+ name: '@DROLSKY/Manifest'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::TestRelease
+ name: '@DROLSKY/TestRelease'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::ConfirmRelease
+ name: '@DROLSKY/ConfirmRelease'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::UploadToCPAN
+ name: '@DROLSKY/UploadToCPAN'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::CheckPrereqsIndexed
+ name: '@DROLSKY/CheckPrereqsIndexed'
+ version: '0.012'
+ -
+ class: Dist::Zilla::Plugin::CopyReadmeFromBuild
+ name: '@DROLSKY/CopyReadmeFromBuild'
+ version: '0.0019'
+ -
+ class: Dist::Zilla::Plugin::DROLSKY::Contributors
+ name: '@DROLSKY/DROLSKY::Contributors'
+ version: '0.21'
+ -
+ class: Dist::Zilla::Plugin::DROLSKY::License
+ name: '@DROLSKY/DROLSKY::License'
+ version: '0.21'
+ -
+ class: Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch
+ config:
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
+ name: '@DROLSKY/Git::CheckFor::CorrectBranch'
+ version: '0.011'
+ -
+ class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts
+ config:
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
+ name: '@DROLSKY/Git::CheckFor::MergeConflicts'
+ version: '0.011'
+ -
+ class: Dist::Zilla::Plugin::Git::Contributors
+ config:
+ Dist::Zilla::Plugin::Git::Contributors:
+ include_authors: '0'
+ include_releaser: '1'
+ order_by: name
+ paths: []
+ name: '@DROLSKY/Git::Contributors'
+ version: '0.008'
+ -
+ class: Dist::Zilla::Plugin::Git::Describe
+ name: '@DROLSKY/Git::Describe'
+ version: '0.003'
+ -
+ class: Dist::Zilla::Plugin::InstallGuide
+ name: '@DROLSKY/InstallGuide'
+ version: '1.200005'
+ -
+ class: Dist::Zilla::Plugin::Meta::Contributors
+ name: '@DROLSKY/Meta::Contributors'
+ version: '0.001'
+ -
+ class: Dist::Zilla::Plugin::MetaConfig
+ name: '@DROLSKY/MetaConfig'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::MetaJSON
+ name: '@DROLSKY/MetaJSON'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::SurgicalPodWeaver
+ config:
+ Dist::Zilla::Plugin::PodWeaver:
+ finder:
+ - ':InstallModules'
+ - ':ExecFiles'
+ plugins:
+ -
+ class: Pod::Weaver::Plugin::EnsurePod5
+ name: '@CorePrep/EnsurePod5'
+ version: '4.006'
+ -
+ class: Pod::Weaver::Plugin::H1Nester
+ name: '@CorePrep/H1Nester'
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Name
+ name: Name
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Version
+ name: Version
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Region
+ name: prelude
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Generic
+ name: SYNOPSIS
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Generic
+ name: DESCRIPTION
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Leftovers
+ name: Leftovers
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Region
+ name: postlude
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Authors
+ name: Authors
+ version: '4.006'
+ -
+ class: Pod::Weaver::Section::Contributors
+ name: Contributors
+ version: '0.008'
+ -
+ class: Pod::Weaver::Section::Legal
+ name: Legal
+ version: '4.006'
+ name: '@DROLSKY/SurgicalPodWeaver'
+ version: '0.0021'
+ -
+ class: Dist::Zilla::Plugin::PodSyntaxTests
+ name: '@DROLSKY/PodSyntaxTests'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::Test::CPAN::Changes
+ name: '@DROLSKY/Test::CPAN::Changes'
+ version: '0.008'
+ -
+ class: Dist::Zilla::Plugin::Test::Compile
+ config:
+ Dist::Zilla::Plugin::Test::Compile:
+ bail_out_on_fail: '0'
+ fail_on_warning: author
+ fake_home: '0'
+ filename: t/00-compile.t
+ module_finder:
+ - ':InstallModules'
+ needs_display: '0'
+ phase: test
+ script_finder:
+ - ':ExecFiles'
+ skips: []
+ name: '@DROLSKY/Test::Compile'
+ version: '2.051'
+ -
+ class: Dist::Zilla::Plugin::Test::EOL
+ config:
+ Dist::Zilla::Plugin::Test::EOL:
+ filename: xt/author/eol.t
+ name: '@DROLSKY/Test::EOL'
+ version: '0.15'
+ -
+ class: Dist::Zilla::Plugin::Test::NoTabs
+ config:
+ Dist::Zilla::Plugin::Test::NoTabs:
+ filename: xt/author/no-tabs.t
+ finder:
+ - ':InstallModules'
+ - ':ExecFiles'
+ - ':TestFiles'
+ name: '@DROLSKY/Test::NoTabs'
+ version: '0.09'
+ -
+ class: Dist::Zilla::Plugin::Test::Pod::LinkCheck
+ name: '@DROLSKY/Test::Pod::LinkCheck'
+ version: '1.001'
+ -
+ class: Dist::Zilla::Plugin::Test::Pod::No404s
+ name: '@DROLSKY/Test::Pod::No404s'
+ version: '1.001'
+ -
+ class: Dist::Zilla::Plugin::Test::Portability
+ name: '@DROLSKY/Test::Portability'
+ version: '2.000005'
+ -
+ class: Dist::Zilla::Plugin::Test::Synopsis
+ name: '@DROLSKY/Test::Synopsis'
+ version: '2.000005'
+ -
+ class: Dist::Zilla::Plugin::Git::Check
+ config:
+ Dist::Zilla::Plugin::Git::Check:
+ untracked_files: die
+ Dist::Zilla::Role::Git::DirtyFiles:
+ allow_dirty:
+ - Changes
+ - CONTRIBUTING.md
+ - README.md
+ allow_dirty_match: []
+ changelog: Changes
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
+ name: '@DROLSKY/Git::Check'
+ version: '2.025'
+ -
+ class: Dist::Zilla::Plugin::Git::Commit
+ config:
+ Dist::Zilla::Plugin::Git::Commit:
+ add_files_in: []
+ commit_msg: v%v%n%n%c
+ time_zone: local
+ Dist::Zilla::Role::Git::DirtyFiles:
+ allow_dirty:
+ - Changes
+ - CONTRIBUTING.md
+ - README.md
+ allow_dirty_match: []
+ changelog: Changes
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
+ name: '@DROLSKY/Git::Commit'
+ version: '2.025'
+ -
+ class: Dist::Zilla::Plugin::Git::Tag
+ config:
+ Dist::Zilla::Plugin::Git::Tag:
+ branch: ~
+ signed: 0
+ tag: v2.00
+ tag_format: v%v
+ tag_message: v%v
+ time_zone: local
+ Dist::Zilla::Role::Git::Repo:
+ repo_root: .
+ name: '@DROLSKY/Git::Tag'
+ version: '2.025'
+ -
+ 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: '@DROLSKY/Git::Push'
+ version: '2.025'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':InstallModules'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':IncModules'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':TestFiles'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':ExecFiles'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':ShareFiles'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':MainModule'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':AllFiles'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: ':NoFiles'
+ version: '5.023'
+ -
+ class: Dist::Zilla::Plugin::FinderCode
+ name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM'
+ version: '5.023'
+ zilla:
+ class: Dist::Zilla::Dist::Builder
+ config:
+ is_trial: '0'
+ version: '5.023'
+x_authority: cpan:DROLSKY
+x_contributors:
+ - 'Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>'
+ - 'David Cantrell <david@cantrell.org.uk>'
+ - 'Graham Knop <haarg@haarg.org>'
+ - 'Ricardo Signes <rjbs@cpan.org>'
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..b4912ac
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,73 @@
+
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.023.
+use strict;
+use warnings;
+
+use 5.006;
+
+use ExtUtils::MakeMaker;
+
+
+
+my %WriteMakefileArgs = (
+ "ABSTRACT" => "An object representing a stack trace",
+ "AUTHOR" => "Dave Rolsky <autarch\@urth.org>",
+ "CONFIGURE_REQUIRES" => {
+ "ExtUtils::MakeMaker" => 0
+ },
+ "DISTNAME" => "Devel-StackTrace",
+ "EXE_FILES" => [],
+ "LICENSE" => "artistic_2",
+ "MIN_PERL_VERSION" => "5.006",
+ "NAME" => "Devel::StackTrace",
+ "PREREQ_PM" => {
+ "File::Spec" => 0,
+ "Scalar::Util" => 0,
+ "overload" => 0,
+ "strict" => 0,
+ "warnings" => 0
+ },
+ "TEST_REQUIRES" => {
+ "ExtUtils::MakeMaker" => 0,
+ "File::Spec" => 0,
+ "IO::Handle" => 0,
+ "IPC::Open3" => 0,
+ "Test::More" => "0.88",
+ "base" => 0,
+ "bytes" => 0
+ },
+ "VERSION" => "2.00",
+ "test" => {
+ "TESTS" => "t/*.t"
+ }
+);
+
+
+my %FallbackPrereqs = (
+ "ExtUtils::MakeMaker" => 0,
+ "File::Spec" => 0,
+ "IO::Handle" => 0,
+ "IPC::Open3" => 0,
+ "Scalar::Util" => 0,
+ "Test::More" => "0.88",
+ "base" => 0,
+ "bytes" => 0,
+ "overload" => 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.md b/README.md
new file mode 100644
index 0000000..73b3bf1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,239 @@
+# NAME
+
+Devel::StackTrace - An object representing a stack trace
+
+# VERSION
+
+version 2.00
+
+# SYNOPSIS
+
+ use Devel::StackTrace;
+
+ my $trace = Devel::StackTrace->new();
+
+ print $trace->as_string(); # like carp
+
+ # from top (most recent) of stack to bottom.
+ while ( my $frame = $trace->next_frame() ) {
+ print "Has args\n" if $frame->hasargs();
+ }
+
+ # from bottom (least recent) of stack to top.
+ while ( my $frame = $trace->prev_frame() ) {
+ print "Sub: ", $frame->subroutine(), "\n";
+ }
+
+# DESCRIPTION
+
+The `Devel::StackTrace` module contains two classes, C,Devel::StackTrace> and
+[Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame). These objects encapsulate the information that
+can retrieved via Perl's `caller()` function, as well as providing a simple
+interface to this data.
+
+The `Devel::StackTrace` object contains a set of `Devel::StackTrace::Frame`
+objects, one for each level of the stack. The frames contain all the data
+available from `caller()`.
+
+This code was created to support my [Exception::Class::Base](https://metacpan.org/pod/Exception::Class::Base) class (part of
+[Exception::Class](https://metacpan.org/pod/Exception::Class)) but may be useful in other contexts.
+
+# 'TOP' AND 'BOTTOM' OF THE STACK
+
+When describing the methods of the trace object, I use the words 'top' and
+'bottom'. In this context, the 'top' frame on the stack is the most recent
+frame and the 'bottom' is the least recent.
+
+Here's an example:
+
+ foo(); # bottom frame is here
+
+ sub foo {
+ bar();
+ }
+
+ sub bar {
+ Devel::StackTrace->new(); # top frame is here.
+ }
+
+# METHODS
+
+This class provide the following methods:
+
+## Devel::StackTrace->new(%named\_params)
+
+Returns a new Devel::StackTrace object.
+
+Takes the following parameters:
+
+- frame\_filter => $sub
+
+ By default, Devel::StackTrace will include all stack frames before the
+ call to its constructor.
+
+ However, you may want to filter out some frames with more granularity
+ than 'ignore\_package' or 'ignore\_class' allow.
+
+ You can provide a subroutine which is called with the raw frame data
+ for each frame. This is a hash reference with two keys, "caller", and
+ "args", both of which are array references. The "caller" key is the
+ raw data as returned by Perl's `caller()` function, and the "args"
+ key are the subroutine arguments found in `@DB::args`.
+
+ The filter should return true if the frame should be included, or
+ false if it should be skipped.
+
+- filter\_frames\_early => $boolean
+
+ If this parameter is true, `frame_filter` will be called as soon as the
+ stacktrace is created, and before refs are stringified (if
+ `unsafe_ref_capture` is not set), rather than being filtered lazily when
+ [Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame) objects are first needed.
+
+ This is useful if you want to filter based on the frame's arguments and want
+ to be able to examine object properties, for example.
+
+- ignore\_package => $package\_name OR \\@package\_names
+
+ Any frames where the package is one of these packages will not be on
+ the stack.
+
+- ignore\_class => $package\_name OR \\@package\_names
+
+ Any frames where the package is a subclass of one of these packages
+ (or is the same package) will not be on the stack.
+
+ Devel::StackTrace internally adds itself to the 'ignore\_package'
+ parameter, meaning that the Devel::StackTrace package is **ALWAYS**
+ ignored. However, if you create a subclass of Devel::StackTrace it
+ will not be ignored.
+
+- skip\_frames => $integer
+
+ This will cause this number of stack frames to be excluded from top of the
+ stack trace. This prevents the frames from being captured at all, and applies
+ before the `frame_filter`, `ignore_package`, or `ignore_class` options,
+ even with `filter_frames_early`.
+
+- unsafe\_ref\_capture => $boolean
+
+ If this parameter is true, then Devel::StackTrace will store
+ references internally when generating stacktrace frames.
+
+ **This option is very dangerous, and should never be used with exception
+ objects**. Using this option will keep any objects or references alive past
+ their normal lifetime, until the stack trace object goes out of scope. It can
+ keep objects alive even after their `DESTROY` sub is called, resulting it it
+ being called multiple times on the same object.
+
+ If not set, Devel::StackTrace replaces any references with their stringified
+ representation.
+
+- no\_args => $boolean
+
+ If this parameter is true, then Devel::StackTrace will not store caller
+ arguments in stack trace frames at all.
+
+- respect\_overload => $boolean
+
+ By default, Devel::StackTrace will call `overload::AddrRef()` to get
+ the underlying string representation of an object, instead of
+ respecting the object's stringification overloading. If you would
+ prefer to see the overloaded representation of objects in stack
+ traces, then set this parameter to true.
+
+- max\_arg\_length => $integer
+
+ By default, Devel::StackTrace will display the entire argument for each
+ subroutine call. Setting this parameter causes truncates each subroutine
+ argument's string representation if it is longer than this number of
+ characters.
+
+- message => $string
+
+ By default, Devel::StackTrace will use 'Trace begun' as the message for the
+ first stack frame when you call `as_string`. You can supply an alternative
+ message using this option.
+
+- indent => $boolean
+
+ If this parameter is true, each stack frame after the first will start with a
+ tab character, just like `Carp::confess()`.
+
+## $trace->next\_frame()
+
+Returns the next [Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame) object on the stack, going
+down. If this method hasn't been called before it returns the first frame. It
+returns `undef` when it reaches the bottom of the stack and then resets its
+pointer so the next call to `$trace->next_frame()` or `$trace->prev_frame()` will work properly.
+
+## $trace->prev\_frame()
+
+Returns the next [Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame) object on the stack, going up. If
+this method hasn't been called before it returns the last frame. It returns
+undef when it reaches the top of the stack and then resets its pointer so the
+next call to `$trace->next_frame()` or `$trace->prev_frame()` will
+work properly.
+
+## $trace->reset\_pointer
+
+Resets the pointer so that the next call to `$trace->next_frame()` or `$trace->prev_frame()` will start at the top or bottom of the stack, as
+appropriate.
+
+## $trace->frames()
+
+When this method is called with no arguments, it returns a list of
+[Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame) objects. They are returned in order from top (most
+recent) to bottom.
+
+This method can also be used to set the object's frames if you pass it a list
+of [Devel::StackTrace::Frame](https://metacpan.org/pod/Devel::StackTrace::Frame) objects.
+
+This is useful if you want to filter the list of frames in ways that are more
+complex than can be handled by the `$trace->filter_frames()` method:
+
+ $stacktrace->frames( my_filter( $stacktrace->frames() ) );
+
+## $trace->frame($index)
+
+Given an index, this method returns the relevant frame, or undef if there is
+no frame at that index. The index is exactly like a Perl array. The first
+frame is 0 and negative indexes are allowed.
+
+## $trace->frame\_count()
+
+Returns the number of frames in the trace object.
+
+## $trace->as\_string(\\%p)
+
+Calls `$frame->as_string()` on each frame from top to bottom, producing
+output quite similar to the Carp module's cluck/confess methods.
+
+The optional `\%p` parameter only has one option. The `max_arg_length`
+parameter truncates each subroutine argument's string representation if it is
+longer than this number of characters.
+
+# SUPPORT
+
+Please submit bugs to the CPAN RT system at
+http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel%3A%3AStackTrace
+or via email at bug-devel-stacktrace@rt.cpan.org.
+
+# AUTHOR
+
+Dave Rolsky <autarch@urth.org>
+
+# CONTRIBUTORS
+
+- Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
+- David Cantrell <david@cantrell.org.uk>
+- Graham Knop <haarg@haarg.org>
+- Ricardo Signes <rjbs@cpan.org>
+
+# COPYRIGHT AND LICENSE
+
+This software is Copyright (c) 2000 - 2014 by David Rolsky.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)
diff --git a/dist.ini b/dist.ini
new file mode 100644
index 0000000..f6873f0
--- /dev/null
+++ b/dist.ini
@@ -0,0 +1,13 @@
+name = Devel-StackTrace
+author = Dave Rolsky <autarch@urth.org>
+copyright_year = 2000
+
+version = 2.00
+
+[@DROLSKY]
+dist = Devel-StackTrace
+next_release_width = 6
+prereqs_skip = Test
+stopwords = CPAN
+stopwords = Rolsky
+stopwords = stacktrace
diff --git a/lib/Devel/StackTrace.pm b/lib/Devel/StackTrace.pm
new file mode 100644
index 0000000..cf7ef43
--- /dev/null
+++ b/lib/Devel/StackTrace.pm
@@ -0,0 +1,531 @@
+package Devel::StackTrace;
+# git description: v1.34-10-g810fd3f
+
+$Devel::StackTrace::VERSION = '2.00';
+use 5.006;
+
+use strict;
+use warnings;
+
+use Devel::StackTrace::Frame;
+use File::Spec;
+use Scalar::Util qw( blessed );
+
+use overload
+ '""' => \&as_string,
+ fallback => 1;
+
+sub new {
+ my $class = shift;
+ my %p = @_;
+
+ $p{unsafe_ref_capture} = !delete $p{no_refs}
+ if exists $p{no_refs};
+
+ my $self = bless {
+ index => undef,
+ frames => [],
+ raw => [],
+ %p,
+ }, $class;
+
+ $self->_record_caller_data();
+
+ return $self;
+}
+
+sub _record_caller_data {
+ my $self = shift;
+
+ my $filter = $self->{filter_frames_early} && $self->_make_frame_filter();
+
+ # We exclude this method by starting at least one frame back.
+ my $x = 1 + ( $self->{skip_frames} || 0 );
+
+ while (
+ my @c
+ = $self->{no_args}
+ ? caller( $x++ )
+ : do {
+ package # the newline keeps dzil from adding a version here
+ DB;
+ @DB::args = ();
+ caller( $x++ );
+ }
+ ) {
+
+ my @args;
+
+ @args = $self->{no_args} ? () : @DB::args;
+
+ my $raw = {
+ caller => \@c,
+ args => \@args,
+ };
+
+ next if $filter && !$filter->($raw);
+
+ unless ( $self->{unsafe_ref_capture} ) {
+ $raw->{args} = [ map { ref $_ ? $self->_ref_to_string($_) : $_ }
+ @{ $raw->{args} } ];
+ }
+
+ push @{ $self->{raw} }, $raw;
+ }
+}
+
+sub _ref_to_string {
+ my $self = shift;
+ my $ref = shift;
+
+ return overload::AddrRef($ref)
+ if blessed $ref && $ref->isa('Exception::Class::Base');
+
+ return overload::AddrRef($ref) unless $self->{respect_overload};
+
+ local $@;
+ local $SIG{__DIE__};
+
+ my $str = eval { $ref . '' };
+
+ return $@ ? overload::AddrRef($ref) : $str;
+}
+
+sub _make_frames {
+ my $self = shift;
+
+ my $filter = !$self->{filter_frames_early} && $self->_make_frame_filter();
+
+ my $raw = delete $self->{raw};
+ for my $r ( @{$raw} ) {
+ next if $filter && !$filter->($r);
+
+ $self->_add_frame( $r->{caller}, $r->{args} );
+ }
+}
+
+my $default_filter = sub { 1 };
+
+sub _make_frame_filter {
+ my $self = shift;
+
+ my ( @i_pack_re, %i_class );
+ if ( $self->{ignore_package} ) {
+ local $@;
+ local $SIG{__DIE__};
+
+ $self->{ignore_package} = [ $self->{ignore_package} ]
+ unless eval { @{ $self->{ignore_package} } };
+
+ @i_pack_re
+ = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} };
+ }
+
+ my $p = __PACKAGE__;
+ push @i_pack_re, qr/^\Q$p\E$/;
+
+ if ( $self->{ignore_class} ) {
+ $self->{ignore_class} = [ $self->{ignore_class} ]
+ unless ref $self->{ignore_class};
+ %i_class = map { $_ => 1 } @{ $self->{ignore_class} };
+ }
+
+ my $user_filter = $self->{frame_filter};
+
+ return sub {
+ return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re;
+ return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class;
+
+ if ($user_filter) {
+ return $user_filter->( $_[0] );
+ }
+
+ return 1;
+ };
+}
+
+sub _add_frame {
+ my $self = shift;
+ my $c = shift;
+ my $p = shift;
+
+ # eval and is_require are only returned when applicable under 5.00503.
+ push @$c, ( undef, undef ) if scalar @$c == 6;
+
+ push @{ $self->{frames} },
+ Devel::StackTrace::Frame->new(
+ $c,
+ $p,
+ $self->{respect_overload},
+ $self->{max_arg_length},
+ $self->{message},
+ $self->{indent}
+ );
+}
+
+sub next_frame {
+ my $self = shift;
+
+ # reset to top if necessary.
+ $self->{index} = -1 unless defined $self->{index};
+
+ my @f = $self->frames();
+ if ( defined $f[ $self->{index} + 1 ] ) {
+ return $f[ ++$self->{index} ];
+ }
+ else {
+ $self->{index} = undef;
+ return undef;
+ }
+}
+
+sub prev_frame {
+ my $self = shift;
+
+ my @f = $self->frames();
+
+ # reset to top if necessary.
+ $self->{index} = scalar @f unless defined $self->{index};
+
+ if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) {
+ return $f[ --$self->{index} ];
+ }
+ else {
+ $self->{index} = undef;
+ return undef;
+ }
+}
+
+sub reset_pointer {
+ my $self = shift;
+
+ $self->{index} = undef;
+}
+
+sub frames {
+ my $self = shift;
+
+ if (@_) {
+ die
+ "Devel::StackTrace->frames() can only take Devel::StackTrace::Frame args\n"
+ if grep { !$_->isa('Devel::StackTrace::Frame') } @_;
+
+ $self->{frames} = \@_;
+ }
+ else {
+ $self->_make_frames() if $self->{raw};
+ }
+
+ return @{ $self->{frames} };
+}
+
+sub frame {
+ my $self = shift;
+ my $i = shift;
+
+ return unless defined $i;
+
+ return ( $self->frames() )[$i];
+}
+
+sub frame_count {
+ my $self = shift;
+
+ return scalar( $self->frames() );
+}
+
+sub as_string {
+ my $self = shift;
+ my $p = shift;
+
+ my $st = '';
+ my $first = 1;
+ foreach my $f ( $self->frames() ) {
+ $st .= $f->as_string( $first, $p ) . "\n";
+ $first = 0;
+ }
+
+ return $st;
+}
+
+{
+ package # hide from PAUSE
+ Devel::StackTraceFrame;
+
+ our @ISA = 'Devel::StackTrace::Frame';
+}
+
+1;
+
+# ABSTRACT: An object representing a stack trace
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Devel::StackTrace - An object representing a stack trace
+
+=head1 VERSION
+
+version 2.00
+
+=head1 SYNOPSIS
+
+ use Devel::StackTrace;
+
+ my $trace = Devel::StackTrace->new();
+
+ print $trace->as_string(); # like carp
+
+ # from top (most recent) of stack to bottom.
+ while ( my $frame = $trace->next_frame() ) {
+ print "Has args\n" if $frame->hasargs();
+ }
+
+ # from bottom (least recent) of stack to top.
+ while ( my $frame = $trace->prev_frame() ) {
+ print "Sub: ", $frame->subroutine(), "\n";
+ }
+
+=head1 DESCRIPTION
+
+The C<Devel::StackTrace> module contains two classes, C,Devel::StackTrace> and
+L<Devel::StackTrace::Frame>. These objects encapsulate the information that
+can retrieved via Perl's C<caller()> function, as well as providing a simple
+interface to this data.
+
+The C<Devel::StackTrace> object contains a set of C<Devel::StackTrace::Frame>
+objects, one for each level of the stack. The frames contain all the data
+available from C<caller()>.
+
+This code was created to support my L<Exception::Class::Base> class (part of
+L<Exception::Class>) but may be useful in other contexts.
+
+=encoding UTF-8
+
+=head1 'TOP' AND 'BOTTOM' OF THE STACK
+
+When describing the methods of the trace object, I use the words 'top' and
+'bottom'. In this context, the 'top' frame on the stack is the most recent
+frame and the 'bottom' is the least recent.
+
+Here's an example:
+
+ foo(); # bottom frame is here
+
+ sub foo {
+ bar();
+ }
+
+ sub bar {
+ Devel::StackTrace->new(); # top frame is here.
+ }
+
+=head1 METHODS
+
+This class provide the following methods:
+
+=head2 Devel::StackTrace->new(%named_params)
+
+Returns a new Devel::StackTrace object.
+
+Takes the following parameters:
+
+=over 4
+
+=item * frame_filter => $sub
+
+By default, Devel::StackTrace will include all stack frames before the
+call to its constructor.
+
+However, you may want to filter out some frames with more granularity
+than 'ignore_package' or 'ignore_class' allow.
+
+You can provide a subroutine which is called with the raw frame data
+for each frame. This is a hash reference with two keys, "caller", and
+"args", both of which are array references. The "caller" key is the
+raw data as returned by Perl's C<caller()> function, and the "args"
+key are the subroutine arguments found in C<@DB::args>.
+
+The filter should return true if the frame should be included, or
+false if it should be skipped.
+
+=item * filter_frames_early => $boolean
+
+If this parameter is true, C<frame_filter> will be called as soon as the
+stacktrace is created, and before refs are stringified (if
+C<unsafe_ref_capture> is not set), rather than being filtered lazily when
+L<Devel::StackTrace::Frame> objects are first needed.
+
+This is useful if you want to filter based on the frame's arguments and want
+to be able to examine object properties, for example.
+
+=item * ignore_package => $package_name OR \@package_names
+
+Any frames where the package is one of these packages will not be on
+the stack.
+
+=item * ignore_class => $package_name OR \@package_names
+
+Any frames where the package is a subclass of one of these packages
+(or is the same package) will not be on the stack.
+
+Devel::StackTrace internally adds itself to the 'ignore_package'
+parameter, meaning that the Devel::StackTrace package is B<ALWAYS>
+ignored. However, if you create a subclass of Devel::StackTrace it
+will not be ignored.
+
+=item * skip_frames => $integer
+
+This will cause this number of stack frames to be excluded from top of the
+stack trace. This prevents the frames from being captured at all, and applies
+before the C<frame_filter>, C<ignore_package>, or C<ignore_class> options,
+even with C<filter_frames_early>.
+
+=item * unsafe_ref_capture => $boolean
+
+If this parameter is true, then Devel::StackTrace will store
+references internally when generating stacktrace frames.
+
+B<This option is very dangerous, and should never be used with exception
+objects>. Using this option will keep any objects or references alive past
+their normal lifetime, until the stack trace object goes out of scope. It can
+keep objects alive even after their C<DESTROY> sub is called, resulting it it
+being called multiple times on the same object.
+
+If not set, Devel::StackTrace replaces any references with their stringified
+representation.
+
+=item * no_args => $boolean
+
+If this parameter is true, then Devel::StackTrace will not store caller
+arguments in stack trace frames at all.
+
+=item * respect_overload => $boolean
+
+By default, Devel::StackTrace will call C<overload::AddrRef()> to get
+the underlying string representation of an object, instead of
+respecting the object's stringification overloading. If you would
+prefer to see the overloaded representation of objects in stack
+traces, then set this parameter to true.
+
+=item * max_arg_length => $integer
+
+By default, Devel::StackTrace will display the entire argument for each
+subroutine call. Setting this parameter causes truncates each subroutine
+argument's string representation if it is longer than this number of
+characters.
+
+=item * message => $string
+
+By default, Devel::StackTrace will use 'Trace begun' as the message for the
+first stack frame when you call C<as_string>. You can supply an alternative
+message using this option.
+
+=item * indent => $boolean
+
+If this parameter is true, each stack frame after the first will start with a
+tab character, just like C<Carp::confess()>.
+
+=back
+
+=head2 $trace->next_frame()
+
+Returns the next L<Devel::StackTrace::Frame> object on the stack, going
+down. If this method hasn't been called before it returns the first frame. It
+returns C<undef> when it reaches the bottom of the stack and then resets its
+pointer so the next call to C<< $trace->next_frame() >> or C<<
+$trace->prev_frame() >> will work properly.
+
+=head2 $trace->prev_frame()
+
+Returns the next L<Devel::StackTrace::Frame> object on the stack, going up. If
+this method hasn't been called before it returns the last frame. It returns
+undef when it reaches the top of the stack and then resets its pointer so the
+next call to C<< $trace->next_frame() >> or C<< $trace->prev_frame() >> will
+work properly.
+
+=head2 $trace->reset_pointer
+
+Resets the pointer so that the next call to C<< $trace->next_frame() >> or C<<
+$trace->prev_frame() >> will start at the top or bottom of the stack, as
+appropriate.
+
+=head2 $trace->frames()
+
+When this method is called with no arguments, it returns a list of
+L<Devel::StackTrace::Frame> objects. They are returned in order from top (most
+recent) to bottom.
+
+This method can also be used to set the object's frames if you pass it a list
+of L<Devel::StackTrace::Frame> objects.
+
+This is useful if you want to filter the list of frames in ways that are more
+complex than can be handled by the C<< $trace->filter_frames() >> method:
+
+ $stacktrace->frames( my_filter( $stacktrace->frames() ) );
+
+=head2 $trace->frame($index)
+
+Given an index, this method returns the relevant frame, or undef if there is
+no frame at that index. The index is exactly like a Perl array. The first
+frame is 0 and negative indexes are allowed.
+
+=head2 $trace->frame_count()
+
+Returns the number of frames in the trace object.
+
+=head2 $trace->as_string(\%p)
+
+Calls C<< $frame->as_string() >> on each frame from top to bottom, producing
+output quite similar to the Carp module's cluck/confess methods.
+
+The optional C<\%p> parameter only has one option. The C<max_arg_length>
+parameter truncates each subroutine argument's string representation if it is
+longer than this number of characters.
+
+=head1 SUPPORT
+
+Please submit bugs to the CPAN RT system at
+http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel%3A%3AStackTrace
+or via email at bug-devel-stacktrace@rt.cpan.org.
+
+=head1 AUTHOR
+
+Dave Rolsky <autarch@urth.org>
+
+=head1 CONTRIBUTORS
+
+=for stopwords Dagfinn Ilmari Mannsåker David Cantrell Graham Knop Ricardo Signes
+
+=over 4
+
+=item *
+
+Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
+
+=item *
+
+David Cantrell <david@cantrell.org.uk>
+
+=item *
+
+Graham Knop <haarg@haarg.org>
+
+=item *
+
+Ricardo Signes <rjbs@cpan.org>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is Copyright (c) 2000 - 2014 by David Rolsky.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)
+
+=cut
diff --git a/lib/Devel/StackTrace/Frame.pm b/lib/Devel/StackTrace/Frame.pm
new file mode 100644
index 0000000..aad497a
--- /dev/null
+++ b/lib/Devel/StackTrace/Frame.pm
@@ -0,0 +1,216 @@
+package Devel::StackTrace::Frame;
+$Devel::StackTrace::Frame::VERSION = '2.00';
+use strict;
+use warnings;
+
+# Create accessor routines
+BEGIN {
+ no strict 'refs';
+ foreach my $f (
+ qw( package filename line subroutine hasargs
+ wantarray evaltext is_require hints bitmask args )
+ ) {
+ next if $f eq 'args';
+ *{$f} = sub { my $s = shift; return $s->{$f} };
+ }
+}
+
+{
+ my @fields = (
+ qw( package filename line subroutine hasargs wantarray
+ evaltext is_require hints bitmask )
+ );
+
+ sub new {
+ my $proto = shift;
+ my $class = ref $proto || $proto;
+
+ my $self = bless {}, $class;
+
+ @{$self}{@fields} = @{ shift() };
+
+ # fixup unix-style paths on win32
+ $self->{filename} = File::Spec->canonpath( $self->{filename} );
+
+ $self->{args} = shift;
+
+ $self->{respect_overload} = shift;
+
+ $self->{max_arg_length} = shift;
+
+ $self->{message} = shift;
+
+ $self->{indent} = shift;
+
+ return $self;
+ }
+}
+
+sub args {
+ my $self = shift;
+
+ return @{ $self->{args} };
+}
+
+sub as_string {
+ my $self = shift;
+ my $first = shift;
+ my $p = shift;
+
+ my $sub = $self->subroutine;
+
+ # This code stolen straight from Carp.pm and then tweaked. All
+ # errors are probably my fault -dave
+ if ($first) {
+ $sub
+ = defined $self->{message}
+ ? $self->{message}
+ : 'Trace begun';
+ }
+ else {
+
+ # Build a string, $sub, which names the sub-routine called.
+ # This may also be "require ...", "eval '...' or "eval {...}"
+ if ( my $eval = $self->evaltext ) {
+ if ( $self->is_require ) {
+ $sub = "require $eval";
+ }
+ else {
+ $eval =~ s/([\\\'])/\\$1/g;
+ $sub = "eval '$eval'";
+ }
+ }
+ elsif ( $sub eq '(eval)' ) {
+ $sub = 'eval {...}';
+ }
+
+ # if there are any arguments in the sub-routine call, format
+ # them according to the format variables defined earlier in
+ # this file and join them onto the $sub sub-routine string
+ #
+ # We copy them because they're going to be modified.
+ #
+ if ( my @a = $self->args ) {
+ for (@a) {
+
+ # set args to the string "undef" if undefined
+ $_ = "undef", next unless defined $_;
+
+ # hack!
+ $_ = $self->Devel::StackTrace::_ref_to_string($_)
+ if ref $_;
+
+ local $SIG{__DIE__};
+ local $@;
+
+ eval {
+ my $max_arg_length
+ = exists $p->{max_arg_length}
+ ? $p->{max_arg_length}
+ : $self->{max_arg_length};
+
+ if ( $max_arg_length
+ && length $_ > $max_arg_length ) {
+ substr( $_, $max_arg_length ) = '...';
+ }
+
+ s/'/\\'/g;
+
+ # 'quote' arg unless it looks like a number
+ $_ = "'$_'" unless /^-?[\d.]+$/;
+
+ # print control/high ASCII chars as 'M-<char>' or '^<char>'
+ s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
+ s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
+ };
+
+ if ( my $e = $@ ) {
+ $_ = $e =~ /malformed utf-8/i ? '(bad utf-8)' : '?';
+ }
+ }
+
+ # append ('all', 'the', 'arguments') to the $sub string
+ $sub .= '(' . join( ', ', @a ) . ')';
+ $sub .= ' called';
+ }
+ }
+
+ # If the user opted into indentation (a la Carp::confess), pre-add a tab
+ my $tab = $self->{indent} && !$first ? "\t" : q{};
+
+ return "${tab}$sub at " . $self->filename . ' line ' . $self->line;
+}
+
+1;
+
+# ABSTRACT: A single frame in a stack trace
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Devel::StackTrace::Frame - A single frame in a stack trace
+
+=head1 VERSION
+
+version 2.00
+
+=head1 DESCRIPTION
+
+See L<Devel::StackTrace> for details.
+
+=for Pod::Coverage new
+
+=head1 METHODS
+
+See Perl's C<caller()> documentation for more information on what these
+methods return.
+
+=head2 $frame->package()
+
+=head2 $frame->filename()
+
+=head2 $frame->line()
+
+=head2 $frame->subroutine()
+
+=head2 $frame->hasargs()
+
+=head2 $frame->wantarray()
+
+=head2 $frame->evaltext()
+
+Returns undef if the frame was not part of an eval.
+
+=head2 $frame->is_require()
+
+Returns undef if the frame was not part of a require.
+
+=head2 $frame->args()
+
+Returns the arguments passed to the frame. Note that any arguments that are
+references are returned as references, not copies.
+
+=head2 $frame->hints()
+
+=head2 $frame->bitmask()
+
+=head2 $frame->as_string()
+
+Returns a string containing a description of the frame.
+
+=head1 AUTHOR
+
+Dave Rolsky <autarch@urth.org>
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is Copyright (c) 2000 - 2014 by David Rolsky.
+
+This is free software, licensed under:
+
+ The Artistic License 2.0 (GPL Compatible)
+
+=cut
diff --git a/t/00-compile.t b/t/00-compile.t
new file mode 100644
index 0000000..b69d9cd
--- /dev/null
+++ b/t/00-compile.t
@@ -0,0 +1,52 @@
+use 5.006;
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.051
+
+use Test::More;
+
+plan tests => 2 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+
+my @module_files = (
+ 'Devel/StackTrace.pm',
+ 'Devel/StackTrace/Frame.pm'
+);
+
+
+
+# no fake home requested
+
+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..4425a79
--- /dev/null
+++ b/t/00-report-prereqs.dd
@@ -0,0 +1,46 @@
+do { my $x = {
+ 'configure' => {
+ 'requires' => {
+ 'ExtUtils::MakeMaker' => '0'
+ }
+ },
+ 'develop' => {
+ 'requires' => {
+ 'Pod::Coverage::TrustPod' => '0',
+ 'Test::CPAN::Changes' => '0.19',
+ 'Test::EOL' => '0',
+ 'Test::More' => '0.88',
+ 'Test::NoTabs' => '0',
+ 'Test::Pod' => '1.41',
+ 'Test::Pod::Coverage' => '1.08',
+ 'Test::Spelling' => '0.12',
+ 'Test::Synopsis' => '0'
+ }
+ },
+ 'runtime' => {
+ 'requires' => {
+ 'File::Spec' => '0',
+ 'Scalar::Util' => '0',
+ 'overload' => '0',
+ 'perl' => '5.006',
+ 'strict' => '0',
+ 'warnings' => '0'
+ }
+ },
+ 'test' => {
+ 'recommends' => {
+ 'CPAN::Meta' => '2.120900'
+ },
+ 'requires' => {
+ 'ExtUtils::MakeMaker' => '0',
+ 'File::Spec' => '0',
+ 'IO::Handle' => '0',
+ 'IPC::Open3' => '0',
+ 'Test::More' => '0.88',
+ 'base' => '0',
+ 'bytes' => '0'
+ }
+ }
+ };
+ $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..402b3d9
--- /dev/null
+++ b/t/00-report-prereqs.t
@@ -0,0 +1,176 @@
+#!perl
+
+use strict;
+use warnings;
+
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.019
+
+use Test::More tests => 1;
+
+use ExtUtils::MakeMaker;
+use File::Spec;
+
+# from $version::LAX
+my $lax_version_re =
+ qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
+ |
+ (?:\.[0-9]+) (?:_[0-9]+)?
+ ) | (?:
+ v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
+ |
+ (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
+ )
+ )/x;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_pre = "CPAN::Meta::Prereqs";
+my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _max {
+ my $max = shift;
+ $max = ( $_ > $max ) ? $_ : $max for @_;
+ return $max;
+}
+
+sub _merge_prereqs {
+ my ($collector, $prereqs) = @_;
+
+ # CPAN::Meta::Prereqs object
+ if (ref $collector eq $cpan_meta_pre) {
+ return $collector->with_merged_prereqs(
+ CPAN::Meta::Prereqs->new( $prereqs )
+ );
+ }
+
+ # Raw hashrefs
+ for my $phase ( keys %$prereqs ) {
+ for my $type ( keys %{ $prereqs->{$phase} } ) {
+ for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
+ $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
+ }
+ }
+ }
+
+ return $collector;
+}
+
+my @include = qw(
+
+);
+
+my @exclude = qw(
+
+);
+
+# Add static prereqs to the included modules list
+my $static_prereqs = do 't/00-report-prereqs.dd';
+
+# Merge all prereqs (either with ::Prereqs or a hashref)
+my $full_prereqs = _merge_prereqs(
+ ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
+ $static_prereqs
+);
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META ) {
+ if ( my $meta = eval { CPAN::Meta->load_file($source) } ) {
+ $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
+ }
+}
+else {
+ $source = 'static metadata';
+}
+
+my @full_reports;
+my @dep_errors;
+my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
+
+# Add static includes into a fake section
+for my $mod (@include) {
+ $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
+ next unless $req_hash->{$phase};
+ next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
+
+ for my $type ( qw(requires recommends suggests conflicts modules) ) {
+ next unless $req_hash->{$phase}{$type};
+
+ my $title = ucfirst($phase).' '.ucfirst($type);
+ my @reports = [qw/Module Want Have/];
+
+ for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
+ next if $mod eq 'perl';
+ next if grep { $_ eq $mod } @exclude;
+
+ my $file = $mod;
+ $file =~ s{::}{/}g;
+ $file .= ".pm";
+ my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
+
+ my $want = $req_hash->{$phase}{$type}{$mod};
+ $want = "undef" unless defined $want;
+ $want = "any" if !$want && $want == 0;
+
+ my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
+
+ if ($prefix) {
+ my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
+ $have = "undef" unless defined $have;
+ push @reports, [$mod, $want, $have];
+
+ if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
+ if ( $have !~ /\A$lax_version_re\z/ ) {
+ push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
+ }
+ elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
+ push @dep_errors, "$mod version '$have' is not in required range '$want'";
+ }
+ }
+ }
+ else {
+ push @reports, [$mod, $want, "missing"];
+
+ if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
+ push @dep_errors, "$mod is not installed ($req_string)";
+ }
+ }
+ }
+
+ if ( @reports ) {
+ push @full_reports, "=== $title ===\n\n";
+
+ my $ml = _max( map { length $_->[0] } @reports );
+ my $wl = _max( map { length $_->[1] } @reports );
+ my $hl = _max( map { length $_->[2] } @reports );
+ 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/01-basic.t b/t/01-basic.t
new file mode 100644
index 0000000..4af30ee
--- /dev/null
+++ b/t/01-basic.t
@@ -0,0 +1,573 @@
+use strict;
+use warnings;
+
+use Test::More 0.88;
+
+use Devel::StackTrace;
+
+sub get_file_name { File::Spec->canonpath( ( caller(0) )[1] ) }
+my $test_file_name = get_file_name();
+
+# Test all accessors
+{
+ my $trace = foo();
+
+ my @f = ();
+ while ( my $f = $trace->prev_frame ) { push @f, $f; }
+
+ my $cnt = scalar @f;
+ is(
+ $cnt, 4,
+ "Trace should have 4 frames"
+ );
+
+ @f = ();
+ while ( my $f = $trace->next_frame ) { push @f, $f; }
+
+ $cnt = scalar @f;
+ is(
+ $cnt, 4,
+ "Trace should have 4 frames"
+ );
+
+ is(
+ $f[0]->package, 'main',
+ "First frame package should be main"
+ );
+
+ is(
+ $f[0]->filename, $test_file_name,
+ "First frame filename should be $test_file_name"
+ );
+
+ is( $f[0]->line, 1009, "First frame line should be 1009" );
+
+ is(
+ $f[0]->subroutine, 'Devel::StackTrace::new',
+ "First frame subroutine should be Devel::StackTrace::new"
+ );
+
+ is( $f[0]->hasargs, 1, "First frame hasargs should be true" );
+
+ ok(
+ !$f[0]->wantarray,
+ "First frame wantarray should be false"
+ );
+
+ my $trace_text = <<"EOF";
+Trace begun at $test_file_name line 1009
+main::baz(1, 2) called at $test_file_name line 1005
+main::bar(1) called at $test_file_name line 1001
+main::foo at $test_file_name line 13
+EOF
+
+ is( $trace->as_string, $trace_text, 'trace text' );
+}
+
+# Test constructor params
+{
+ my $trace = SubTest::foo( ignore_class => 'Test' );
+
+ my @f = ();
+ while ( my $f = $trace->prev_frame ) { push @f, $f; }
+
+ my $cnt = scalar @f;
+
+ is( $cnt, 1, "Trace should have 1 frame" );
+
+ is(
+ $f[0]->package, 'main',
+ "The package for this frame should be main"
+ );
+
+ $trace = Test::foo( ignore_class => 'Test' );
+
+ @f = ();
+ while ( my $f = $trace->prev_frame ) { push @f, $f; }
+
+ $cnt = scalar @f;
+
+ is( $cnt, 1, "Trace should have 1 frame" );
+ is(
+ $f[0]->package, 'main',
+ "The package for this frame should be main"
+ );
+}
+
+# 15 - stringification overloading
+{
+ my $trace = baz();
+
+ my $trace_text = <<"EOF";
+Trace begun at $test_file_name line 1009
+main::baz at $test_file_name line 99
+EOF
+
+ my $t = "$trace";
+ is( $t, $trace_text, 'trace text' );
+}
+
+# 16-18 - frame_count, frame, reset_pointer, frames methods
+{
+ my $trace = foo();
+
+ is(
+ $trace->frame_count, 4,
+ "Trace should have 4 frames"
+ );
+
+ my $f = $trace->frame(2);
+
+ is(
+ $f->subroutine, 'main::bar',
+ "Frame 2's subroutine should be 'main::bar'"
+ );
+
+ $trace->next_frame;
+ $trace->next_frame;
+ $trace->reset_pointer;
+
+ $f = $trace->next_frame;
+ is(
+ $f->subroutine, 'Devel::StackTrace::new',
+ "next_frame should return first frame after call to reset_pointer"
+ );
+
+ my @f = $trace->frames;
+ is(
+ scalar @f, 4,
+ "frames method should return four frames"
+ );
+
+ is(
+ $f[0]->subroutine, 'Devel::StackTrace::new',
+ "first frame's subroutine should be Devel::StackTrace::new"
+ );
+
+ is(
+ $f[3]->subroutine, 'main::foo',
+ "last frame's subroutine should be main::foo"
+ );
+}
+
+# Not storing references
+{
+ my $obj = RefTest->new;
+
+ my $trace = $obj->{trace};
+
+ my $call_to_trace = ( $trace->frames )[1];
+
+ my @args = $call_to_trace->args;
+
+ is(
+ scalar @args, 1,
+ "Only one argument should have been passed in the call to trace()"
+ );
+
+ like(
+ $args[0], qr/RefTest=HASH/,
+ "Actual object should be replaced by string 'RefTest=HASH'"
+ );
+}
+
+# Storing references
+{
+ my $obj = RefTest2->new;
+
+ my $trace = $obj->{trace};
+
+ my $call_to_trace = ( $trace->frames )[1];
+
+ my @args = $call_to_trace->args;
+
+ is(
+ scalar @args, 1,
+ "Only one argument should have been passed in the call to trace()"
+ );
+
+ isa_ok( $args[0], 'RefTest2' );
+}
+
+# Storing references (deprecated interface 1)
+{
+ my $obj = RefTestDep1->new;
+
+ my $trace = $obj->{trace};
+
+ my $call_to_trace = ( $trace->frames )[1];
+
+ my @args = $call_to_trace->args;
+
+ is(
+ scalar @args, 1,
+ "Only one argument should have been passed in the call to trace()"
+ );
+
+ isa_ok( $args[0], 'RefTestDep1' );
+}
+
+# No ref to Exception::Class::Base object without refs
+if ( $Exception::Class::VERSION && $Exception::Class::VERSION >= 1.09 )
+{
+ eval {
+ Exception::Class::Base->throw(
+ error => 'error',
+ show_trace => 1,
+ );
+ };
+ my $exc = $@;
+ eval { quux($exc) };
+
+ ok( !$@, 'create stacktrace with no refs and exception object on stack' );
+}
+
+{
+ sub FooBar::some_sub { return Devel::StackTrace->new }
+
+ my $trace = eval { FooBar::some_sub('args') };
+
+ my $f = ( $trace->frames )[2];
+
+ is( $f->subroutine, '(eval)', 'subroutine is (eval)' );
+
+ my @args = $f->args;
+
+ is( scalar @args, 0, 'no args given to eval block' );
+}
+
+{
+ {
+ package #hide
+ FooBarBaz;
+
+ sub func2 {
+ return Devel::StackTrace->new( ignore_package => qr/^FooBar/ );
+ }
+ sub func1 { FooBarBaz::func2() }
+ }
+
+ my $trace = FooBarBaz::func1('args');
+
+ my @f = $trace->frames;
+
+ is( scalar @f, 1, 'check regex as ignore_package arg' );
+}
+
+{
+ package #hide
+ StringOverloaded;
+
+ use overload '""' => sub { 'overloaded' };
+}
+
+{
+ my $o = bless {}, 'StringOverloaded';
+
+ my $trace = baz($o);
+
+ unlike(
+ $trace->as_string, qr/\boverloaded\b/,
+ 'overloading is ignored by default'
+ );
+}
+
+{
+ my $o = bless {}, 'StringOverloaded';
+
+ my $trace = respect_overloading($o);
+
+ like(
+ $trace->as_string, qr/\boverloaded\b/,
+ 'overloading is ignored by default'
+ );
+}
+
+{
+ package #hide
+ BlowOnCan;
+
+ sub can { die 'foo' }
+}
+
+{
+ my $o = bless {}, 'BlowOnCan';
+
+ my $trace = baz($o);
+
+ like(
+ $trace->as_string, qr/BlowOnCan/,
+ 'death in overload::Overloaded is ignored'
+ );
+}
+
+{
+ my $trace = max_arg_length('abcdefghijklmnop');
+
+ my $trace_text = <<"EOF";
+Trace begun at $test_file_name line 1021
+main::max_arg_length('abcdefghij...') called at $test_file_name line 305
+EOF
+
+ is( $trace->as_string, $trace_text, 'trace text' );
+
+ my $trace_text_1 = <<"EOF";
+Trace begun at $test_file_name line 1021
+main::max_arg_length('abc...') called at $test_file_name line 305
+EOF
+
+ is(
+ $trace->as_string( { max_arg_length => 3 } ),
+ $trace_text_1,
+ 'trace text, max_arg_length = 3',
+ );
+}
+
+SKIP:
+{
+ skip "Test only runs on Linux", 1
+ unless $^O eq 'linux';
+
+ my $frame = Devel::StackTrace::Frame->new(
+ [ 'Foo', 'foo/bar///baz.pm', 10, 'bar', 1, 1, '', 0 ],
+ []
+ );
+
+ is( $frame->filename, 'foo/bar/baz.pm', 'filename is canonicalized' );
+}
+
+{
+ my $obj = RefTest4->new();
+
+ my $trace = $obj->{trace};
+
+ ok(
+ ( !grep { ref $_ } map { @{ $_->{args} } } @{ $trace->{raw} } ),
+ 'raw data does not contain any references when unsafe_ref_capture not set'
+ );
+
+ is(
+ $trace->{raw}[1]{args}[1], 'not a ref',
+ 'non-refs are preserved properly in raw data as well'
+ );
+}
+
+{
+ my $trace = overload_no_stringify( CodeOverload->new() );
+
+ eval { $trace->as_string() };
+
+ is(
+ $@, q{},
+ 'no error when respect_overload is true and object overloads but does not stringify'
+ );
+}
+
+{
+ my $trace = Filter::foo();
+
+ my @frames = $trace->frames();
+ is( scalar @frames, 2, 'frame_filtered trace has just 2 frames' );
+ is(
+ $frames[0]->subroutine(), 'Devel::StackTrace::new',
+ 'first subroutine'
+ );
+ is(
+ $frames[1]->subroutine(), 'Filter::bar',
+ 'second subroutine (skipped Filter::foo)'
+ );
+}
+
+{
+ my $trace = FilterAllFrames::a_foo();
+
+ my @frames = $trace->frames();
+ is(
+ scalar @frames, 2,
+ 'after filtering whole list of frames, got just 2 frames'
+ );
+ is(
+ $frames[0]->subroutine(), 'FilterAllFrames::a_bar',
+ 'first subroutine'
+ );
+ is(
+ $frames[1]->subroutine(), 'FilterAllFrames::a_foo',
+ 'second subroutine'
+ );
+}
+
+done_testing();
+
+# This means I can move these lines down without constantly fiddling
+# with the checks for line numbers in the tests.
+
+#line 1000
+sub foo {
+ bar( @_, 1 );
+}
+
+sub bar {
+ baz( @_, 2 );
+}
+
+sub baz {
+ Devel::StackTrace->new( @_ ? @_[ 0, 1 ] : () );
+}
+
+sub quux {
+ Devel::StackTrace->new();
+}
+
+sub respect_overloading {
+ Devel::StackTrace->new( respect_overload => 1 );
+}
+
+sub max_arg_length {
+ Devel::StackTrace->new( max_arg_length => 10 );
+}
+
+sub overload_no_stringify {
+ return Devel::StackTrace->new( respect_overload => 1 );
+}
+
+{
+ package #hide
+ Test;
+
+ sub foo {
+ trace(@_);
+ }
+
+ sub trace {
+ Devel::StackTrace->new(@_);
+ }
+}
+
+{
+ package #hide
+ SubTest;
+
+ use base qw(Test);
+
+ sub foo {
+ trace(@_);
+ }
+
+ sub trace {
+ Devel::StackTrace->new(@_);
+ }
+}
+
+{
+ package #hide
+ RefTest;
+
+ sub new {
+ my $self = bless {}, shift;
+
+ $self->{trace} = trace($self);
+
+ return $self;
+ }
+
+ sub trace {
+ Devel::StackTrace->new();
+ }
+}
+
+{
+ package #hide
+ RefTest2;
+
+ sub new {
+ my $self = bless {}, shift;
+
+ $self->{trace} = trace($self);
+
+ return $self;
+ }
+
+ sub trace {
+ Devel::StackTrace->new( unsafe_ref_capture => 1 );
+ }
+}
+
+{
+ package #hide
+ RefTestDep1;
+
+ sub new {
+ my $self = bless {}, shift;
+
+ $self->{trace} = trace($self);
+
+ return $self;
+ }
+
+ sub trace {
+ Devel::StackTrace->new( no_refs => 0 );
+ }
+}
+
+{
+ package #hide
+ RefTest4;
+
+ sub new {
+ my $self = bless {}, shift;
+
+ $self->{trace} = trace( $self, 'not a ref' );
+
+ return $self;
+ }
+
+ sub trace {
+ Devel::StackTrace->new();
+ }
+}
+
+{
+ package #hide
+ CodeOverload;
+
+ use overload '&{}' => sub { 'foo' };
+
+ sub new {
+ my $class = shift;
+ return bless {}, $class;
+ }
+}
+
+{
+ package #hide
+ Filter;
+
+ sub foo {
+ bar();
+ }
+
+ sub bar {
+ return Devel::StackTrace->new(
+ frame_filter => sub { $_[0]{caller}[3] ne 'Filter::foo' } );
+ }
+}
+
+{
+ package #hide
+ FilterAllFrames;
+
+ sub a_foo { b_foo() }
+ sub b_foo { a_bar() }
+ sub a_bar { b_bar() }
+
+ sub b_bar {
+ my $stacktrace = Devel::StackTrace->new();
+ $stacktrace->frames( only_a_frames( $stacktrace->frames() ) );
+ return $stacktrace;
+ }
+
+ sub only_a_frames {
+ my @frames = @_;
+ return grep { $_->subroutine() =~ /^FilterAllFrames::a/ } @frames;
+ }
+}
diff --git a/t/02-bad-utf8.t b/t/02-bad-utf8.t
new file mode 100644
index 0000000..0574553
--- /dev/null
+++ b/t/02-bad-utf8.t
@@ -0,0 +1,40 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+eval 'use Encode';
+plan skip_all => 'These tests require Encode.pm'
+ unless eval 'use Encode; 1';
+
+plan skip_all => 'These tests require Perl 5.8.8+'
+ unless $] >= 5.008008;
+
+plan skip_all => 'These tests are not relevant with Perl 5.13.8+'
+ if $] >= 5.013008;
+
+use Devel::StackTrace;
+
+# This should be invalid UTF8
+my $raw_bad = do { use bytes; chr(0xED) . chr(0xA1) . chr(0xBA) };
+
+my $decoded = Encode::decode( 'utf8' => $raw_bad );
+my $trace = foo($decoded);
+
+my $string = eval { $trace->as_string() };
+
+my $e = $@;
+is(
+ $e, '',
+ 'as_string() does not throw an exception'
+);
+like(
+ $string, qr/\Q(bad utf-8)/,
+ 'stringified output notes bad utf-8'
+);
+
+sub foo {
+ Devel::StackTrace->new();
+}
+
+done_testing();
diff --git a/t/03-message.t b/t/03-message.t
new file mode 100644
index 0000000..50eb219
--- /dev/null
+++ b/t/03-message.t
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+sub foo {
+ return Devel::StackTrace->new(@_);
+}
+
+sub make_dst {
+ foo(@_);
+}
+
+{
+ my $dst = make_dst();
+
+ like(
+ $dst->as_string(), qr/^Trace begun/,
+ q{default message is "Trace begun"}
+ );
+}
+
+{
+ my $dst = make_dst( message => 'Foo bar' );
+
+ like(
+ $dst->as_string(), qr/^Foo bar/,
+ q{set explicit message for trace}
+ );
+}
+
+done_testing();
diff --git a/t/04-indent.t b/t/04-indent.t
new file mode 100644
index 0000000..5b0391c
--- /dev/null
+++ b/t/04-indent.t
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+sub foo {
+ return Devel::StackTrace->new(@_);
+}
+
+sub make_dst {
+ foo(@_);
+}
+
+{
+ my $dst = make_dst();
+
+ for my $line ( split /\n/, $dst->as_string() ) {
+ unlike( $line, qr/^\s/, 'line does not start with whitespace' );
+ }
+}
+
+{
+ my $dst = make_dst( indent => 1 );
+
+ my @lines = split /\n/, $dst->as_string();
+ shift @lines;
+
+ for my $line (@lines) {
+ like( $line, qr/^\s/, 'line starts with whitespace' );
+ }
+}
+
+done_testing();
diff --git a/t/05-back-compat.t b/t/05-back-compat.t
new file mode 100644
index 0000000..3b0c4fc
--- /dev/null
+++ b/t/05-back-compat.t
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+isa_ok( 'Devel::StackTraceFrame', 'Devel::StackTrace::Frame' );
+
+done_testing();
diff --git a/t/06-dollar-at.t b/t/06-dollar-at.t
new file mode 100644
index 0000000..fdf061a
--- /dev/null
+++ b/t/06-dollar-at.t
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+{
+ $@ = my $msg = q{Don't tread on me};
+
+ Devel::StackTrace->new()->frame(0)->as_string();
+
+ is( $@, $msg, '$@ is not overwritten in as_string() method' );
+}
+
+{
+ $@ = my $msg = q{Don't tread on me};
+
+ Devel::StackTrace->new( ignore_package => 'Foo' )->frames();
+
+ is( $@, $msg, '$@ is not overwritten in _make_filter() method' );
+}
+
+done_testing();
diff --git a/t/07-no-args.t b/t/07-no-args.t
new file mode 100644
index 0000000..7bdc166
--- /dev/null
+++ b/t/07-no-args.t
@@ -0,0 +1,45 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+{
+ my $trace = foo( 1, 2 );
+ is_deeply(
+ [ map { [ $_->args() ] } $trace->frames() ],
+ [
+ ['Devel::StackTrace'],
+ [ 3, 4 ],
+ [ 1, 2 ],
+ ],
+ 'trace includes args'
+ );
+
+ $trace = foo( 0, 2 );
+ is_deeply(
+ [ map { [ $_->args() ] } $trace->frames() ],
+ [
+ [],
+ [],
+ [],
+ ],
+ 'trace does not include args'
+ );
+
+}
+
+done_testing();
+
+sub foo {
+ $_[0] ? bar( 3, 4 ) : baz( 3, 4 );
+}
+
+sub bar {
+ return Devel::StackTrace->new();
+}
+
+sub baz {
+ return Devel::StackTrace->new( no_args => 1 );
+}
diff --git a/t/08-filter-early.t b/t/08-filter-early.t
new file mode 100644
index 0000000..3471a4d
--- /dev/null
+++ b/t/08-filter-early.t
@@ -0,0 +1,31 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+{
+ my $trace = foo( [] );
+ is(
+ 0 + grep( ref, map { $_->args } $trace->frames ), 0,
+ 'args stringified in trace'
+ );
+}
+
+done_testing();
+
+sub foo {
+ return Devel::StackTrace->new(
+ frame_filter => sub {
+ my $frame = shift;
+ if ( $frame->{caller}[3] eq "main::foo" ) {
+ ok( ref $frame->{args}[0], 'ref arg passed to filter' );
+ }
+ 1;
+ },
+ filter_frames_early => 1,
+ no_refs => 1,
+ );
+}
+
diff --git a/t/09-skip-frames.t b/t/09-skip-frames.t
new file mode 100644
index 0000000..3834e68
--- /dev/null
+++ b/t/09-skip-frames.t
@@ -0,0 +1,41 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use Devel::StackTrace;
+
+{
+ my $trace = baz();
+ my @f;
+ while ( my $f = $trace->next_frame ) { push @f, $f; }
+
+ my $cnt = scalar @f;
+ is(
+ $cnt, 2,
+ "Trace should have 2 frames"
+ );
+
+ is(
+ $f[0]->subroutine, 'main::bar',
+ "First frame subroutine should be main::bar"
+ );
+ is(
+ $f[1]->subroutine, 'main::baz',
+ "First frame subroutine should be main::baz"
+ );
+}
+
+done_testing();
+
+sub foo {
+ return Devel::StackTrace->new( skip_frames => 2 );
+}
+
+sub bar {
+ foo();
+}
+
+sub baz {
+ bar();
+}
diff --git a/t/author-eol.t b/t/author-eol.t
new file mode 100644
index 0000000..2348cd2
--- /dev/null
+++ b/t/author-eol.t
@@ -0,0 +1,16 @@
+
+BEGIN {
+ unless ($ENV{AUTHOR_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for testing by the author');
+ }
+}
+
+use strict;
+use warnings;
+use Test::More;
+
+# generated by Dist::Zilla::Plugin::Test::EOL 0.15
+use Test::EOL;
+
+all_perl_files_ok({ trailing_whitespace => 1 });
diff --git a/t/author-no-tabs.t b/t/author-no-tabs.t
new file mode 100644
index 0000000..3a99740
--- /dev/null
+++ b/t/author-no-tabs.t
@@ -0,0 +1,45 @@
+
+BEGIN {
+ unless ($ENV{AUTHOR_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for testing by the author');
+ }
+}
+
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.09
+
+use Test::More 0.88;
+use Test::NoTabs;
+
+my @files = (
+ 'lib/Devel/StackTrace.pm',
+ 'lib/Devel/StackTrace/Frame.pm',
+ 't/00-compile.t',
+ 't/00-report-prereqs.dd',
+ 't/00-report-prereqs.t',
+ 't/01-basic.t',
+ 't/02-bad-utf8.t',
+ 't/03-message.t',
+ 't/04-indent.t',
+ 't/05-back-compat.t',
+ 't/06-dollar-at.t',
+ 't/07-no-args.t',
+ 't/08-filter-early.t',
+ 't/09-skip-frames.t',
+ 't/author-eol.t',
+ 't/author-no-tabs.t',
+ 't/author-pod-spell.t',
+ 't/release-cpan-changes.t',
+ 't/release-pod-coverage.t',
+ 't/release-pod-linkcheck.t',
+ 't/release-pod-no404s.t',
+ 't/release-pod-syntax.t',
+ 't/release-portability.t',
+ 't/release-synopsis.t'
+);
+
+notabs_ok($_) foreach @files;
+done_testing;
diff --git a/t/author-pod-spell.t b/t/author-pod-spell.t
new file mode 100644
index 0000000..e687980
--- /dev/null
+++ b/t/author-pod-spell.t
@@ -0,0 +1,45 @@
+
+BEGIN {
+ unless ($ENV{AUTHOR_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for testing by the author');
+ }
+}
+
+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__
+DROLSKY
+DROLSKY's
+Rolsky
+Rolsky's
+CPAN
+stacktrace
+Dave
+autarch
+David
+Dagfinn
+Ilmari
+Mannsåker
+ilmari
+Cantrell
+david
+Graham
+Knop
+haarg
+Ricardo
+Signes
+rjbs
+lib
+Devel
+StackTrace
+Frame
diff --git a/t/release-cpan-changes.t b/t/release-cpan-changes.t
new file mode 100644
index 0000000..214650f
--- /dev/null
+++ b/t/release-cpan-changes.t
@@ -0,0 +1,19 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+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/t/release-pod-coverage.t b/t/release-pod-coverage.t
new file mode 100644
index 0000000..1f3b7b6
--- /dev/null
+++ b/t/release-pod-coverage.t
@@ -0,0 +1,43 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+# This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable.
+
+use Test::Pod::Coverage 1.08;
+use Test::More 0.88;
+use Pod::Coverage::TrustPod;
+
+my %skip = map { $_ => 1 } qw( );
+
+my @modules;
+for my $module ( all_modules() ) {
+ next if $skip{$module};
+
+ push @modules, $module;
+}
+
+plan skip_all => 'All the modules we found were excluded from POD coverage test.'
+ unless @modules;
+
+plan tests => scalar @modules;
+
+my %trustme = ();
+
+for my $module ( sort @modules ) {
+ pod_coverage_ok(
+ $module,
+ {
+ coverage_class => 'Pod::Coverage::TrustPod',
+ trustme => $trustme{$module} || [],
+ },
+ "pod coverage for $module"
+ );
+}
+
+done_testing();
diff --git a/t/release-pod-linkcheck.t b/t/release-pod-linkcheck.t
new file mode 100644
index 0000000..654cf06
--- /dev/null
+++ b/t/release-pod-linkcheck.t
@@ -0,0 +1,28 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+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/t/release-pod-no404s.t b/t/release-pod-no404s.t
new file mode 100644
index 0000000..da185ec
--- /dev/null
+++ b/t/release-pod-no404s.t
@@ -0,0 +1,29 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use strict;
+use warnings;
+use Test::More;
+
+foreach my $env_skip ( qw(
+ SKIP_POD_NO404S
+ AUTOMATED_TESTING
+) ){
+ plan skip_all => "\$ENV{$env_skip} is set, skipping"
+ if $ENV{$env_skip};
+}
+
+eval "use Test::Pod::No404s";
+if ( $@ ) {
+ plan skip_all => 'Test::Pod::No404s required for testing POD';
+}
+else {
+ all_pod_files_ok();
+}
diff --git a/t/release-pod-syntax.t b/t/release-pod-syntax.t
new file mode 100644
index 0000000..cdd6a6c
--- /dev/null
+++ b/t/release-pod-syntax.t
@@ -0,0 +1,14 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+# 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/t/release-portability.t b/t/release-portability.t
new file mode 100644
index 0000000..f0fd79f
--- /dev/null
+++ b/t/release-portability.t
@@ -0,0 +1,19 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use strict;
+use warnings;
+
+use Test::More;
+
+eval 'use Test::Portability::Files';
+plan skip_all => 'Test::Portability::Files required for testing portability'
+ if $@;
+run_tests();
diff --git a/t/release-synopsis.t b/t/release-synopsis.t
new file mode 100644
index 0000000..2d9b8ee
--- /dev/null
+++ b/t/release-synopsis.t
@@ -0,0 +1,13 @@
+#!perl
+
+BEGIN {
+ unless ($ENV{RELEASE_TESTING}) {
+ require Test::More;
+ Test::More::plan(skip_all => 'these tests are for release candidate testing');
+ }
+}
+
+
+use Test::Synopsis;
+
+all_synopsis_ok();
diff --git a/weaver.ini b/weaver.ini
new file mode 100644
index 0000000..90c76a6
--- /dev/null
+++ b/weaver.ini
@@ -0,0 +1,17 @@
+[@CorePrep]
+
+[Name]
+[Version]
+
+[Region / prelude]
+
+[Generic / SYNOPSIS]
+[Generic / DESCRIPTION]
+
+[Leftovers]
+
+[Region / postlude]
+
+[Authors]
+[Contributors]
+[Legal]