Devel-Cover-1.44000755000765000024 014631552031 12767 5ustar00pjcjstaff000000000000Changes100644000765000024 11023514631552031 14405 0ustar00pjcjstaff000000000000Devel-Cover-1.44Devel::Cover history 1.44 - 10 June 2024 - Test against 5.40 - Test with DBM::Deep on CI 1.43 - 8 June 2024 - Bump coancover version requirements to 5.38 - Format cpancover and Cover::Collection - Format main documentation - Tidy dc script - Remove dzil's .build from distribution (Graham Knop) (GH-337) 1.42 - 26 April 2024 - Improve tests 1.41 - 25 April 2024 - Spelling, linting and formatting changes 1.40 - 30 April 2023 - Note usage with dzil (Steve Rogerson) (GH-319) - Fix html_basic report (jkahrman) (GH-318) - Use CPAN::Meta (Slaven Rezić) (GH-314) - Make non-interactive output less noisy (jkahrman) (GH-312) - Avoid infinite recursion in Type::Tiny and other places (Ed J) (GH-307) - Add ignore_covered_err option (Tina Müller) (GH-323) - Handle empty hashes and arrays on condition RHS in 5.37.6 and later 1.39 - 29 April 2023 - Remove dependency on B::Debug (Jim Keenan) (GH-289) - Raise minimum version to 5.12 - Correct spelling of Pod::Coverage trustme parameter (Oliver Youle) (GH-302) - Fix annotations in html_basic report (Opera Wang) (GH-310) 1.38 - 5 June 2022 - Improve documentation 1.37 - 5 June 2022 - Fix Subroutine module docs (bkerin) (GH-262) - Use github actions instead of travis (Zakariyya Mughal) (GH-291) - Improve mkdir error messages (Felipe Gasper) (GH-296) - Remove asterisk from gcov count (Zakariyya Mughal) (GH-294) - Test against 5.36.0 - Avoid warnings from check_files (Nicolas R) (GH-292) - Support __SUB__ (Graham Knop) (GH-290, GH-243, GH-285) - Support uncoverable count ranges (Tina Müller) (GH-288) - Improve gcov support for XS code (Ed J) (GH-280) - Allow overriding of HTML code highlighting (Jesús Alonso Abad) (GH-271) - Improve contributing docs 1.36 - 19 May 2020 - Fix pod error - Quieten perltidy syntax highlighting errors - Fix up minimum perl version (Dick Franks) (GH-268) - Fix passing full path for cover DB (GH-267) 1.35 - 17 May 2020 - Replace "use vars" with "our" (James Raspass) (GH-255) - Remove tray db file from release - Don't chdir when given a -dir flag (Dave Rolsky) (GH-253) - Manage code references in @INC (Slaven Rezić) (GH-249, GH-250) 1.34 - 16 May 2020 - Minimum supported version is now 5.10.0 (Karen Etheridge) (GH-226) - Support 5.32 by accommodating signauture changes (GH-260) 1.33 - 26 April 2019 - Fix pod error (Mohammad S Anwar) (GH-240) - Work with cperl where class is a keyword (Reini Urban) (GH-238) - Restore correct behaviour on merging DBs (Daniel Egeberg) (GH-232) - Fix gcov output being on incorrect lines - Fix cover -test with Build.PL (Dagfinn Ilmari Mannsåker) (GH-241) 1.32 - 25 April 2019 - Test up to 5.26.3, 5.28.3 and 5.29.10 - Get dev environment working on MacOS - Fix up tests with recent Math::BigInt versions (Ed J) (GH-219) - Add progress text when processing coverage (Christian Walde) (GH-221) - Optionally use Term::Size (Paul "LeoNerd" Evans) (GH-228) - Fix indentation in pod (Graham Knop) (GH-229) - Fix warn precedence (Alexandr Evstigneev) (GH-231) 1.31 - 18 September 2018 - Add queue for cpancover (Joel Berger) - Handle circular refs (Ed J) (GH-164, GH-216) - Allow for $DEVEL_COVER_TEST_OPTS to be unset (Dick Franks) (GH-217) 1.30 - 14 July 2018 - Fix incorrect merging of structure (Emiliya Boyadjieva) (GH-199) - Fix up compiler warnings (Jens Rehsack) (GH-211) - Test against 5.28.0, 5.29.0 and some other versions - Compress and then delete old cpancover data - Clarify some docs around ignore (Olaf Alders) (GH-207) - Run coverage on cpp and hpp files (Jacques Germishuys) (GH-203) - Add docs for coverage of modules on command line (Slaven Rezić) (GH-204) - Ignore .AppleDouble files (David Cantrell) (GH-200) 1.29 - 15 October 2017 - Lock using read and append mode (Stephan Loyd) (GH-196) - Clean up lock files when running cover command 1.28 - 5 October 2017 - Fix typo in docs (Gregor Herrmann) (GH-195) - Fix up options to cover program (GH-194) 1.27 - 20 September 2017 - Test against 5.27.3 - Add dependency on B::Debug (Ryan Voots) (GH-189) - Remove obsolete dev and cpancover code - Manage multiple ignore and select options (Sullivan Beck) (GH-163) - Write top-level html last for better sorting (Christian Walde) (GH-158) - Restore XS coverage in cpancover (H.Merijn Brand) (GH-188) - Allow cpancover to run fully from local directory - Handle missing start times in runs (Chad Granum) (GH-190) - Add test for string eval (Sebastian Paaske Tørholm) (GH-145) - Improve uncoverable tests and docs (Kevin Brannen) (GH-167) - The cover program accepts multiple reports (Eden Hochbaum) (GH-172) - Add -prefer_lib option to cover script (Kent Fredric) (GH-91) - Fix low-level file locking (Graham Knop) (GH-90) 1.26 - 24 July 2017 - Untaint $DEVEL_COVER_OPTIONS (Alexey Sokolov) (GH-187) - Add loose_perms option (Todd Rinaldo) (GH-185) - Set EXTENDED_TESTING during cpancover runs - Improve version parsing for cpancover (Helmut Wollmersdorfer) (GH-124) - Improve cpancover code and documentation 1.25 - 11 May 2017 - Fix C code to work with MSVC (Marc-Philip) (GH-177) - Fix cover command using Module::Build on Win32 (sago35) (GH-160) - Add file and line info to keep ops unique (Niko Tyni) (GH-143) - Report coverage for all declarations (Heinz Knutzen) (GH-166) - Fix spelling mistakes (Gregor Herrmann) (GH-171) - Fix condition coverage for complex conditions (Heinz Knutzen) (GH-165) - Use JSON::MaybeXS for sppen and flexibility (Olivier Mengué) (GH-139) - Add CONTRIBUTING file (Gabor Szabó) (GH-100) 1.24 - 18 April 2017 - Work with 5.25.x (op_sibling) (Dan Collins, Matthew Horsfall) (GH-162) - Perl versions below 5.10.0 are now unsupported 1.23 - 24 April 2016 - Enhance html coverage popups (Haydn Newport) (GH-156) - Add cpancover about page (Guillermo O. Freschi) (GH-146) - Perl versions below 5.8.1 are now unsupported 1.22 - 9 April 2016 - Test against 5.20.3, 5.23.1 - 5.23.9, 5.22.1 - Improve uncoverable docs (Alex Balhatchet) (GH-148) - Improve cpancover 1.21 - 20 September 2015 - Test more versions on travis - Fix things up with cpancover for new docker release - Fix problem under 5.22 (Dick Franks) (GH-140) 1.20 - 6 July 2015 - Document setting PerlSwitches for mod_perl (jpsalvesen) (GH-128) 1.19 - 5 July 2015 - Get things working with 5.22.0 - Test against 5.23.0 - Remove dependency on Test::Warn 1.18 - 6 April 2015 - Remove dependency on CGI (use HTML::Entities instead) (Lee Johnson) - Fix a use of the wrong type of null constant (Zefram) (RT-103102) - Link to next uncovered statement in html_basic (H.Merijn Brand) (GH-112) - Add "provides" to metadata (Ivan Wills) (GH-119) 1.17 - 20 September 2014 - Get cpancover to release quality - Add IRC link to META - Test against 5.20.1, 5.21.1, 5.21.2, 5.21.3 and 5.21.4 - Officially support 5.20.1 1.16 - 17 August 2014 - Fix segfault in 5.20.0 - Improvements to cpancover - Fix vim report to work with recent versions (cono) (GH-94) - Ignore vim swap files in git (Gábor Szabó) (GH-95) - Improve help for cover command (Gábor Szabó) (GH-96) 1.15 - 1 June 2014 - Allow -coverage default,-pod option to cover (David Cantrell) (GH-89) - Get cpancover coverage in docker containers - Add CGI.pm as a prerequisite - Test against 5.20.0 and 5.21.0 - Add longer delay in tests to try to appease *BSD 1.14 - 2 May 2014 - Fix test failures on OpenBSD, NetBSD and Windows 1.13 - 28 April 2014 - Test against 5.19.11 - Fix "use 5.xyz;" on pre 5.10 perls (GH-87) - Round percentages down in summary and reports (also fixes Windows tests) 1.12 - 17 April 2014 - Fix test failure on OSX, FreeBSD and HPUX (thanks H.Merijn Brand) 1.11 - 13 April 2014 - Tests should pass when all run in parallel (Kent Fredric) (GH-69) - Fix problems with using Sereal as DB format 1.10 - 6 April 2014 - Test against 5.19.10 - Add Sereal backend and use it if available - Support spaces in DB path (Keith Wissing) (GH-81) - Test against 5.8 on Travis (Slaven Rezić) (GH-76) - HTML cleanups (H.Merijn Brand) - Fix deep recursion with use overload (Matthew Horsfall) (GH-78, GH-79) - Improve testing process 1.09 - 15 March 2014 - Add Contributors file - Test against 5.19.4 - 5.19.9 - Officially support 5.18.2 - Fix shortcircuiting conditional operators for blead changes (Matthew Horsfall) (RT-90591, GH-75, GH-80) - Fix tab expansion in HTML report (H.Merijn Brand) (GH-83) 1.08 - 24 August 2013 - Don't test against 5.17.x development releases - Don't test against 5.19.2 and 5.19.3 which have a bug which causes tests to fail - Perl 5.18 is more picky about POD encodings (Gregor Herrmann) (RT-88027) - Numerous typo fixes (David Steinbrunner) (GH-67) 1.07 - 22 August 2013 - Improve -coverage options, fix -ignore_re for .gcov files (Steve Sanbeg) (GH-53) - Work around B::CV::GV regression in 5.18.1 - Officially support 5.18.1 - Test against 5.19.1, 5.19.2 and 5.19.3 1.06 - 17 July 2013 - More DEVEL_COVER_NO_TESTS changes for p5cover 1.05 - 17 July 2013 - Quieten some deparse warnings - Fix errors in write_csv (Jim Keenan) (GH-64) - Fix error in -inc/+inc docs and pod formatting (Olaf Alders) (GH-65) - Add DEVEL_COVER_NO_TESTS option to not run any tests during p5cover 1.04 - 1 June 2013 - Fix return code from cover (Kan Fushihara) (guthub 61) - Fix pod coverage for multiple packages in a file. (RT-34888) - Speed improvements 1.03 - 20 May 2013 - Fixes for correct operation with 5.17.11, 5.18.0 and 5.19.0 1.02 - 28 April 2013 - Make -silent even quieter (Sergiy Borodych) (guthub 49) - mod_perl2 on Debian sets $^X to apache2 (Lasse Makholm) (GH-47) - Add csv file for use with metacpan (Dinis Rebolo) (GH-56) - cover -test exists with the status of the underlying test run (Kan Fushihara) (GH-57, GH-58) - Quieten a warning (Jim Keenan) (GH-59) 1.01 - 30 March 2013 - Test against 5.14.4, 5.16.3, 5.17.8, 5.17.9 and 5.17.10 - Ignore PERL5OPT during tests. And other make targets. (RT-43833) - &&=, ||= and //= operators now require RHS to be true and false - Fix some "uninitialized value" warnings 1.00 - 10 February 2013 - Fix segv in constant folding of xor ops (GH-40) - Fix various problems running Devel::Cover under tainting (GH-41) - Add JavaScript to filter results in html_basic (David Cantrell) (GH-42) Use -norestrict option to keep previous behaviour - Document ability to mark code as uncoverable (GH-45) 0.99 - 31 December 2012 - Improve documentation (Olaf Alders) (GH-34) - Thank Bytemark for the cpancover server - Test against 5.17.7 - Provide coverage for subs removed from the symbol table (RT-13207) 0.98 - 25 November 2012 - Fix links on html_basic report - Fix setting Inc under taint mode (Guillaume Aubert) (GH-26, GH-33) - Test against 5.17.6 - Improve warnings from Devel::Cover and reduce duplicates - Make cover -test -nodelete work - Run cpancover with 5.16.2 - Prefer bugs on github rather than RT 0.97 - 10 November 2012 - Filter paths contained in CWD out of @Inc (Christian Walde) (GH-32) - Test against 5.12.5, 5.14.3, 5.16.2, and 5.17.5 - Improve parallelism for cpancover 0.96 - 24 September 2012 - JSON:PP should have been JSON::PP (Paul Hirst) (GH-28) - Correct when some new tests should be skipped - Quieten some debugging output - Fix infinite loop during global destruction (GH-29) 0.95 - 22 September 2012 - Fix loss of condition coverage data when first operand calls into ignored file (Celogeek, Christian Walde) (RT-63090, GH-15, GH-20) - Fix similar problem with branch coverage (Robert Freimuth) (RT-72027) - More similar problems (Brian Cassidy, Florian Ragwitz, Heikki J Laaksonen) (RT-63698) - Test against 5.17.4 0.94 - 18 September 2012 - Officially support 5.16.1 - Manage mod_perl2 setting $^X to httpd - Make changes to support 5.17.3 0.93 - 4 August 2012 - Fix up start and finish times in text report - Make summary cover report respect options given - Make vim report respect specified criteria (RT-38258) - Only collect time and condition coverage when requested - Fix some "ignoring extra $criterion" errors - Don't stop reports at __END__ with AutoLoader - Add perl version and OS to html_basic - Make html_minimal summary more like html_basic - Time coverage is no use in the vim report - Keep descriptions to a single line 0.92 - 17 July 2012 - Fix inc directories when working with local::lib (Olivier Mengué) (GH-25) 0.91 - 15th July 2012 - Generate inc directories at runtime (RT-68991, RT-76528, RT-66881, RT-37349) - Get the tests running again on Windows 0.90 - 13th July 2012 - Fix cover -test on Windows (Christian Walde) (GH-24, RT-75565) - Better document coverage options (GH-23) - Run in directories containing spaces (RT-62423) - Add moose_constraint test (RT-57173) 0.89 - 15th June 2012 - Fix POD syntax error (gregor herrmann ) (RT-77599) - Handle RE metachars in build directory (RT-75633, RT-77598) (dcoupal@cisco.com & Niko Tyni ) - Return to starting directory after cover report (John Lightsey) (RT-61515) - Relax permissions on DB directories (GH-22) 0.88 - 8th June 2012 - Add -launch option to open report in appropriate viewer (Stephen Thirlwall) - Move ignored filename list into DB module (RT-77163, GH-12) - Don't complain about Mouse accessors (RT-71680) - Turn off $^W when calling B::Deparse (fixes PERLRT-113464) - Update cpancover 0.87 - 21st May 2012 - Major documentation overhaul (Pau Amma) - Cleanup Data::Dumper usage (localise settings) (Olivier Mengué) (RT-76531) - Ignore more generated filenames - Moose and Template Toolkit - Improve results for chained logical operators - Officially support 5.16.0 0.86 - 9th April 2012 - Add all coverage criteria to the Vim report 0.85 - 1st April 2012 - Add customisable thresholds to HTML reports (Xavier Caron) - Improve Vim report 0.84 - 31th March 2012 - Add Vim report (based on discussion with Tatsuhiko Miyagawa) 0.83 - 30th March 2012 - Prefer JSON::XS for faster operation (Audrey Tang (唐鳳)) - Rework testing framework (Xavier Caron) 0.82 - 19th March 2012 - Do not distribute MYMETA.json (Olivier Mengué) (RT-75883) 0.81 - 18th March 2012 - Fix up dzil release process 0.80 - 18th March 2012 - Don't be so noisy with Moose code - Move to Dist:Zilla (Christian Walde) - Test against 5.14.2 and 5.15.2 - 5.15.8 - Select gcov2perl from the same directory as cover - Print warnings to STDERR so $SIG{__WARN__} isn't called (Christian Walde) - Manage coverage reporting errors before an exec (Daisuke Maki) - Don't run fork tests on Windows (Christian Walde) - Add more documentation about cover --test (Kirk Kimmel) - Remove race conditions around mkdir - Add travis config file - Add word "Warning" to MD5 digest message 0.79 - 5th August 2011 - Test against 5.12.4, 5.14.1, 5.15.0 and 5.15.1 - Fix inc_sub test failures dependant on whether JSON:PP was installed 0.78 - 17th May 2011 - Fix up test quoting to work with Windows too 0.77 - 15th May 2011 - Fix cover -test covering all the test files (Larry Leszczynski) (RT-65920) - Add DEVEL_COVER_IO_OPTIONS environment variable - Sort runs by start time - Add digests to DB - Add cover -make option (Olivier Mengué) (RT-44906) - Add digests to DB This should fix some problems related to losing coverage data when there are duplicate files. This happens most usually when modules are sometimes loaded from lib and sometimes from blib. (RT-14192, RT-32465, RT-45737) - Add branch coverage for gcov (RT-30365) 0.76 - 18th April 2011 - Move CHANGES file into root for search.cpan.org (RT-67541) - Add top level version subroutine (requested by H.Merijn Brand) - Add DEVEL_COVER_DB_FORMAT environment variable - Add advisory locking to database IO operations - Explain what to do if regexp_eval.t ever fails again (Florian Ragwitz) - Remove leftovers from PERL_OBJECT (Florian Ragwitz) - Recommend 5.8.8 and above - 5.8.7 is crashing so skip some tests there 0.75 - 17th April 2011 - Write database as JSON if JSON::PP is available 0.74 - 16th April 2011 - Test against 5.12.3 and code frozen 5.14.0 (unreleased) - Fix tests to work with all releases of 5.13.x (RT-64210, RT-60901) - Avoid race condition writing DB structure files (Nicholas Clark) - Add debuglog method to Devel::Cover::DB::Structure (Nicholas Clark) - Be more careful deleting DB structure files (Nicholas Clark) - Get cover -test to honour the db passed in 0.73 - 2nd October 2010 - Tidy up Makefile.PL and META.yml - Get coverage working with Windows again 0.72 - 27th September 2010 - Teach cpancover how to work in parallel - Improve speed of check_file() (Goro Fuji) - Fix errors with non-existent directories on Cygwin (Goro Fuji) - Improve self coverage with new test - Fix tests to work with 5.13.5 - New dependency on Test::Warn - New dependency on Parallel::Iterator for cpancover 0.71 - 10th September 2010 - Improve running of Devel::Cover on itself - Fix occasional parallel test failures - Test against 5.12.2 0.70 - 29th August 2010 - Get Devel::Cover working better on itself - Distribution should now pass on 5.13.* development releases 0.69 - 28th August 2010 - Correctly report on C and other shortcuts - Put end to end tests in t/e2e - Add test for regexp eval fail (Florian Ragwitz) - Fix some warnings from strict compilers (Florian Ragwitz) - Allow tests to run in parallel (Florian Ragwitz) - Test against 5.13.* development releases - We now require Test::More to run the tests 0.68 - 5th August 2010 - Fix gcov2perl to work with large numbers (Thomas Dorner) (RT-45028) - Fix "gcov -l" include files (Thomas Dorner) (RT-44864) - Test against 5.12.1 - Gross workaround for for regexp evals (Florian Ragwitz) 0.67 - 8th May 2010 - Fix up the Makefile for dmake on Strawberry Perl (Curtis Jewell) (RT-50774) 0.66 - 12th April 2010 - Move to faster method of collecting data. Could be up to twice as fast now - Add -replace_ops options to be able to revert to previous collection method - Test against 5.12.0 and update tests as necessary - Work better with non-existent databases - XS fixes related to overriding ops rather than replacing runops (Florian Ragwitz) - Don't chmod created directories (mkdir should suffice) 0.65 - 8th August 2009 - Fix uninitialised value warning (reported by Andrew Billeb) - Test against 5.8.9 and 5.10.1 (RC1) - Correct deparsed conditional output in elsif conditions - Unset PERL5OPT when running tests 0.64 - 10th April 2008 - Build on Windows - Make "cover -test" work for Module::Build (Michael G Schwern) (RT-34263) - Make "cover -test" cover .[ch] files (Michael G Schwern) (RT-34262) - Make "cover -gcov" a valid option (Michael G Schwern) (RT-34261) 0.63 - 16th November 2007 - require 5.006001 might stop CPAN testers trying to test with 5.005 - store_return() should be a void function (H.Merijn Brand) - Finish dor support - Add support for exec (Brandon Black) - Tested against 5.10 (RC1) 0.62 - 5th November 2007 - Add table sorting to Html_basic report (Nathan Haigh) - Assume heredocs are constants - Don't add 0x200 to $^P ("file" names for evals) (Fix for Template::Declare) - Add timer and alarm for cpancover - Add Report Date to basic html report - Quieten some warnings - Document cover -test - Get rid of any __DIE__and __WARN__ signals during the report - Don't try to get a digest for "-e" - Tidy up filename normalisation - Be more explicit about what I mean when I call this alpha software - Add uncoverable comments - Don't complain about POSIX.pm (Erwan Lemonnier) - Don't resolve pathnames of symbolic links (Stefan Becker) - Spelling nits (James E Keenan) 0.61 - 10th January 2007 - Fix some "ignored" errors due to multiple subs of the same name on the same line (RT-14192) - Display pod coverage with subroutine coverage in text report - Update golden output (tests were failing in 0.60) 0.60 - 2nd January 2007 - Simplify get_key function and remove TODO item (Gisle Aas) - Be careful with UNC paths on Windows (John LoVerso) (RT-24105) - Only call HvSHAREKEYS_off if threading is enabled - s/unvailable/unavailable/ (Jim Cromie) - Don't key on op_targ - it might change (RT-22701) - Tidy up docs and error messages for reports (RT-21098) - Better database validation - Don't delete invalid databases (RT-16039) - Tested against 5.9.5 - Allow for new anonlist and anonhash ops (RT-24067) - Use outputfile for both cover and cpancover - Add compilation report (Denis Howe) 0.59 - 23rd August 2006 - Tidy up HTML, especially for cpancover - Allow coverage of subroutine statements in a different file (as with Mason) (clkao) - Bump refcount on subs to ensure they stay around for us to look at them (yes, this is a hack) 0.58 - 6th August 2006 - Be more clever about void context and so avoid SvROK hack - Document some bugs, limitations and requirements - HTML alignment fix (Sébastien Aperghis-Tramoni) - CSS improvements for HTML reports (Sébastien Aperghis-Tramoni) 0.57 - 3rd August 2006 - Report Pod::Coverage load failure (dom - happygiraffe.net) (RT-14425) - Use Perl::Tidy as an alternative syntax highlighter (Sébastien Aperghis-Tramoni) - Lighten the style a little - make table cells only have right and bottom borders, using the ones from the surrounding cells to form the grid (Sébastien Aperghis-Tramoni) - subs_only option to only show coverage for subs (Nicholas Clark) 0.56 - 1st August 2006 - gcov2perl creates db if necessary (Steve Peters) (RT-13536) - Properly merge identical files (Jeff Wren) (RT-12410) - Allow line anchors in html_basic (Mark Stosberg) (RT-13615) - Right justify numerical tabular html output (Sébastien Aperghis-Tramoni) - Work around ExtUtils::MakeMaker realclean bug (Florian Ragwitz) (RT-17324) - Don't try to delete db if it isn't there - The following changes were made at the Devel::Cover hackathon, sponsored by Best Practical - No longer create the temporary .version files (Leon Brocard) - Document Module::Build's testcover (Leon Brocard) - Add more detail about code coverage in docs (Leon Brocard) - Make the HTML valid by moving comment past the (Leon Brocard) - Add syntax highlighting to HTML_basic if PPI::HTML is installed (Leon Brocard) - Refactored common code for calculate_summary across all Criterion classes (Norman Nunley) - Remove duplicated code paths between Branch and Condition (Norman Nunley) - Don't call overload bool in condition coverage (clkao) - Fix the XML comment for cpancover (Norman Nunley) - Turn conditionals in void context into or2 conditions so that the value of the RHS doesn't matter for coverage purposes - Add a tool to scan comments about uncoverable code and output .uncoverable format to stdout (clkao) - Add and update overload tests 0.55 - 22nd September 2005 - Add -gcov option to cover and make it default when using gcc - Remolve unused File::Find from cpancover - Document how to get XS coverage in gcov2perl - Improvements to SVK annotation (Chia-liang Kao) 0.54 - 13th September 2005 - Make html_basic prettier - Fix pod coverage percentages - Fix integer <-> pointer conversion warnings (Robin Barker) - Add more tests for sort bug fixed in 0.53 (Rob Kinyon) - Handle || bless {}, "XXX" (reported by Marcel Grünauer) - Add preliminary dor support (unfinished) - Test against perl-5.8.7 - Add check for Pod::Coverage::CountParents - Fix line number display problem in conditionals in Html_basic - Add eval_sub and eval3 tests - Add buildperl script - Add -report option to cpancover - Update cpancover CSS - Partial solution for structure problems including debugging code - Add outputfile option to Html_basic 0.53 - 17th April 2005 - Clean up database directories - Allow require File::Spec->catfile('t', 'common.pl'); (from an example by Randy W. Sims) - Fix core dump associated with sort subs and add test case supplied by Leif Eriksen - Add extra options for coverage criteria - Allow pod coverage options to be specified - Update copyrights - Allow Test::Differences output to be displayed usefully - Test against perl-5.9.3 0.52 - 13th December 2004 - Fix thread locking bug (Ruslan Zakirov) - Make valgrind happy - Fix gcov2perl (Steve Peters) - Restore failure message to CLONE 0.51 - 29th November 2004 - Handle $y || undef - Small branch coverage fix - Improve reporting of uncoverable constructs in html reports - Test against perl-5.8.6 - Recommend at least perl-5.8.2 0.50 - 25th October 2004 - Add -test option to cover - Fix missing coverage when calling a sub in an ignored module - Add module_ignore test - Add uncoverable options to cover 0.49 - 6th October 2004 - Compile on Win32 (and elsewhere) (Steve Hay) 0.48 - 5th October 2004 - Working towards thread safety - Test against perl-5.8.5 - Store perl version number in Inc.pm and complain if it doesn't match - Add annotation API and Random example - Display run information in text report - Remove POSIX path bodge which is now properly fixed - Update test results for new functionality - Add -select_re and -ignore_re options to cover - Sort out "ignoring extra subroutine" and friends - Add eval2 and eval_use tests - Ignore *.t by default with blib - Add beginnings of sort report - Bump up DB version - Fix problems with references in INC (which can't be handled) - Fixes for mod_perl (Vadim O. Ustiansky) 0.47 - 27th June 2004 - Provide subroutine coverage for empty subs - sub empty { } - Only override B::Deparse subs whilst using them and add deparse test 0.46 - 23rd June 2004 - Don't lose data merging DBs - Work with Safe.pm, by not covering it - Swap Profiling_op for Profiling_key to avoid accessing freed memory - Rename -file and -exclude options in cover to -select and -ignore - Fully cover conditions and branches when the condition calls a sub in an ignored file 0.45 - 27th May 2004 - Cope with spaces in build path on Windows (Max Maischein) - Allow Devel::Cover to be used under mod_perl (Philippe M. Chiasson) - Handle $x ||= 1 and friends nicely, including subs and *foo{THING} - Allow uncoverable code to be specified. (Unfinished) 0.44 - 18th May 2004 - Fix get_elapsed, although its result is not used yet - Recommend 5.8.1 as a minimum - Replace run Makefile target with text and html - Fix up gcov2perl - Fail gracefully when covering a threaded program - Add DEVEL_COVER_OPTIONS environment variable 0.43 - 2nd May 2004 - Add +ignore and +select options, and change meaning of -ignore and -select options. This is an interface change - Ignore coverage on Devel::Cover's files by default - Cover INIT and END blocks more reliably - Fix 5.6 on Windows. Well, sort of - Add a message in Makefile.PL recommending against using Devel::Cover on 5.6, especially under Windows 0.42 - 30th April 2004 - Add SYNOPSIS section to README - Resolve links for Devel::Cover::Inc (Dave Rolsky) - Get things running on Windows again 0.41 - 29th April 2004 - Correct time coverage percentages - Collect data for BEGIN, CHECK, INIT and END blocks in the main program, and INIT and END blocks in modules - Ensure our END block is always the last run - Don't clean up Pending_conditionals data - Untaint @INC after using blib - Be silent if called via HARNESS_PERL_SWITCHES - Test against perl-5.8.4 - Store cwd from when each module was required in order to find them again - Refactor and tidy XS code - Get cpancover running again with the DB changes - Normalise filenames 0.40 - 24th March 2004 - Remove DB structure for unwanted files - Identify ops based on address and OP contents, except for op_ppaddr, which we modify - Overhaul of coverage collection - Additions to tests 0.39 - 22nd March 2004 - Major database rework to store runs - Add Devel::Cover::DB::Structure.pm - Check for Test::Differences in Makefile.PL - Test with perl5.9.2 - Skip fork test on MSWin32 0.38 - 12th March 2004 - Allow coverage summary title to be changed (David Wheeler) - More care generating pod golden results - Small Devel::Cover::Op output fix - Handle "my $x = shift || []" and friends nicely - Add default_param test - Provide summary output to one decimal place - Update gcov2perl 0.37 - 10th March 2004 - Fix up pod test golden results - Add limitation documentation (Michael Carman) 0.36 - 9th March 2004 - Add fork test - Remove debugging code from md5 test - Remove runs after merging - code was commented out for debugging - Don't merge runs during coverage collection - Delete database at start if not merging to cope with forking 0.35 - 8th March 2004 - Change Text2 to pick up version changes - Minor documentation updates - Minor changes to Devel::Cover::Op - Add outputfile option to HTML output (David Wheeler) - Document -silent option to Devel::Cover - Add -silent option to cover (David Wheeler) - Make Devel::Cover taint safe, or tolerant at least - Only add versioned golden results to tests that need them - Add trivial, md5 and module_no_inc tests - Increase flexibility of testing system to accommodate md5 test - Add mani, all_gold and all_test Makefile targets - Make all_versions skip non-existent platforms - Add DB option to make dump target - Remove dependencies on op_seq. (I removed it from bleadperl.) Use op_targ instead - Collect some metadata - Documentation updates (Andy Lester) - Document the mechanism by which files are selected for coverage 0.34 - 14th January 2004 - Fix various warnings and errors that had crept in whilst working on dynamic subs 0.33 - 13th January 2004 - Get things working on paths with spaces in them - Documentation clarifications (Andy Lester) - Fix coverage for simple if, elsif and unless conditionals - Add if test - Ensure runs are merged in the order they were created - Don't report multiple data from dynamically created subs - Add alias, alias1 and dynamic_subs tests - Fix and document Devel::Cover::Op - Redo subroutine coverage so anon subs are covered correctly in 5.6.x 0.32 - 4th January 2004 - Actually include do test - Create run concept in database - Belatedly remove check for Template - Add branch_return_sub test - Add finalise_conditions() to collect previously missed coverage - Fix incorrect coverage results associated with "and" conditions - Add all_versions utility script - Put /usr/bin/perl on all shebang lines 0.31 - 22nd December 2003 - Remove debugging output. Hmmm 0.30 - 22nd December 2003 - Get things working under Windows 0.29 - 19th December 2003 - Merge data from files with identical MD5 checksums (Arthur Bergman) - Add do test - Handle $x || return - Keep cover -delete happy when there is no existing database - In cover, make -file a glob and add -exclude - Watch for coverage options being set in cover (PERL5OPT set?) - Fix up html_basic and html_subtle - Make 5.6.x builds a bit quieter - Clean up time routines in XS code 0.28 - 1st December 2003 - Remove leading whitespace from HTML templates (Gabor Szabó) - Remove obsolete indent option - Add MD5 checksums (Michael Carman) - Add Html_minimal.pm (Michael Carman) (Obsoleting Gabor's patch before it was released) - Pass unknown cover options to the formatter and remove -option - Specify the output directory for HTML - Search up directory trees for modules 0.27 - 9th November 2003 - Behave sensibly if import() is not called, for example when MakeMaker does a PREREQ_PM check - Use Storable for the database instead of Data::Dumper/eval (Michael Carman) 0.26 - 12th October 2003 - Decline to output HTML results for conditions containing > 16 terms - Add titles to HTML output 0.25 - 10th October 2003 - Fix for perl 5.6.1. Cwd::abs_path($d) gets upset if $d doesn't exist - Start of some changes to cpancover HTML 0.24 - 10th October 2003 - Paths in Devel::Cover::Inc in single quotes for Windows platforms - Add -dir option and default it to cwd - Ignore test.pl in cpancover - Display pod coverage in cpancover 0.23 - 6th September 2003 - Report condition coverage for branches on the same line as the branch - Add subroutine coverage - Made "all" coverage value work and made it the default 0.22 - 2nd September 2003 - Rewrite runops function - First line of DESTROY blocks and overload subs not now skipped - Add some more tests 0.21 - 1st September 2003 - Add cpancover - Handle $x || next and friends - Add html_subtle and text2 backends (Michael Carman) - Rename html backend to html_basic - Make html backend a wrapper around preferred style, currently html_subtle - Make time coverage a little more accurate. OK, a lot more accurate, it's at least on the right line now, but I still wouldn't really trust it - Fix pod coverage which has been broken for a while - Don't collect branch coverage when not asked for - Provide golden results for different Perl versions - Change some B::Deparse logic to mirror changes in 5.8.1/5.10 0.20 - 5th October 2002 - Add break after default to satisfy IBM's xlC compiler on AIX - Get things working with threads again - make realclean is 0.19 - 29th September 2002 - Quieten uninitialised value warnings 0.18 - 28th September 2002 - Redo the way condition coverage is gathered - abuse op_ppaddr - Put or conditions the right way round - Allow for subclasses of coverage types - Add: Devel::Cover::Condition_or_2.pm Devel::Cover::Condition_or_3.pm Devel::Cover::Condition_and_3.pm Devel::Cover::Condition_xor_4.pm - "use" all conditions in Criterion.pm, and nowhere else - Add support for xor, ||= and &&= 0.17 - 15th September 2002 - Call check_files() in report() to ensure we pick up anything added to the symbol table while the program was running 0.16 - 9th September 2002 - Get rid of some uninitialised warnings - Inline the HTML templates - Rebless the op after blessing it as a COP - Make branch coverage line numbers more accurate 0.15 - 5th September 2002 - Reinstate coverage of subs in main:: which got lost somewhere (0.11?) - Bug fixes for use of uninitialised values - Automatically generate tests. Well, their infrastructure anyway - Move Cover to lib/Devel/Cover to keep case insensitive filesystems happy - Remove -detail option. (It belongs to cover.) - Work on op addresses and sequence numbers instead of just op addresses, to be (almost) unique - Clean up subroutine location code - Fix -select to override anything else - Add condition coverage for && and || ops - Various changes in runops_cover to try to reduce runtime - Don't use runops_cover until CHECK time - Add merge, write and file options to cover - Add branch coverage - Abstract away cover backends - Use TT for HTML output 0.14 - 28th February 2002 - Add a workaround for an AUTOLOAD bug in bleadperl - Add gcov2perl program to convert gcov files to Devel::Cover databases - Get rid of // comments in xs file 0.13 - 14th October 2001 - Forgot to allow for lack of Pod::Coverage in Devel::Cover::Pod.pm 0.12 - 14th October 2001 - Improve pod coverage by considering private subs - Add time coverage, aka profiling - Add: Devel::Cover::DB::File.pm Devel::Cover::Time.pm - Abstract summary and percentage calculations to appropriate classes 0.11 - 10th September 2001 - Add pod coverage based on Pod::Coverage.pm - Put a full API on the database - Add: Devel::Cover::Criterion.pm Devel::Cover::Statement.pm Devel::Cover::Condition.pm Devel::Cover::Pod.pm - Some improvements to the cover program 0.10 - 27th August 2001 - Add cover program to generate reports 0.09 - 18th August 2001 - Beef up Devel::Cover::DB 0.08 - 18th August 2001 - Provide better handling of files to report on or ignore Makefile.PL generates Inc.pm containing default @INC added +inc, -ignore and -select 0.07 - 17th August 2001 - Add an API to Devel::Cover::DB 0.06 - 10th August 2001 - Rename Devel::Cover::Process to Devel::Cover::DB - Make the database a directory - Add fix for eval in filename. (Arthur Bergman ) - Add more tests and abstract away comparison subroutine - Clear @Inc if it is set explicitly - Trim filename length in detailed output 0.05 - 9th August 2001 - Make line numbers more accurate when nextstate has been optimised away - Get things working with ithreads 0.04 - 12th April 2001 - Include Devel::Cover::Op - Add condition coverage (sort of) 0.03 - 10th April 2001 - Add detailed output - Add -d option to turn it on 0.02 - 10th April 2001 - Add summary output - Add -S option to turn it off - Turn Devel::Cover::Process into a class 0.01 - Initial release - 9th April 2001 LICENCE100644000765000024 4642714631552031 14072 0ustar00pjcjstaff000000000000Devel-Cover-1.44This software is copyright (c) 2024 by Paul Johnson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2024 by Paul Johnson. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Perl Artistic License 1.0 --- This software is Copyright (c) 2024 by Paul Johnson. This is free software, licensed under: The Perl Artistic License 1.0 The "Artistic License" Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. 7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. 8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. 9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Cover.xs100644000765000024 12325514631552031 14552 0ustar00pjcjstaff000000000000Devel-Cover-1.44/* * Copyright 2001-2024, Paul Johnson (paul@pjcj.net) * * This software is free. It is licensed under the same terms as Perl itself. * * The latest version of this software should be available from my homepage: * http://www.pjcj.net * */ #ifdef __cplusplus extern "C" { #endif #define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef __cplusplus } #endif #ifdef PERL_OBJECT #define CALLOP this->*PL_op #else #define CALLOP *PL_op #endif #ifndef START_MY_CXT /* No threads in 5.6 */ #define START_MY_CXT static my_cxt_t my_cxt; #define dMY_CXT_SV dNOOP #define dMY_CXT dNOOP #define MY_CXT_INIT NOOP #define MY_CXT my_cxt #define pMY_CXT void #define pMY_CXT_ #define _pMY_CXT #define aMY_CXT #define aMY_CXT_ #define _aMY_CXT #endif #define MY_CXT_KEY "Devel::Cover::_guts" XS_VERSION #define PDEB(a) a #define NDEB(a) ; #define D PerlIO_printf #define L Perl_debug_log #define svdump(sv) do_sv_dump(0, L, (SV *)sv, 0, 10, 1, 0); #define None 0x00000000 #define Statement 0x00000001 #define Branch 0x00000002 #define Condition 0x00000004 #define Subroutine 0x00000008 #define Path 0x00000010 #define Pod 0x00000020 #define Time 0x00000040 #define All 0xffffffff #if defined HAS_GETTIMEOFDAY || defined HAS_TIMES # define CAN_PROFILE 1 #else # define CAN_PROFILE 0 #endif struct unique { /* Well, we'll be fairly unlucky if it's not */ OP *addr, op; /* include hashed file location information, where available (cops) */ size_t fileinfohash; }; #define KEY_SZ sizeof(struct unique) typedef struct { unsigned covering; int collecting_here; HV *cover, *statements, *branches, *conditions, #if CAN_PROFILE *times, #endif *modules, *files; AV *ends; char profiling_key[KEY_SZ]; bool profiling_key_valid; SV *module, *lastfile; int tid; int replace_ops; /* - fix up whatever is broken with module_relative on Windows here */ #if PERL_VERSION > 8 Perl_ppaddr_t ppaddr[MAXO]; #else OP *(*ppaddr[MAXO])(pTHX); #endif } my_cxt_t; #ifdef USE_ITHREADS static perl_mutex DC_mutex; #endif static HV *Pending_conditionals, *Return_ops; static int tid; START_MY_CXT #define collecting(criterion) (MY_CXT.covering & (criterion)) #ifdef HAS_GETTIMEOFDAY #ifdef __cplusplus extern "C" { #endif #ifdef WIN32 #include #else #include #endif #ifdef __cplusplus } #endif /* op->op_sibling is deprecated on new perls, but the OpSIBLING macro doesn't exist on older perls. We don't need to check for PERL_OP_PARENT here because if PERL_OP_PARENT was set, and we needed to check op_moresib, we would already have this macro. */ #ifndef OpSIBLING #define OpSIBLING(o) (0 + (o)->op_sibling) #endif static double get_elapsed() { #ifdef WIN32 dTHX; #endif struct timeval time; double e; gettimeofday(&time, NULL); e = time.tv_sec * 1e6 + time.tv_usec; return e; } static double elapsed() { static double p; double e, t; t = get_elapsed(); e = t - p; p = t; return e; } #elif defined HAS_TIMES #ifndef HZ # ifdef CLK_TCK # define HZ CLK_TCK # else # define HZ 60 # endif #endif static int cpu() { #ifdef WIN32 dTHX; #endif static struct tms time; static int utime = 0, stime = 0; int e; #ifndef VMS (void)PerlProc_times(&time); #else (void)PerlProc_times((tbuffer_t *)&time); #endif e = time.tms_utime - utime + time.tms_stime - stime; utime = time.tms_utime; stime = time.tms_stime; return e / HZ; } #endif /* HAS_GETTIMEOFDAY */ /* * http://codereview.stackexchange.com/questions/85556/simple-string-hashing-algorithm-implementation * https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function * http://www.isthe.com/chongo/tech/comp/fnv/index.html#public_domain * * FNV hash algorithms and source code have been released into the * public domain. The authors of the FNV algorithm took deliberate * steps to disclose the algorithm in a public forum soon after it was * invented. More than a year passed after this public disclosure and the * authors deliberately took no steps to patent the FNV algorithm. Therefore * it is safe to say that the FNV authors have no patent claims on the FNV * algorithm as published. * */ /* Fowler/Noll/Vo (FNV) hash function, variant 1a */ static size_t fnv1a_hash(const char* cp) { size_t hash = 0x811c9dc5; while (*cp) { hash ^= (unsigned char) *cp++; hash *= 0x01000193; } return hash; } #define FILEINFOSZ 1024 static char *get_key(OP *o) { static struct unique uniq; static char mybuf[FILEINFOSZ]; uniq.addr = o; uniq.op = *o; uniq.op.op_ppaddr = 0; /* we mess with this field */ uniq.op.op_targ = 0; /* might change */ if (o->op_type == OP_NEXTSTATE || o->op_type == OP_DBSTATE) { /* cop, has file location information */ char *file = CopFILE((COP *)o); long line = CopLINE((COP *)o); snprintf(mybuf, FILEINFOSZ - 1, "%s:%ld", file, line); uniq.fileinfohash = fnv1a_hash(mybuf); } else { /* no file location information available */ uniq.fileinfohash = 0; } return (char *)&uniq; } static char *hex_key(char *key) { static char hk[KEY_SZ * 2 + 1]; size_t c; for (c = 0; c < KEY_SZ; c++) { NDEB(D(L, "%zu of %zu, <%02X> at %p\n", c, KEY_SZ, (unsigned char)key[c], hk + c * 2)); sprintf(hk + c * 2, "%02X", (unsigned char)key[c]); } hk[c * 2] = 0; return hk; } static void set_firsts_if_needed(pTHX) { SV *init = (SV *)get_cv("Devel::Cover::first_init", 0); SV *end = (SV *)get_cv("Devel::Cover::first_end", 0); NDEB(svdump(end)); if (PL_initav && av_len(PL_initav) >= 0) { SV **cv = av_fetch(PL_initav, 0, 0); if (*cv != init) { av_unshift(PL_initav, 1); av_store(PL_initav, 0, init); } } if (PL_endav && av_len(PL_endav) >= 0) { SV **cv = av_fetch(PL_endav, 0, 0); if (*cv != end) { av_unshift(PL_endav, 1); av_store(PL_endav, 0, end); } } } static int check_if_collecting(pTHX_ COP *cop) { dMY_CXT; #if !NO_TAINT_SUPPORT int tainted = PL_tainted; #endif char *file = CopFILE(cop); int in_re_eval = strnEQ(file, "(reeval ", 8); NDEB(D(L, "check_if_collecting at: %s:%ld\n", file, (long)CopLINE(cop))); if (file && strNE(SvPV_nolen(MY_CXT.lastfile), file)) { int found = 0; if (MY_CXT.files) { SV **f = hv_fetch(MY_CXT.files, file, strlen(file), 0); if (f) { MY_CXT.collecting_here = SvIV(*f); found = 1; NDEB(D(L, "File: %s:%ld [%d]\n", file, (long)CopLINE(cop), MY_CXT.collecting_here)); } } if (!found && MY_CXT.replace_ops && !in_re_eval) { dSP; int count; SV *rv; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(file, 0))); PUTBACK; count = call_pv("Devel::Cover::use_file", G_SCALAR); SPAGAIN; if (count != 1) croak("use_file returned %d values\n", count); rv = POPs; MY_CXT.collecting_here = SvTRUE(rv) ? 1 : 0; NDEB(D(L, "-- %s - %d\n", file, MY_CXT.collecting_here)); PUTBACK; FREETMPS; LEAVE; } sv_setpv(MY_CXT.lastfile, file); } NDEB(D(L, "%s - %d\n", SvPV_nolen(MY_CXT.lastfile), MY_CXT.collecting_here)); #if PERL_VERSION > 6 if (SvTRUE(MY_CXT.module)) { STRLEN mlen, flen = strlen(file); char *m = SvPV(MY_CXT.module, mlen); if (flen >= mlen && strnEQ(m, file + flen - mlen, mlen)) { SV **dir = hv_fetch(MY_CXT.modules, file, strlen(file), 1); if (!SvROK(*dir)) { SV *cwd = newSV(0); AV *d = newAV(); *dir = newRV_inc((SV*) d); av_push(d, newSVsv(MY_CXT.module)); if (getcwd_sv(cwd)) { av_push(d, newSVsv(cwd)); NDEB(D(L, "require %s as %s from %s\n", m, file, SvPV_nolen(cwd))); } } } sv_setpv(MY_CXT.module, ""); set_firsts_if_needed(aTHX); } #endif #if !NO_TAINT_SUPPORT PL_tainted = tainted; #endif return MY_CXT.collecting_here; } #if CAN_PROFILE static void cover_time(pTHX) { dMY_CXT; SV **count; NV c; if (collecting(Time)) { /* * Profiling information is stored against MY_CXT.profiling_key, * the key for the op we have just run */ NDEB(D(L, "Cop at %p, op at %p\n", PL_curcop, PL_op)); if (MY_CXT.profiling_key_valid) { count = hv_fetch(MY_CXT.times, MY_CXT.profiling_key, KEY_SZ, 1); c = (SvTRUE(*count) ? SvNV(*count) : 0) + #if defined HAS_GETTIMEOFDAY elapsed(); #else cpu(); #endif sv_setnv(*count, c); } if (PL_op) { memcpy(MY_CXT.profiling_key, get_key(PL_op), KEY_SZ); MY_CXT.profiling_key_valid = 1; } else { MY_CXT.profiling_key_valid = 0; } } } #endif static int collecting_here(pTHX) { dMY_CXT; if (MY_CXT.collecting_here) return 1; #if CAN_PROFILE cover_time(aTHX); MY_CXT.profiling_key_valid = 0; #endif NDEB(D(L, "op %p is %s\n", PL_op, OP_NAME(PL_op))); if (hv_exists(Return_ops, get_key(PL_op), KEY_SZ)) return MY_CXT.collecting_here = 1; else return 0; } static void store_return(pTHX) { dMY_CXT; /* * If we are jumping somewhere we might not be collecting * coverage there, so store where we will be coming back to * so we can turn on coverage straight away. We need to * store more than one return op because a non collecting * sub may call back to a collecting sub. */ if (MY_CXT.collecting_here && PL_op->op_next) { (void)hv_fetch(Return_ops, get_key(PL_op->op_next), KEY_SZ, 1); NDEB(D(L, "adding return op %p\n", PL_op->op_next)); } } static void store_module(pTHX) { dMY_CXT; dSP; #if PERL_VERSION > 8 SvSetSV_nosteal(MY_CXT.module, (SV*)newSVpv(SvPV_nolen(TOPs), 0)); NDEB(D(L, "require %s\n", SvPV_nolen(MY_CXT.module))); #endif } static void call_report(pTHX) { dSP; PUSHMARK(SP); call_pv("Devel::Cover::report", G_VOID|G_DISCARD|G_EVAL); SPAGAIN; } static void cover_statement(pTHX_ OP *op) { dMY_CXT; char *ch; SV **count; IV c; if (!collecting(Statement)) return; ch = get_key(op); count = hv_fetch(MY_CXT.statements, ch, KEY_SZ, 1); c = SvTRUE(*count) ? SvIV(*count) + 1 : 1; NDEB(D(L, "Statement: %s:%ld\n", CopFILE(cCOPx(op)), (long)CopLINE(cCOPx(op)))); sv_setiv(*count, c); NDEB(op_dump(op)); } static void cover_current_statement(pTHX) { #if CAN_PROFILE cover_time(aTHX); #endif cover_statement(aTHX_ PL_op); } static void add_branch(pTHX_ OP *op, int br) { dMY_CXT; AV *branches; SV **count; int c; SV **tmp = hv_fetch(MY_CXT.branches, get_key(op), KEY_SZ, 1); if (SvROK(*tmp)) { branches = (AV *) SvRV(*tmp); } else { *tmp = newRV_inc((SV*) (branches = newAV())); av_unshift(branches, 2); } count = av_fetch(branches, br, 1); c = SvTRUE(*count) ? SvIV(*count) + 1 : 1; sv_setiv(*count, c); NDEB(D(L, "Adding branch making %d at %p\n", c, op)); } static AV *get_conditional_array(pTHX_ OP *op) { dMY_CXT; AV *conds; SV **cref = hv_fetch(MY_CXT.conditions, get_key(op), KEY_SZ, 1); if (SvROK(*cref)) conds = (AV *) SvRV(*cref); else *cref = newRV_inc((SV*) (conds = newAV())); return conds; } static void set_conditional(pTHX_ OP *op, int cond, int value) { /* * The conditional array is composed of six elements: * * 0 - 1 iff we are in an xor and the first operand was true * 1 - not short circuited - second operand is false * 2 - not short circuited - second operand is true * 3 - short circuited, or for xor second operand is false * 4 - for xor second operand is true * 5 - 1 iff we are in void context */ SV **count = av_fetch(get_conditional_array(aTHX_ op), cond, 1); sv_setiv(*count, value); NDEB(D(L, "Setting %d conditional to %d at %p\n", cond, value, op)); } static void add_conditional(pTHX_ OP *op, int cond) { SV **count = av_fetch(get_conditional_array(aTHX_ op), cond, 1); int c = SvTRUE(*count) ? SvIV(*count) + 1 : 1; sv_setiv(*count, c); NDEB(D(L, "Adding %d conditional making %d at %p\n", cond, c, op)); } #ifdef USE_ITHREADS static AV *get_conds(pTHX_ AV *conds) { dMY_CXT; AV *thrconds; HV *threads; SV *tid, **cref; char *t; if (av_exists(conds, 2)) { SV **cref = av_fetch(conds, 2, 0); threads = (HV *) *cref; } else { threads = newHV(); HvSHAREKEYS_off(threads); av_store(conds, 2, (SV *)threads); } tid = newSViv(MY_CXT.tid); t = SvPV_nolen(tid); cref = hv_fetch(threads, t, strlen(t), 1); if (SvROK(*cref)) thrconds = (AV *)SvRV(*cref); else *cref = newRV_inc((SV*) (thrconds = newAV())); return thrconds; } #endif static void add_condition(pTHX_ SV *cond_ref, int value) { int final = !value; AV *conds = (AV *) SvRV(cond_ref); OP *next = INT2PTR(OP *, SvIV(*av_fetch(conds, 0, 0))); OP *(*addr)(pTHX) = INT2PTR(OP *(*)(pTHX), SvIV(*av_fetch(conds, 1, 0))); I32 i; if (!final && next != PL_op) croak("next (%p) does not match PL_op (%p)", next, PL_op); #ifdef USE_ITHREADS i = 0; conds = get_conds(aTHX_ conds); #else i = 2; #endif NDEB(D(L, "Looking through %zd conditionals at %p\n", av_len(conds) - 1, PL_op)); for (; i <= av_len(conds); i++) { OP *op = INT2PTR(OP *, SvIV(*av_fetch(conds, i, 0))); SV **count = av_fetch(get_conditional_array(aTHX_ op), 0, 1); int type = SvTRUE(*count) ? SvIV(*count) : 0; sv_setiv(*count, 0); /* Check if we have come from an xor with a true first op */ if (final) value = 1; if (type == 1) value += 2; NDEB(D(L, "Found %p: %d, %d\n", op, type, value)); add_conditional(aTHX_ op, value); } #ifdef USE_ITHREADS i = -1; #else i = 1; #endif while (av_len(conds) > i) av_pop(conds); NDEB(svdump(conds)); NDEB(D(L, "addr is %p, next is %p, PL_op is %p, length is %zd final is %d\n", addr, next, PL_op, av_len(conds), final)); if (!final) next->op_ppaddr = addr; } static void dump_conditions(pTHX) { HE *e; MUTEX_LOCK(&DC_mutex); hv_iterinit(Pending_conditionals); PDEB(D(L, "Pending_conditionals:\n")); while ((e = hv_iternext(Pending_conditionals))) { I32 len; char *key = hv_iterkey(e, &len); SV *cond_ref = hv_iterval(Pending_conditionals, e); AV *conds = (AV *) SvRV(cond_ref); OP *next = INT2PTR(OP *, SvIV(*av_fetch(conds, 0,0))); OP *(*addr)(pTHX) = INT2PTR(OP *(*)(pTHX), SvIV(*av_fetch(conds, 1,0))); I32 i; #ifdef USE_ITHREADS i = 0; /* TODO - this can't be right */ conds = get_conds(aTHX_ conds); #else i = 2; #endif PDEB(D(L, " %s: op %p, next %p (%ld)\n", hex_key(key), next, addr, (long)av_len(conds) - 1)); for (; i <= av_len(conds); i++) { OP *op = INT2PTR(OP *, SvIV(*av_fetch(conds, i, 0))); SV **count = av_fetch(get_conditional_array(aTHX_ op), 0, 1); int type = SvTRUE(*count) ? SvIV(*count) : 0; sv_setiv(*count, 0); PDEB(D(L, " %2d: %p, %d\n", i - 2, op, type)); } } MUTEX_UNLOCK(&DC_mutex); } #if PERL_VERSION > 18 /* For if ($a || $b) and unless ($a && $b), rpeep skips past a few * logops and messes with Devel::Cover * * This function will find the skipped op if there is one */ static OP *find_skipped_conditional(pTHX_ OP *o) { OP *right, *next; if (o->op_type != OP_OR && o->op_type != OP_AND) return NULL; /* Get to the end of the "a || b || c" block */ right = OpSIBLING(cLOGOP->op_first); while (right && OpSIBLING(cLOGOPx(right))) right = OpSIBLING(cLOGOPx(right)); if (!right) return NULL; next = right->op_next; while (next && next->op_type == OP_NULL) next = next->op_next; if (!next) return NULL; if (o == next) return NULL; if (next->op_type != OP_OR && next->op_type != OP_AND) return NULL; /* if ($a || $b) or unless ($a && $b) */ if (o->op_type == next->op_type) return NULL; if ((next->op_flags & OPf_WANT) != OPf_WANT_VOID) return NULL; if (!cLOGOPx(next)->op_other || !o->op_next) return NULL; if (cLOGOPx(next)->op_other != o->op_next) return NULL; return next; } #endif /* NOTE: caller must protect get_condition calls by locking DC_mutex */ static OP *get_condition(pTHX) { SV **pc = hv_fetch(Pending_conditionals, get_key(PL_op), KEY_SZ, 0); if (pc && SvROK(*pc)) { dSP; NDEB(D(L, "get_condition from %p, %p: %p (%s)\n", PL_op, (void *)PL_op->op_targ, pc, hex_key(get_key(PL_op)))); /* dump_conditions(aTHX); */ NDEB(svdump(Pending_conditionals)); add_condition(aTHX_ *pc, SvTRUE(TOPs) ? 2 : 1); } else { PDEB(D(L, "All is lost, I know not where to go from %p, %p: %p (%s)\n", PL_op, (void *)PL_op->op_targ, pc, hex_key(get_key(PL_op)))); dump_conditions(aTHX); NDEB(svdump(Pending_conditionals)); /* croak("urgh"); */ exit(1); } return PL_op; } static void finalise_conditions(pTHX) { /* * Our algorithm for conditions relies on ending up at a particular * op which we use to call get_condition(). It's possible that we * never get to that op; for example we might return out of a sub. * This causes us to lose coverage information. * * This function is called after the program has been run in order * to collect that lost information. */ HE *e; NDEB(D(L, "finalise_conditions\n")); /* dump_conditions(aTHX); */ NDEB(svdump(Pending_conditionals)); MUTEX_LOCK(&DC_mutex); hv_iterinit(Pending_conditionals); while ((e = hv_iternext(Pending_conditionals))) add_condition(aTHX_ hv_iterval(Pending_conditionals, e), 0); MUTEX_UNLOCK(&DC_mutex); } static void cover_cond(pTHX) { dMY_CXT; if (collecting(Branch)) { dSP; int val = SvTRUE(TOPs); add_branch(aTHX_ PL_op, !val); } } static void cover_logop(pTHX) { /* * For OP_AND, if the first operand is false, we have short * circuited the second, otherwise the value of the op is the * value of the second operand. * * For OP_OR, if the first operand is true, we have short circuited * the second, otherwise the value of the op is the value of the * second operand. * * We check the value of the first operand by simply looking on the * stack. To check the second operand it is necessary to note the * location of the next op after this logop. When we get there, we * look at the stack and store the coverage information indexed to * this op. * * This scheme also works for OP_XOR with a small modification * because it doesn't short circuit. See the comment below. * * To find out when we get to the next op we change the op_ppaddr to * point to get_condition(), which will do the necessary work and * then reset and run the original op_ppaddr. We also store * information in the Pending_conditionals hash. This is keyed on * the op and the value is an array, the first element of which is * the op we are messing with, the second element of which is the * op_ppaddr we overwrote, and the subsequent elements are the ops * about which we are collecting the condition coverage information. * Note that an op may be collecting condition coverage information * about a number of conditions. */ dMY_CXT; NDEB(D(L, "logop() at %p\n", PL_op)); NDEB(op_dump(PL_op)); if (!collecting(Condition)) return; if (cLOGOP->op_first->op_type == OP_ITER) { /* loop - ignore it for now */ } else { dSP; int left_val = SvTRUE(TOPs); #if PERL_VERSION > 8 int left_val_def = SvOK(TOPs); #endif /* We don't count X= as void context because we care about the value * of the RHS */ int void_context = GIMME_V == G_VOID && #if PERL_VERSION > 8 PL_op->op_type != OP_DORASSIGN && #endif PL_op->op_type != OP_ANDASSIGN && PL_op->op_type != OP_ORASSIGN; NDEB(D(L, "left_val: %d, void_context: %d at %p\n", left_val, void_context, PL_op)); NDEB(op_dump(PL_op)); set_conditional(aTHX_ PL_op, 5, void_context); if ((PL_op->op_type == OP_AND && left_val) || (PL_op->op_type == OP_ANDASSIGN && left_val) || (PL_op->op_type == OP_OR && !left_val) || (PL_op->op_type == OP_ORASSIGN && !left_val) || #if PERL_VERSION > 8 (PL_op->op_type == OP_DOR && !left_val_def) || (PL_op->op_type == OP_DORASSIGN && !left_val_def) || #endif (PL_op->op_type == OP_XOR)) { /* no short circuit */ OP *right = OpSIBLING(cLOGOP->op_first); NDEB(op_dump(right)); if (void_context || right->op_type == OP_NEXT || right->op_type == OP_LAST || right->op_type == OP_REDO || right->op_type == OP_GOTO || right->op_type == OP_RETURN || right->op_type == OP_DIE) { /* * If we are in void context, or the right side of the op is a * branch, we don't care what its value is - it won't be * returning one. We're just glad to be here, so we chalk up * success. */ NDEB(D(L, "Add conditional 2\n")); add_conditional(aTHX_ PL_op, 2); } else { char *ch; AV *conds; SV **cref, *cond; OP *next; if (PL_op->op_type == OP_XOR && left_val) { /* * This is an xor. It does not short circuit. We * have just executed the first op. When we get to * next we will have already done the xor, so we can * work out what the value of the second op was. * * We set a flag in the first element of the array * to say that we had a true value from the first * op. */ set_conditional(aTHX_ PL_op, 0, 1); } #if PERL_VERSION > 14 NDEB(D(L, "Getting next\n")); next = (PL_op->op_type == OP_XOR) ? PL_op->op_next : right->op_next; while (next && next->op_type == OP_NULL) next = next->op_next; #else next = PL_op->op_next; #endif if (!next) return; /* in fold_constants */ NDEB(op_dump(PL_op)); NDEB(op_dump(next)); ch = get_key(next); MUTEX_LOCK(&DC_mutex); cref = hv_fetch(Pending_conditionals, ch, KEY_SZ, 1); if (SvROK(*cref)) conds = (AV *)SvRV(*cref); else *cref = newRV_inc((SV*) (conds = newAV())); if (av_len(conds) < 0) { av_push(conds, newSViv(PTR2IV(next))); av_push(conds, newSViv(PTR2IV(next->op_ppaddr))); } #ifdef USE_ITHREADS conds = get_conds(aTHX_ conds); #endif cond = newSViv(PTR2IV(PL_op)); av_push(conds, cond); NDEB(D(L, "Adding conditional %p (%s) " "making %zd at %p (%s), ppaddr: %p\n", next, PL_op_name[next->op_targ], av_len(conds) - 1, PL_op, hex_key(ch), next->op_ppaddr)); /* dump_conditions(aTHX); */ NDEB(svdump(Pending_conditionals)); NDEB(op_dump(PL_op)); NDEB(op_dump(next)); next->op_ppaddr = get_condition; MUTEX_UNLOCK(&DC_mutex); } } else { /* short circuit */ #if PERL_VERSION > 14 OP *up = OpSIBLING(cLOGOP->op_first)->op_next; #if PERL_VERSION > 18 OP *skipped; #endif while (up && up->op_type == PL_op->op_type) { NDEB(D(L, "Considering adding %p (%s) -> (%p) " "from %p (%s) -> (%p)\n", up, PL_op_name[up->op_type], up->op_next, PL_op, PL_op_name[PL_op->op_type], PL_op->op_next)); add_conditional(aTHX_ up, 3); if (up->op_next == PL_op->op_next) break; up = OpSIBLING(cLOGOPx(up)->op_first)->op_next; } #endif add_conditional(aTHX_ PL_op, 3); #if PERL_VERSION > 18 skipped = PL_op; while ((skipped = find_skipped_conditional(aTHX_ skipped)) != NULL) add_conditional(aTHX_ skipped, 2); /* Should this ever be 1? */ #endif } } } #if PERL_VERSION > 16 /* A sequence of variable declarations may have been optimized * to a single OP_PADRANGE. The original sequence may span multiple lines, * but only the first line has been marked as covered for now. * Mark other OP_NEXTSTATE inside the original sequence of statements. */ static void cover_padrange(pTHX) { dMY_CXT; OP *next, *orig; if (!collecting(Statement)) return; next = PL_op->op_next; orig = OpSIBLING(PL_op); /* Ignore padrange preparing subroutine call */ while (orig && orig != next) { if (orig->op_type == OP_ENTERSUB) return; orig = orig->op_next; } orig = OpSIBLING(PL_op); while (orig && orig != next) { if (orig->op_type == OP_NEXTSTATE) { cover_statement(aTHX_ orig); } orig = orig->op_next; } } static OP *dc_padrange(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_padrange() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering) cover_padrange(aTHX); return MY_CXT.ppaddr[OP_PADRANGE](aTHX); } #endif static OP *dc_nextstate(pTHX) { dMY_CXT; NDEB(D(L, "dc_nextstate() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering) check_if_collecting(aTHX_ cCOP); if (collecting_here(aTHX)) cover_current_statement(aTHX); return MY_CXT.ppaddr[OP_NEXTSTATE](aTHX); } #if PERL_VERSION <= 10 static OP *dc_setstate(pTHX) { dMY_CXT; NDEB(D(L, "dc_setstate() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering) check_if_collecting(aTHX_ cCOP); if (collecting_here(aTHX)) cover_current_statement(aTHX); return MY_CXT.ppaddr[OP_SETSTATE](aTHX); } #endif static OP *dc_dbstate(pTHX) { dMY_CXT; NDEB(D(L, "dc_dbstate() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering) check_if_collecting(aTHX_ cCOP); if (collecting_here(aTHX)) cover_current_statement(aTHX); return MY_CXT.ppaddr[OP_DBSTATE](aTHX); } static OP *dc_entersub(pTHX) { dMY_CXT; NDEB(D(L, "dc_entersub() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering) store_return(aTHX); return MY_CXT.ppaddr[OP_ENTERSUB](aTHX); } static OP *dc_cond_expr(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_cond_expr() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_cond(aTHX); return MY_CXT.ppaddr[OP_COND_EXPR](aTHX); } static OP *dc_and(pTHX) { dMY_CXT; NDEB(D(L, "dc_and() at %p (%d)\n", PL_op, collecting_here(aTHX))); check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_and() at %p (%d)\n", PL_curcop, collecting_here(aTHX))); NDEB(D(L, "PL_curcop: %s:%ld\n", CopFILE(PL_curcop), (long)CopLINE(PL_curcop))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_AND](aTHX); } static OP *dc_andassign(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_andassign() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_ANDASSIGN](aTHX); } static OP *dc_or(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_or() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_OR](aTHX); } static OP *dc_orassign(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_orassign() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_ORASSIGN](aTHX); } #if PERL_VERSION > 8 static OP *dc_dor(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_dor() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_DOR](aTHX); } static OP *dc_dorassign(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_dorassign() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_DORASSIGN](aTHX); } #endif OP *dc_xor(pTHX) { dMY_CXT; check_if_collecting(aTHX_ PL_curcop); NDEB(D(L, "dc_xor() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) cover_logop(aTHX); return MY_CXT.ppaddr[OP_XOR](aTHX); } static OP *dc_require(pTHX) { dMY_CXT; NDEB(D(L, "dc_require() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) store_module(aTHX); return MY_CXT.ppaddr[OP_REQUIRE](aTHX); } static OP *dc_exec(pTHX) { dMY_CXT; NDEB(D(L, "dc_exec() at %p (%d)\n", PL_op, collecting_here(aTHX))); if (MY_CXT.covering && collecting_here(aTHX)) call_report(aTHX); return MY_CXT.ppaddr[OP_EXEC](aTHX); } static void replace_ops (pTHX) { dMY_CXT; int i; NDEB(D(L, "initialising replace_ops\n")); for (i = 0; i < MAXO; i++) MY_CXT.ppaddr[i] = PL_ppaddr[i]; PL_ppaddr[OP_NEXTSTATE] = dc_nextstate; #if PERL_VERSION <= 10 PL_ppaddr[OP_SETSTATE] = dc_setstate; #endif PL_ppaddr[OP_DBSTATE] = dc_dbstate; PL_ppaddr[OP_ENTERSUB] = dc_entersub; #if PERL_VERSION > 16 PL_ppaddr[OP_PADRANGE] = dc_padrange; #endif PL_ppaddr[OP_COND_EXPR] = dc_cond_expr; PL_ppaddr[OP_AND] = dc_and; PL_ppaddr[OP_ANDASSIGN] = dc_andassign; PL_ppaddr[OP_OR] = dc_or; PL_ppaddr[OP_ORASSIGN] = dc_orassign; #if PERL_VERSION > 8 PL_ppaddr[OP_DOR] = dc_dor; PL_ppaddr[OP_DORASSIGN] = dc_dorassign; #endif PL_ppaddr[OP_XOR] = dc_xor; PL_ppaddr[OP_REQUIRE] = dc_require; PL_ppaddr[OP_EXEC] = dc_exec; } static void initialise(pTHX) { dMY_CXT; NDEB(D(L, "initialising\n")); MUTEX_LOCK(&DC_mutex); if (!Pending_conditionals) { Pending_conditionals = newHV(); #ifdef USE_ITHREADS HvSHAREKEYS_off(Pending_conditionals); #endif } if (!Return_ops) { Return_ops = newHV(); #ifdef USE_ITHREADS HvSHAREKEYS_off(Return_ops); #endif } MUTEX_UNLOCK(&DC_mutex); MY_CXT.collecting_here = 1; if (!MY_CXT.covering) { /* TODO - this probably leaks all over the place */ SV **tmp; MY_CXT.cover = newHV(); #ifdef USE_ITHREADS HvSHAREKEYS_off(MY_CXT.cover); #endif tmp = hv_fetch(MY_CXT.cover, "statement", 9, 1); MY_CXT.statements = newHV(); *tmp = newRV_inc((SV*) MY_CXT.statements); tmp = hv_fetch(MY_CXT.cover, "branch", 6, 1); MY_CXT.branches = newHV(); *tmp = newRV_inc((SV*) MY_CXT.branches); tmp = hv_fetch(MY_CXT.cover, "condition", 9, 1); MY_CXT.conditions = newHV(); *tmp = newRV_inc((SV*) MY_CXT.conditions); #if CAN_PROFILE tmp = hv_fetch(MY_CXT.cover, "time", 4, 1); MY_CXT.times = newHV(); *tmp = newRV_inc((SV*) MY_CXT.times); #endif tmp = hv_fetch(MY_CXT.cover, "module", 6, 1); MY_CXT.modules = newHV(); *tmp = newRV_inc((SV*) MY_CXT.modules); MY_CXT.files = get_hv("Devel::Cover::Files", FALSE); #ifdef USE_ITHREADS HvSHAREKEYS_off(MY_CXT.statements); HvSHAREKEYS_off(MY_CXT.branches); HvSHAREKEYS_off(MY_CXT.conditions); #if CAN_PROFILE HvSHAREKEYS_off(MY_CXT.times); #endif HvSHAREKEYS_off(MY_CXT.modules); #endif MY_CXT.profiling_key_valid = 0; MY_CXT.module = newSVpv("", 0); MY_CXT.lastfile = newSVpvn("", 1); MY_CXT.covering = All; MY_CXT.tid = tid++; MY_CXT.replace_ops = SvTRUE(get_sv("Devel::Cover::Replace_ops", FALSE)); NDEB(D(L, "running with Replace_ops as %d\n", MY_CXT.replace_ops)); } } static int runops_cover(pTHX) { dMY_CXT; NDEB(D(L, "entering runops_cover\n")); #if defined HAS_GETTIMEOFDAY elapsed(); #elif defined HAS_TIMES cpu(); #endif for (;;) { NDEB(D(L, "running func %p from %p (%s)\n", PL_op->op_ppaddr, PL_op, OP_NAME(PL_op))); if (!MY_CXT.covering) goto call_fptr; /* Nothing to collect when we've hijacked the ppaddr */ { int hijacked; MUTEX_LOCK(&DC_mutex); hijacked = PL_op->op_ppaddr == get_condition; MUTEX_UNLOCK(&DC_mutex); if (hijacked) goto call_fptr; } /* Check to see whether we are interested in this file */ if (PL_op->op_type == OP_NEXTSTATE) check_if_collecting(aTHX_ cCOP); else if (PL_op->op_type == OP_ENTERSUB) store_return(aTHX); if (!collecting_here(aTHX)) goto call_fptr; /* * We are about the run the op PL_op, so we'll collect * information for it now */ switch (PL_op->op_type) { case OP_NEXTSTATE: #if PERL_VERSION <= 10 case OP_SETSTATE: #endif case OP_DBSTATE: { cover_current_statement(aTHX); break; } #if PERL_VERSION > 16 case OP_PADRANGE: { cover_padrange(aTHX); break; } #endif case OP_COND_EXPR: { cover_cond(aTHX); break; } case OP_AND: case OP_ANDASSIGN: case OP_OR: case OP_ORASSIGN: #if PERL_VERSION > 8 case OP_DOR: case OP_DORASSIGN: #endif case OP_XOR: { cover_logop(aTHX); break; } case OP_REQUIRE: { store_module(aTHX); break; } case OP_EXEC: { call_report(aTHX); break; } default: ; /* IBM's xlC compiler on AIX is very picky */ } call_fptr: if (!(PL_op = PL_op->op_ppaddr(aTHX))) break; PERL_ASYNC_CHECK(); } #if CAN_PROFILE cover_time(aTHX); #endif MY_CXT.collecting_here = 1; NDEB(D(L, "exiting runops_cover\n")); TAINT_NOT; return 0; } static int runops_orig(pTHX) { NDEB(D(L, "entering runops_orig\n")); while ((PL_op = PL_op->op_ppaddr(aTHX))) { PERL_ASYNC_CHECK(); } NDEB(D(L, "exiting runops_orig\n")); TAINT_NOT; return 0; } #if defined DO_RUNOPS_TRACE static int runops_trace(pTHX) { PDEB(D(L, "entering runops_trace\n")); for (;;) { PDEB(D(L, "running func %p from %p (%s)\n", PL_op->op_ppaddr, PL_op, OP_NAME(PL_op))); if (!(PL_op = PL_op->op_ppaddr(aTHX))) break; PERL_ASYNC_CHECK(); } PDEB(D(L, "exiting runops_trace\n")); TAINT_NOT; return 0; } #endif static char *svclassnames[] = { "B::NULL", "B::IV", "B::NV", "B::RV", "B::PV", "B::PVIV", "B::PVNV", "B::PVMG", "B::BM", "B::GV", "B::PVLV", "B::AV", "B::HV", "B::CV", "B::FM", "B::IO", }; static SV *make_sv_object(pTHX_ SV *arg, SV *sv) { IV iv; char *type; iv = PTR2IV(sv); type = svclassnames[SvTYPE(sv)]; sv_setiv(newSVrv(arg, type), iv); return arg; } typedef OP *B__OP; typedef AV *B__AV; MODULE = Devel::Cover PACKAGE = Devel::Cover PROTOTYPES: ENABLE void set_criteria(flag) unsigned flag PREINIT: dMY_CXT; PPCODE: MY_CXT.covering = flag; /* fprintf(stderr, "Cover set to %d\n", flag); */ if (MY_CXT.replace_ops) return; PL_runops = MY_CXT.covering ? runops_cover : runops_orig; void add_criteria(flag) unsigned flag PREINIT: dMY_CXT; PPCODE: MY_CXT.covering |= flag; if (MY_CXT.replace_ops) return; PL_runops = MY_CXT.covering ? runops_cover : runops_orig; void remove_criteria(flag) unsigned flag PREINIT: dMY_CXT; PPCODE: MY_CXT.covering &= ~flag; if (MY_CXT.replace_ops) return; PL_runops = MY_CXT.covering ? runops_cover : runops_orig; unsigned get_criteria() PREINIT: dMY_CXT; CODE: RETVAL = MY_CXT.covering; OUTPUT: RETVAL unsigned coverage_none() CODE: RETVAL = None; OUTPUT: RETVAL unsigned coverage_statement() CODE: RETVAL = Statement; OUTPUT: RETVAL unsigned coverage_branch() CODE: RETVAL = Branch; OUTPUT: RETVAL unsigned coverage_condition() CODE: RETVAL = Condition; OUTPUT: RETVAL unsigned coverage_subroutine() CODE: RETVAL = Subroutine; OUTPUT: RETVAL unsigned coverage_path() CODE: RETVAL = Path; OUTPUT: RETVAL unsigned coverage_pod() CODE: RETVAL = Pod; OUTPUT: RETVAL unsigned coverage_time() CODE: RETVAL = Time; OUTPUT: RETVAL unsigned coverage_all() CODE: RETVAL = All; OUTPUT: RETVAL double get_elapsed() CODE: #ifdef HAS_GETTIMEOFDAY RETVAL = get_elapsed(); #else RETVAL = 0; #endif OUTPUT: RETVAL SV * coverage(final) unsigned final PREINIT: dMY_CXT; CODE: NDEB(D(L, "Getting coverage %d\n", final)); if (final) finalise_conditions(aTHX); if (MY_CXT.cover) RETVAL = newRV_inc((SV*) MY_CXT.cover); else RETVAL = &PL_sv_undef; OUTPUT: RETVAL SV * get_key(o) B::OP o CODE: RETVAL = newSV(KEY_SZ + 1); sv_setpvn(RETVAL, get_key(o), KEY_SZ); OUTPUT: RETVAL void set_first_init_and_end() PPCODE: set_firsts_if_needed(aTHX); void collect_inits() PREINIT: dMY_CXT; PPCODE: int i; if (!MY_CXT.ends) MY_CXT.ends = newAV(); NDEB(svdump(MY_CXT.ends)); if (PL_initav) for (i = 0; i <= av_len(PL_initav); i++) { SV **cv = av_fetch(PL_initav, i, 0); SvREFCNT_inc(*cv); av_push(MY_CXT.ends, *cv); } void set_last_end() PREINIT: dMY_CXT; PPCODE: int i; SV *end = (SV *)get_cv("last_end", 0); av_push(PL_endav, end); NDEB(svdump(end)); if (!MY_CXT.ends) MY_CXT.ends = newAV(); if (PL_endav) for (i = 0; i <= av_len(PL_endav); i++) { SV **cv = av_fetch(PL_endav, i, 0); SvREFCNT_inc(*cv); av_push(MY_CXT.ends, *cv); } B::AV get_ends() PREINIT: dMY_CXT; CODE: if (!MY_CXT.ends) MY_CXT.ends = newAV(); /* TODO: how? */ RETVAL = MY_CXT.ends; OUTPUT: RETVAL BOOT: { MY_CXT_INIT; #ifdef USE_ITHREADS MUTEX_INIT(&DC_mutex); #endif initialise(aTHX); if (MY_CXT.replace_ops) { replace_ops(aTHX); #if defined HAS_GETTIMEOFDAY elapsed(); #elif defined HAS_TIMES cpu(); #endif #if defined DO_RUNOPS_TRACE PL_runops = runops_trace; #endif } else { PL_runops = runops_cover; } #if PERL_VERSION > 6 PL_savebegin = TRUE; #endif } dist.ini100644000765000024 654514631552031 14526 0ustar00pjcjstaff000000000000Devel-Cover-1.44name = Devel-Cover abstract = Code coverage metrics for Perl author = Paul Johnson license = Perl_5 copyright_holder = Paul Johnson [VersionFromScript] ; the version is stored in Makefile.PL script = make show_version [Run::BeforeBuild] ; commands to run before build phase run = perl Makefile.PL ; needed for VersionFromScript above [GatherDir] ; gather files from the dist dir include_dotfiles = 1 prune_directory = ^\.build$ [ManifestSkip] ; remove gathered files specified by MANIFEST.SKIP [ExecDir] ; mark bin as the dir to contain scripts [OurPkgVersion] ; add versions to the packages [PodVersion] ; add versions to the POD of packages [MetaYAML] ; create META.yml [MetaJSON] ; create META.json [MetaConfig] ; add dzil info to meta files [MetaResources] ; add resources to meta files homepage = http://www.pjcj.net/perl.html bugtracker.web = https://github.com/pjcj/Devel--Cover/issues license = http://dev.perl.org/licenses repository.url = http://github.com/pjcj/Devel--Cover repository.web = http://github.com/pjcj/Devel--Cover repository.type = git x_mailing_list = http://lists.perl.org/list/perl-qa.html x_IRC = irc://irc.perl.org/#perl-qa [MetaNoIndex] directory = tests directory = t directory = utils [MetaProvides::Package] [License] filename = LICENCE [Manifest] ; builds the manifest from the gathered files [Prereqs] perl = 5.012000 Storable = 0 Digest::MD5 = 0 HTML::Entities = 3.69 [Prereqs / Recommends] Template = 2.00 PPI::HTML = 1.07 Perl::Tidy = 20060719 Pod::Coverage = 0.06 Pod::Coverage::CountParents = 0 Parallel::Iterator = 0 JSON::MaybeXS = 1.003003 Test::Differences = 0 ; make sure it gets added Browser::Open = 0 Capture::Tiny = 0 Class::XSAccessor = 0 Moo = 0 namespace::clean = 0 HTML::Parser = 0 Sereal::Decoder = 0 Sereal::Encoder = 0 [Prereqs / ConfigureRequires] ExtUtils::MakeMaker = 0 [Prereqs / TestRequires] Test::More = 0.88 ; done_testing Math::BigInt = 0 ; so test reports will show version [Prereqs / TestRecommends] Test::Differences = 0 [Run::Test] run = perl Makefile.PL && make t [Git::Check] ; [CheckChangesHasContent] ; ensure Changes has been updated [NextRelease] ; fixes up the Changes file format = %v - %{d}d %{MMMM yyyy}d ; needs to be in this order [Git::Commit] ; check the release in [Git::Tag] ; and tag it [TestRelease] ; tests the dist before releasing [ConfirmRelease] ; asks for manual confirmation of release [UploadToCPAN] ; uploads to cpan [Git::Push] ; push to remote repository ; following can do stuff, but aren't used yet ; [ExtraTests] ; [PruneCruft] ; [ShareDir] ; [InsertCopyright] ; [EOLTests] ; [FakeFaker] ; [LocalBrew] ; [Bugtracker] ; [InstallGuide] tests000755000765000024 014631552031 14052 5ustar00pjcjstaff000000000000Devel-Cover-1.44if100644000765000024 70614631552031 14516 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; my ($x, $p, $q, $r, $s); $x = 0; if ($x) { $p++ } unless ($x) { $q++ } $x = 1; if ($x) { $r++ } if ($x) { $r++ } else { $s++ } unless ($x) { $s++ } t2100644000765000024 75414631552031 14450 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; my @x; sub xx { $x[shift]++; } for (0 .. 10) { time && $x[1]++; $x[2]++ if time; for (0 .. 2) { $x[3]++; } if (time) { xx(4); } else { $x[5]++; } } t1100644000765000024 47714631552031 14451 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; my @x; sub xx { $x[shift]++; } xx(4); t0100644000765000024 103514631552031 14457 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; my @x; my $y = 1; for (0 .. 10) { $y && $x[1]++; $y && $x[0]++ && $x[1]++; $x[2]++ if $y; for (0 .. 2) { $x[3]++; } if ($y) { $x[4]++; } else { $x[5]++; } } # print join(", ", @x), "\n"; utils000755000765000024 014631552031 14050 5ustar00pjcjstaff000000000000Devel-Cover-1.44dc100755000765000024 2211314631552031 14543 0ustar00pjcjstaff000000000000Devel-Cover-1.44/utils#!/usr/bin/env bash # Copyright 2001-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net if ((BASH_VERSINFO[0] < 5)); then echo "❌ bash version $BASH_VERSION is too old. Please install v5 or higher." exit 1 fi set -eEuo pipefail shopt -s inherit_errexit script=$(basename "$0") readl=readlink if command -v greadlink >&/dev/null; then readl=greadlink; fi srcdir=$("$readl" -f "$(dirname "$0")") readonly LOG_FILE="/tmp/$script.log" _p() { __l=$1 shift echo "$__l $script: $*" | tee -a "$LOG_FILE" >&2 } pt() { _p "[TRACE] " "$*"; } pd() { _p "[DEBUG] " "$*"; } pi() { _p "[INFO] " "$*"; } pw() { _p "[WARNING]" "$*"; } pe() { _p "[ERROR] " "$*"; } pf() { _p "[FATAL] " "$*" exit 1 } usage() { cat </dev/null # shellcheck disable=SC2181 if [[ $? == 0 ]]; then "$docker" logs "$name" >"$staging/$name.out" local_staging="$staging/$name" mkdir -p "$local_staging" "$docker" cp "$name:/root/staging" "$local_staging" if [[ -d $local_staging ]]; then sudo chmod -R 755 "$local_staging" sudo find "$local_staging" -type f -exec chmod 644 {} \; sudo chown -R pjcj:pjcj "$local_staging" cd "$local_staging"/* || exit for f in *; do if [[ -d $f ]]; then rm -rf "${staging:?}/$f" mv "$f" "$staging" fi done rm -r "$local_staging" fi fi "$docker" rm "$name" >/dev/null ;; cpancover-generate-html) pi "Generating HTML at $(date)" # perl -V "$0" cpancover-compress-old-versions "$0" cpancover --generate_html "$0" cpancover-compress json=$results_dir/cpancover.json tmp=$json-tmp-$$.gz pi "Compressing $json" pigz <"$json" >"$tmp" && mv "$tmp" "$json.gz" pi "Done" ;; cpancover-run) export DEVEL_COVER_CPUS=10 while true; do pi "Starting cpancover run at $(date) on $DEVEL_COVER_CPUS cpus" "$0" cpancover-rm-docker # just in case something bad happened "$0" cpancover-latest | "$0" cpancover "$0" cpancover-generate-html pi "Finished cpancover run at $(date)" sleep 600 # 10 minutes done ;; cpancover-compress-old-versions) keep="${2:-3}" "$0" cpancover --nobuild --compress_old_versions "$keep" ;; cpancover-kill-docker) "$docker" ps -a | tail -n +2 | awk '{ print $1 }' | xargs -r "$docker" kill ;; cpancover-rm-docker) "$docker" ps -a | tail -n +2 | awk '{ print $1 }' | xargs -r "$docker" rm -f "$docker" system prune --force ;; cpancover-start-queue) COVER_DEBUG=1 perl bin/queue minion worker -j 4 ;; cpancover-start-minion) COVER_DEBUG=1 perl bin/queue daemon -l http://\*:30000 -m production ;; cpancover-add) module="$2" COVER_DEBUG=1 perl bin/queue add "$module" ;; sereal_each_bug) perl="${2:-perl}" "$perl" Makefile.PL make rm -rf cover_db cp tests/trivial tests/change "$perl" -Mblib -MDevel::Cover tests/change cp tmp/change tests "$perl" -Mblib -MDevel::Cover tests/change "$perl" -Mblib bin/cover -report text rm tests/change ;; options) perl -nE 'say $1 =~ s/"//gr =~ s/\s*\|\s*/\n/gr' \ -E 'if /^ {2}"?([a-zA-Z0-9_ "|\\-]+)"?(?:\)|\s*\|\s*\\)$/' \ -E '&& $1 !~ /^_/' <"$0" ;; *) pf "Unknown option: $1" ;; esac } if [[ ${BASH_SOURCE[0]} == "$0" ]]; then trap cleanup EXIT INT main "$@" fi META.yml100644000765000024 3170414631552031 14346 0ustar00pjcjstaff000000000000Devel-Cover-1.44--- abstract: 'Code coverage metrics for Perl' author: - 'Paul Johnson ' build_requires: Math::BigInt: '0' Test::More: '0.88' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Devel-Cover no_index: directory: - t - tests - utils provides: Devel::Cover: file: lib/Devel/Cover.pm version: '1.44' Devel::Cover::Annotation::Git: file: lib/Devel/Cover/Annotation/Git.pm version: '1.44' Devel::Cover::Annotation::Random: file: lib/Devel/Cover/Annotation/Random.pm version: '1.44' Devel::Cover::Annotation::Svk: file: lib/Devel/Cover/Annotation/Svk.pm version: '1.44' Devel::Cover::Branch: file: lib/Devel/Cover/Branch.pm version: '1.44' Devel::Cover::Collection: file: lib/Devel/Cover/Collection.pm version: '1.44' Devel::Cover::Collection::Template::Provider: file: lib/Devel/Cover/Collection.pm version: '1.44' Devel::Cover::Condition: file: lib/Devel/Cover/Condition.pm version: '1.44' Devel::Cover::Condition_and_2: file: lib/Devel/Cover/Condition_and_2.pm version: '1.44' Devel::Cover::Condition_and_3: file: lib/Devel/Cover/Condition_and_3.pm version: '1.44' Devel::Cover::Condition_or_2: file: lib/Devel/Cover/Condition_or_2.pm version: '1.44' Devel::Cover::Condition_or_3: file: lib/Devel/Cover/Condition_or_3.pm version: '1.44' Devel::Cover::Condition_xor_4: file: lib/Devel/Cover/Condition_xor_4.pm version: '1.44' Devel::Cover::Criterion: file: lib/Devel/Cover/Criterion.pm version: '1.44' Devel::Cover::DB: file: lib/Devel/Cover/DB.pm version: '1.44' Devel::Cover::DB::Criterion: file: lib/Devel/Cover/Truth_Table.pm version: '1.44' Devel::Cover::DB::Digests: file: lib/Devel/Cover/DB/Digests.pm version: '1.44' Devel::Cover::DB::File: file: lib/Devel/Cover/DB/File.pm version: '1.44' Devel::Cover::DB::IO: file: lib/Devel/Cover/DB/IO.pm version: '1.44' Devel::Cover::DB::IO::Base: file: lib/Devel/Cover/DB/IO/Base.pm version: '1.44' Devel::Cover::DB::IO::JSON: file: lib/Devel/Cover/DB/IO/JSON.pm version: '1.44' Devel::Cover::DB::IO::Sereal: file: lib/Devel/Cover/DB/IO/Sereal.pm version: '1.44' Devel::Cover::DB::IO::Storable: file: lib/Devel/Cover/DB/IO/Storable.pm version: '1.44' Devel::Cover::DB::Run: file: lib/Devel/Cover/DB.pm version: '1.44' Devel::Cover::DB::Structure: file: lib/Devel/Cover/DB/Structure.pm version: '1.44' Devel::Cover::Html_Common: file: lib/Devel/Cover/Html_Common.pm version: '1.44' Devel::Cover::Op: file: lib/Devel/Cover/Op.pm version: '1.44' Devel::Cover::Pod: file: lib/Devel/Cover/Pod.pm version: '1.44' Devel::Cover::Report::Compilation: file: lib/Devel/Cover/Report/Compilation.pm version: '1.44' Devel::Cover::Report::Html: file: lib/Devel/Cover/Report/Html.pm version: '1.44' Devel::Cover::Report::Html_basic: file: lib/Devel/Cover/Report/Html_basic.pm version: '1.44' Devel::Cover::Report::Html_basic::Template::Provider: file: lib/Devel/Cover/Report/Html_basic.pm version: '1.44' Devel::Cover::Report::Html_minimal: file: lib/Devel/Cover/Report/Html_minimal.pm version: '1.44' Devel::Cover::Report::Html_subtle: file: lib/Devel/Cover/Report/Html_subtle.pm version: '1.44' Devel::Cover::Report::Html_subtle::Template::Provider: file: lib/Devel/Cover/Report/Html_subtle.pm version: '1.44' Devel::Cover::Report::Json: file: lib/Devel/Cover/Report/Json.pm version: '1.44' Devel::Cover::Report::Sort: file: lib/Devel/Cover/Report/Sort.pm version: '1.44' Devel::Cover::Report::Text: file: lib/Devel/Cover/Report/Text.pm version: '1.44' Devel::Cover::Report::Text2: file: lib/Devel/Cover/Report/Text2.pm version: '1.44' Devel::Cover::Report::Vim: file: lib/Devel/Cover/Report/Vim.pm version: '1.44' Devel::Cover::Report::Vim::Template::Provider: file: lib/Devel/Cover/Report/Vim.pm version: '1.44' Devel::Cover::Statement: file: lib/Devel/Cover/Statement.pm version: '1.44' Devel::Cover::Subroutine: file: lib/Devel/Cover/Subroutine.pm version: '1.44' Devel::Cover::Test: file: lib/Devel/Cover/Test.pm version: '1.44' Devel::Cover::Time: file: lib/Devel/Cover/Time.pm version: '1.44' Devel::Cover::Truth_Table: file: lib/Devel/Cover/Truth_Table.pm version: '1.44' Devel::Cover::Truth_Table::Row: file: lib/Devel/Cover/Truth_Table.pm version: '1.44' Devel::Cover::Util: file: lib/Devel/Cover/Util.pm version: '1.44' Devel::Cover::Web: file: lib/Devel/Cover/Web.pm version: '1.44' recommends: Browser::Open: '0' Capture::Tiny: '0' Class::XSAccessor: '0' HTML::Parser: '0' JSON::MaybeXS: '1.003003' Moo: '0' PPI::HTML: '1.07' Parallel::Iterator: '0' Perl::Tidy: '20060719' Pod::Coverage: '0.06' Pod::Coverage::CountParents: '0' Sereal::Decoder: '0' Sereal::Encoder: '0' Template: '2.00' Test::Differences: '0' namespace::clean: '0' requires: Digest::MD5: '0' HTML::Entities: '3.69' Storable: '0' perl: '5.012000' resources: IRC: irc://irc.perl.org/#perl-qa Mailing_list: http://lists.perl.org/list/perl-qa.html bugtracker: https://github.com/pjcj/Devel--Cover/issues homepage: http://www.pjcj.net/perl.html license: http://dev.perl.org/licenses repository: http://github.com/pjcj/Devel--Cover version: '1.44' x_Dist_Zilla: perl: version: '5.040000' plugins: - class: Dist::Zilla::Plugin::VersionFromScript name: VersionFromScript version: '0.017' - class: Dist::Zilla::Plugin::Run::BeforeBuild config: Dist::Zilla::Plugin::Run::Role::Runner: fatal_errors: 1 quiet: 0 run: - 'perl Makefile.PL' version: '0.050' name: Run::BeforeBuild version: '0.050' - class: Dist::Zilla::Plugin::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: [] exclude_match: [] follow_symlinks: 0 include_dotfiles: 1 prefix: '' prune_directory: - ^\.build$ root: . name: GatherDir version: '6.032' - class: Dist::Zilla::Plugin::ManifestSkip name: ManifestSkip version: '6.032' - class: Dist::Zilla::Plugin::ExecDir name: ExecDir version: '6.032' - class: Dist::Zilla::Plugin::OurPkgVersion name: OurPkgVersion version: '0.21' - class: Dist::Zilla::Plugin::PodVersion name: PodVersion version: '6.032' - class: Dist::Zilla::Plugin::MetaYAML name: MetaYAML version: '6.032' - class: Dist::Zilla::Plugin::MetaJSON name: MetaJSON version: '6.032' - class: Dist::Zilla::Plugin::MetaConfig name: MetaConfig version: '6.032' - class: Dist::Zilla::Plugin::MetaResources name: MetaResources version: '6.032' - class: Dist::Zilla::Plugin::MetaNoIndex name: MetaNoIndex version: '6.032' - class: Dist::Zilla::Plugin::MetaProvides::Package config: Dist::Zilla::Plugin::MetaProvides::Package: finder_objects: - class: Dist::Zilla::Plugin::FinderCode name: MetaProvides::Package/AUTOVIV/:InstallModulesPM version: '6.032' include_underscores: 0 Dist::Zilla::Role::MetaProvider::Provider: $Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004' inherit_missing: 1 inherit_version: 1 meta_noindex: 1 Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000038' version: '0.006' name: MetaProvides::Package version: '2.004003' - class: Dist::Zilla::Plugin::License name: License version: '6.032' - class: Dist::Zilla::Plugin::Manifest name: Manifest version: '6.032' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: runtime type: requires name: Prereqs version: '6.032' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: runtime type: recommends name: Recommends version: '6.032' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: configure type: requires name: ConfigureRequires version: '6.032' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: TestRequires version: '6.032' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: recommends name: TestRecommends version: '6.032' - class: Dist::Zilla::Plugin::Run::Test config: Dist::Zilla::Plugin::Run::Role::Runner: fatal_errors: 1 quiet: 0 run: - 'perl Makefile.PL && make t' version: '0.050' Dist::Zilla::Role::TestRunner: default_jobs: 1 name: Run::Test version: '0.050' - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.45.2 repo_root: . name: Git::Check version: '2.049' - class: Dist::Zilla::Plugin::NextRelease name: NextRelease version: '6.032' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: [] commit_msg: v%V%n%n%c signoff: 0 Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: 2.45.2 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: Git::Commit version: '2.049' - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ changelog: Changes signed: 0 tag: v1.44 tag_format: v%V tag_message: v%V Dist::Zilla::Role::Git::Repo: git_version: 2.45.2 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: Git::Tag version: '2.049' - class: Dist::Zilla::Plugin::TestRelease name: TestRelease version: '6.032' - class: Dist::Zilla::Plugin::ConfirmRelease name: ConfirmRelease version: '6.032' - class: Dist::Zilla::Plugin::UploadToCPAN name: UploadToCPAN version: '6.032' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: 2.45.2 repo_root: . name: Git::Push version: '2.049' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: '6.032' - class: Dist::Zilla::Plugin::FinderCode name: MetaProvides::Package/AUTOVIV/:InstallModulesPM version: '6.032' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: 0 version: '6.032' x_generated_by_perl: v5.40.0 x_serialization_backend: 'YAML::Tiny version 1.74' x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later' MANIFEST100644000765000024 1613514631552031 14227 0ustar00pjcjstaff000000000000Devel-Cover-1.44# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.032. .autoenv.zsh .editorconfig .github/workflows/ci.yml .gitignore .hadolint.yaml .markdownlint.yaml .mdformat.toml .perlcriticrc .perltidyrc .shellcheckrc .typos.toml .yamllint Changes Contributors Cover.xs LICENCE MANIFEST MANIFEST.SKIP META.json META.yml Makefile.PL README.md bin/cover bin/cpancover bin/gcov2perl bin/queue dist.ini docs/BUGS docs/CONTRIBUTING.md docs/RELEASE.md docs/TODO docs/cpancover.md lib/Devel/Cover.pm lib/Devel/Cover/Annotation/Git.pm lib/Devel/Cover/Annotation/Random.pm lib/Devel/Cover/Annotation/Svk.pm lib/Devel/Cover/Branch.pm lib/Devel/Cover/Collection.pm lib/Devel/Cover/Condition.pm lib/Devel/Cover/Condition_and_2.pm lib/Devel/Cover/Condition_and_3.pm lib/Devel/Cover/Condition_or_2.pm lib/Devel/Cover/Condition_or_3.pm lib/Devel/Cover/Condition_xor_4.pm lib/Devel/Cover/Criterion.pm lib/Devel/Cover/DB.pm lib/Devel/Cover/DB/Digests.pm lib/Devel/Cover/DB/File.pm lib/Devel/Cover/DB/IO.pm lib/Devel/Cover/DB/IO/Base.pm lib/Devel/Cover/DB/IO/JSON.pm lib/Devel/Cover/DB/IO/Sereal.pm lib/Devel/Cover/DB/IO/Storable.pm lib/Devel/Cover/DB/Structure.pm lib/Devel/Cover/Dumper.pm lib/Devel/Cover/Html_Common.pm lib/Devel/Cover/Op.pm lib/Devel/Cover/Pod.pm lib/Devel/Cover/Report/Compilation.pm lib/Devel/Cover/Report/Html.pm lib/Devel/Cover/Report/Html_basic.pm lib/Devel/Cover/Report/Html_minimal.pm lib/Devel/Cover/Report/Html_subtle.pm lib/Devel/Cover/Report/Json.pm lib/Devel/Cover/Report/Sort.pm lib/Devel/Cover/Report/Text.pm lib/Devel/Cover/Report/Text2.pm lib/Devel/Cover/Report/Vim.pm lib/Devel/Cover/Statement.pm lib/Devel/Cover/Subroutine.pm lib/Devel/Cover/Test.pm lib/Devel/Cover/Time.pm lib/Devel/Cover/Truth_Table.pm lib/Devel/Cover/Tutorial.pod lib/Devel/Cover/Util.pm lib/Devel/Cover/Web.pm t/00-report-prereqs.t t/internal/criteria.t t/internal/inc_filter.t t/internal/inc_filter/cwd/lib/.dummy t/internal/inc_filter/cwd_lib/.dummy t/internal/launch.t t/internal/subprocess.t t/regexp/regexp_eval.t test_output/cover/accessor.5.012000 test_output/cover/alias.5.012000 test_output/cover/alias1.5.012000 test_output/cover/and.5.012000 test_output/cover/bigint.5.032000 test_output/cover/branch_return_sub.5.012000 test_output/cover/change.5.012000 test_output/cover/circular_ref.5.012000 test_output/cover/cond_and.5.012000 test_output/cover/cond_branch.5.012000 test_output/cover/cond_branch.5.014000 test_output/cover/cond_branch.5.016000 test_output/cover/cond_branch.5.018000 test_output/cover/cond_chained.5.012000 test_output/cover/cond_chained.5.016000 test_output/cover/cond_or.5.012000 test_output/cover/cond_or.5.022000 test_output/cover/cond_or.5.038000 test_output/cover/cond_xor.5.012000 test_output/cover/cop.5.012000 test_output/cover/dbm_cond.5.014000 test_output/cover/dbm_cond.5.022000 test_output/cover/default_param.5.012000 test_output/cover/default_param.5.014000 test_output/cover/deparse.5.012000 test_output/cover/destroy.5.012000 test_output/cover/dynamic_subs.5.012000 test_output/cover/empty.5.012000 test_output/cover/end_constant.5.012000 test_output/cover/eval1.5.012000 test_output/cover/eval2.5.012000 test_output/cover/eval3.5.012000 test_output/cover/eval_merge.5.012000 test_output/cover/eval_merge.t.5.012000 test_output/cover/eval_merge_0.5.012000 test_output/cover/eval_merge_1.5.012000 test_output/cover/eval_merge_sep.t.5.012000 test_output/cover/eval_nested.5.012000 test_output/cover/eval_string.5.012000 test_output/cover/eval_sub.t.5.012000 test_output/cover/eval_use.t.5.012000 test_output/cover/exec.5.012000 test_output/cover/exec_die.5.012000 test_output/cover/final_op.5.012000 test_output/cover/fork.5.012000 test_output/cover/if.5.012000 test_output/cover/md5.5.012000 test_output/cover/module1.5.012000 test_output/cover/module2.5.012000 test_output/cover/module_ignore.5.012000 test_output/cover/module_import.5.012000 test_output/cover/module_relative.5.012000 test_output/cover/module_statements.5.012000 test_output/cover/moo_cond.5.012000 test_output/cover/moo_cond.5.022000 test_output/cover/moose_basic.5.012000 test_output/cover/moose_cond.5.012000 test_output/cover/moose_constraint.5.012000 test_output/cover/moose_constraint.5.016000 test_output/cover/overload_bool.5.012000 test_output/cover/overload_bool2.5.012000 test_output/cover/overload_bool2.5.022000 test_output/cover/overload_bool2.5.038000 test_output/cover/overloaded.5.012000 test_output/cover/padrange.5.012000 test_output/cover/padrange2.5.012000 test_output/cover/padrange2.5.018000 test_output/cover/padrange2.5.022000 test_output/cover/pod.5.012000 test_output/cover/pod_nocp.5.012000 test_output/cover/readonly.5.012000 test_output/cover/recursive_sub.5.016000 test_output/cover/redefine_sub.5.012000 test_output/cover/require.5.012000 test_output/cover/signature.5.032000 test_output/cover/skip.5.012000 test_output/cover/sort.5.012000 test_output/cover/special_blocks.5.012000 test_output/cover/statement.5.012000 test_output/cover/subs_only.5.012000 test_output/cover/t0.5.012000 test_output/cover/t1.5.012000 test_output/cover/t2.5.012000 test_output/cover/taint.5.012000 test_output/cover/trivial.5.012000 test_output/cover/uncoverable.5.012000 test_output/cover/uncoverable_error.5.012000 test_output/cover/uncoverable_error_ignore.5.012000 test_output/cover/v-58x.5.012000 test_output/cover/xor_constant_fold.5.012000 tests/.uncoverable tests/Accessor_maker.pm tests/Alias1.pm tests/COP.pm tests/E2.pm tests/E3.pm tests/E4.pm tests/IncSub.pm tests/Module1.pm tests/Module2.pm tests/Module_import.pm tests/PodMod.pm tests/Taint.pm tests/accessor tests/alias tests/alias1 tests/and tests/bigint tests/branch_return_sub tests/change.t tests/circular_ref tests/cond_and tests/cond_branch tests/cond_chained tests/cond_or tests/cond_or.pl tests/cond_xor tests/cop tests/dbm_cond tests/default_param tests/deparse tests/destroy tests/dist/DC-Test-Dist/Makefile.PL tests/dist/DC-Test-Dist/lib/DC/Test/Dist.pm tests/dist/DC-Test-Dist/lib/DC/Test/Dist/M1.pm tests/dist/DC-Test-Dist/t/t1.t tests/dynamic_subs tests/empty tests/end_constant tests/eval1 tests/eval2 tests/eval3 tests/eval_merge tests/eval_merge.t tests/eval_merge_0 tests/eval_merge_1 tests/eval_merge_sep.t tests/eval_nested tests/eval_string tests/eval_sub.t tests/eval_use.t tests/exec tests/exec_die tests/final_op tests/fork tests/if tests/inc_sub tests/md5.t tests/module1 tests/module2 tests/module_ignore tests/module_import tests/module_relative tests/module_statements tests/moo_cond tests/moose_basic tests/moose_cond tests/moose_constraint tests/overload_bool tests/overload_bool2 tests/overloaded tests/padrange tests/padrange2 tests/pod tests/pod_nocp tests/random/dir/file tests/readonly tests/recursive_sub tests/redefine_sub tests/require tests/signature tests/skip tests/sort tests/special_blocks tests/statement tests/subs_only tests/t0 tests/t1 tests/t2 tests/taint tests/trivial tests/uncoverable tests/uncoverable_error tests/uncoverable_error_ignore tests/v-58x tests/xor_constant_fold utils/Devel/Cover/BuildUtils.pm utils/all_versions utils/bisect.sh utils/cpancover.nginx utils/create_all_gold utils/create_gold utils/dc utils/mail_contributors utils/makeh utils/queue.conf utils/scanuncov utils/setup utils/typemap .yamllint100644000765000024 41414631552031 14661 0ustar00pjcjstaff000000000000Devel-Cover-1.44--- extends: default rules: braces: { min-spaces-inside: 1, max-spaces-inside: 1 } brackets: { min-spaces-inside: 1, max-spaces-inside: 1 } comments: level: error comments-indentation: disable document-start: level: error truthy: level: error README.md100644000765000024 606714631552031 14340 0ustar00pjcjstaff000000000000Devel-Cover-1.44# Devel::Cover ## Code coverage metrics for Perl This module provides code coverage metrics for Perl. Code coverage metrics describe how thoroughly tests exercise code. By using Devel::Cover you can discover areas of code not exercised by your tests and determine which tests to create to increase coverage. Code coverage can be considered an indirect measure of quality. Devel::Cover is now quite stable and provides many of the features to be expected in a useful coverage tool. Statement, branch, condition, subroutine, and pod coverage information is reported. Statement and subroutine coverage data should be accurate. Branch and condition coverage data should be mostly accurate too, although not always what one might initially expect. Pod coverage comes from Pod::Coverage. If Pod::Coverage::CountParents is available it will be used instead. The `cover` program can be used to generate coverage reports. Devel::Cover ships with a number of reports including various types of HTML output, textual reports, a report to display missing coverage in the same format as compilation errors and a report to display coverage information within the Vim editor. It is possible to add annotations to reports, for example you can add a column to an HTML report showing who last changed a line, as determined by git blame. Some annotation modules are shipped with Devel::Cover and you can easily create your own. The `gcov2perl` program can be used to convert gcov files to `Devel::Cover` databases. This allows you to display your C or XS code coverage together with your Perl coverage, or to use any of the Devel::Cover reports to display your C coverage data. Code coverage data are collected by replacing perl ops with functions which count how many times the ops are executed. These data are then mapped back to reality using the B compiler modules. There is also a statement profiling facility which should not be relied on. For proper profiling use [Devel::NYTProf](https://metacpan.org/pod/Devel::NYTProf). Previous versions of Devel::Cover collected coverage data by replacing perl's runops function. It is still possible to switch to that mode of operation, but this now gets little testing and will probably be removed soon. You probably don't care about any of this. The most appropriate mailing list on which to discuss this module would be [perl-qa](http://lists.perl.org/list/perl-qa.html). The Devel::Cover repository can be found on [github](http://github.com/pjcj/Devel--Cover). This is also where problems should be reported. To get coverage for an uninstalled module: ```sh cover -test ``` or ```sh cover -delete HARNESS_PERL_SWITCHES=-MDevel::Cover make test cover ``` To get coverage for an uninstalled module which uses Module::Build (0.26 or later): ```sh ./Build testcover ``` If the module does not use the t/\*.t framework: ```sh PERL5OPT=-MDevel::Cover make test ``` If you want to get coverage for a program: ```sh perl -MDevel::Cover yourprog args cover ``` To alter default values: ```sh perl -MDevel::Cover=-db,cover_db,-coverage,statement,time yourprog args ``` bin000755000765000024 014631552031 13460 5ustar00pjcjstaff000000000000Devel-Cover-1.44queue100755000765000024 1222314631552031 14712 0ustar00pjcjstaff000000000000Devel-Cover-1.44/bin#!/usr/bin/env perl use 5.26.0; # requires: Mojolicious Minion Minion::Backend::SQLite use Mojolicious::Lite -signatures; use Mojo::File; use CPAN::DistnameInfo; use Capture::Tiny "capture_merged"; my $Debug = $ENV{COVER_DEBUG}; plugin Config => { default => { minion => { SQLite => "sqlite:queue.db" }, # uploads_socket => "ws://api-3.cpantesters.org/v3/upload", uploads_socket => "ws://localhost:3001/v3/upload", results_dir => "/cover/staging_dev", }, }; plugin "Minion" => app->config->{minion}; plugin "Minion::Admin"; helper results => sub { Mojo::File->new(shift->app->config->{results_dir}) }; push app->static->paths->@*, app->results->to_string; push app->commands->namespaces->@*, "Devel::Cover::Queue::Commands"; package Devel::Cover::Queue::Commands::monitor { use Mojo::Base "Mojolicious::Command"; use Mojo::IOLoop; use Mojo::UserAgent; use Mojo::WebSocket; use Scalar::Util (); use experimental "signatures"; has ua => sub { Mojo::UserAgent->new->inactivity_timeout(0) }; sub run ($command) { say STDERR "run" if $Debug; $command->connect; Mojo::IOLoop->start; } sub connect ($command) { say STDERR "connect" if $Debug; my $url = $command->app->config->{uploads_socket}; Scalar::Util::weaken $command; $command->ua->websocket($url => sub ($, $tx) { unless ($tx->is_websocket) { $command->app->log->warn("Not a websocket"); Mojo::IOLoop->timer(1 => sub { $command->connect }); return; } say STDERR "CONNECTED" if $Debug; my $waiting; $tx->on(json => sub ($, $data) { print STDERR Mojo::Util::dumper $data if $Debug; $command->app->minion->enqueue(run_cover => [ $data ]); }); $tx->on(frame => sub ($, $frame) { return unless $frame->[4] eq Mojo::WebSocket::WS_PONG; say STDERR "PONG" if $Debug; $waiting = 0; }); my $pinger = Mojo::IOLoop->recurring(30 => sub { say STDERR "PING" if $Debug; return $tx->finish if $waiting; $waiting = 1; $tx->send([ 1, 0, 0, 0, Mojo::WebSocket::WS_PING, "" ]) }); $tx->on(finish => sub { Mojo::IOLoop->remove($pinger); say STDERR "FINISH" if $Debug; Mojo::IOLoop->timer(1 => sub { $command->connect }); }); }); } } package Devel::Cover::Queue::Commands::add { use Mojo::Base "Mojolicious::Command"; use experimental "signatures"; has description => "Add a distribution to the queue"; has usage => "add P/PJ/PJCJ/Shell-Source-0.01.tar.gz"; sub run ($command, $dist) { say STDERR "add $dist" if $Debug; $command->app->minion->enqueue(run_cover => [ $dist ]); } } helper release_covered => sub ($c, $release) { my $check = $c->results->child($release)->to_abs; -d "$check" }; helper visit_latest_releases => sub ($c, $cb) { require CPAN::Releases::Latest; my $latest = CPAN::Releases::Latest->new(max_age => 0); # no caching my $iterator = $latest->release_iterator; while (my $release = $iterator->next_release) { $c->$cb($release) } }; app->minion->add_task(generate_html => sub ($job) { my $results = $job->app->results->to_abs; my $command = "dc -v -r $results cpancover-generate-html"; system $command; }); app->minion->add_task(enqueue_latest => sub ($job) { say STDERR "run enqueue_latest" if $Debug; my $app = $job->app; my $minion = $app->minion; $app->visit_latest_releases(sub ($, $r) { return if $app->release_covered($r->distinfo->distvname); $minion->enqueue(run_cover => [ $r->path ]); }); }); app->minion->add_task(run_cover => sub ($job, $data, $opts = undef) { say STDERR "run_cover $data" if $Debug; # say STDERR "path $ENV{PATH}" if $Debug; # say STDERR `which dc` if $Debug; # say STDERR `which perl` if $Debug; my $path = ""; my $file = ""; my $release = ""; if (ref $data) { $path .= substr($data->{author}, 0, 1) . "/"; $path .= substr($data->{author}, 0, 2) . "/"; $path .= "$data->{author}/$data->{filename}"; $file = $data->{filename}; $release = "$data->{dist}-$data->{version}"; } else { $path = $data; my $d = CPAN::DistnameInfo->new("authors/id/$path"); $file = $d->filename; $release = $d->distvname; } my $results = $job->app->results->to_abs; my $command = "dc -v -r $results cpancover $path"; my $output = capture_merged { system $command }; say STDERR $output if $Debug; if ($job->app->release_covered($release)) { $job->finish({ command => $command, message => "$file was processed", }); } else { $job->fail({ command => $command, message => "$file was not processed correctly", output => $output, }); } }); app->start cover100755000765000024 5357214631552031 14720 0ustar00pjcjstaff000000000000Devel-Cover-1.44/bin#!/usr/bin/perl # Copyright 2001-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net require 5.12.0; use strict; use warnings; our $VERSION; BEGIN { our $VERSION = '1.44'; # VERSION } use Devel::Cover::DB; use Devel::Cover::Inc; BEGIN { $VERSION //= $Devel::Cover::Inc::VERSION } use Config; use File::Spec; use File::Find (); use File::Path; use Getopt::Long; use Pod::Usage; use Storable qw( dclone ); use Devel::Cover::Dumper; # For debugging use Data::Dumper (); # no import of Dumper (use Devel::Cover::Dumper if needed) my $Options = { add_uncoverable_point => [], annotation => [], gcov_chdir => 0, coverage => [], delete => undef, delete_uncoverable_point => [], gcov => $Config{gccversion}, ignore => [], ignore_re => [], launch => 0, make => $Config{make}, prefer_lib => 0, relative_only => 0, report => [], report_c0 => 75, report_c1 => 90, report_c2 => 100, select => [], select_re => [], summary => 1, uncoverable_file => [], # .uncoverable and ~/.uncoverable are always checked }; sub get_options { Getopt::Long::Configure("pass_through"); die "Bad option" unless GetOptions($Options, # Store the options in the Options hash. "write:s" => sub { @$Options{qw( write summary )} = ($_[1], 0) }, qw( add_uncoverable_point=s annotation=s clean_uncoverable_points! coverage=s delete! delete_uncoverable_point=s dump_db! gcov! gcov_chdir! help|h! ignore=s ignore_covered_err! ignore_re=s info|i! launch! make=s outputdir=s prefer_lib! relative_only! report=s report_c0=s report_c1=s report_c2=s select=s select_re=s silent! summary! test! uncoverable_file=s version|v! )); Getopt::Long::Configure("nopass_through"); $Options->{report} = ["html"] if !@{$Options->{report}} && !exists $Options->{write}; # handle comma separated ops, like -coverage branch,statement # also accept them in the same format they're output my %coverage_abbrev = ( stmt => "statement", bran => "branch", cond => "condition", sub => "subroutine", ); my %coverage_allowed = map {$_ => 1} values %coverage_abbrev, "time", "pod"; # expanding 'default' to all available @{$Options->{coverage}} = map { $_ eq "default" ? (keys %coverage_allowed) : $_ } split(/,/, join(",", @{$Options->{coverage}})); # delete exclusions from that list for my $exclusion (grep /^-/, @{$Options->{coverage}}) { $exclusion = substr($exclusion, 1); # chop off leading - $Options->{coverage} = [grep $_ ne $exclusion, @{$Options->{coverage}}]; } my %options_coverage = map {$_ => 1} @{$Options->{coverage}}; while (my ($abbr, $full) = each %coverage_abbrev) { $options_coverage{$full} = delete $options_coverage{$abbr} if $options_coverage{$abbr}; } @{$Options->{coverage}} = keys %options_coverage; # generating data may take time, so bail now if options are wrong for my $cov (@{$Options->{coverage}}) { die "Unrecognised -coverage: $cov" unless $coverage_allowed{$cov}; } } sub delete_db { for my $del (@_) { my $db = Devel::Cover::DB->new(db => $del); unless ($db->is_valid) { print "Devel::Cover: $del is an invalid database - ignoring\n" unless $Options->{silent}; next; } print "Deleting database $del\n" if $db->exists && !$Options->{silent}; $db->delete; rmtree($del); } } # Decide whether to run ./Build test or make test sub test_command { -e "Build" ? mb_test_command() : mm_test_command() } # Compiler arguments necessary to do a coverage run sub gcov_args() { "-fprofile-arcs -ftest-coverage" } # Test command for MakeMaker sub mm_test_command { my $test = "$Options->{make} test"; if ($Options->{gcov}) { my $o = gcov_args(); $test .= qq{ "OPTIMIZE=-O0 $o" "OTHERLDFLAGS=$o"}; } $test } # Test command for Module::Build sub mb_test_command { my $builder = File::Spec->catfile(File::Spec->curdir, "Build"); my $test = "$builder test"; if ($Options->{gcov}) { my $c = my $l = gcov_args(); if (my $params = do("./_build/build_params")) { $c = join(' ', @{$params->[-1]{extra_compiler_flags} || []}, $c); $l = join(' ', @{$params->[-1]{extra_linker_flags} || []}, $c); } $test .= qq{ --extra_compiler_flags="-O0 $c" --extra_linker_flags="$l"}; } $test } sub main { $|++; # try to impose order on STDOUT and STDERR if (!$ENV{DEVEL_COVER_SELF} && $INC{"Devel/Cover.pm"}) { my $err = "$0 shouldn't be run with coverage turned on.\n"; eval { require POSIX; print STDERR $err; POSIX::_exit(1); }; die $err; } get_options; $Devel::Cover::Silent = 1 if $Options->{silent}; $Devel::Cover::Ignore_covered_err = 1 if $Options->{ignore_covered_err}; $Options->{report} = [ grep { my $report = $_; my $format = "Devel::Cover::Report::\u$report"; eval ("use $format"); if ($@) { print "Error: $report is not a recognised output format\n$@\n\n"; () } else { $report } } @{$Options->{report}} ]; exit 1 if !@{$Options->{report}} && !$Options->{delete} && !exists $Options->{write}; $Options->{annotations} = []; for my $a (@{$Options->{annotation}}) { my $annotation = "Devel::Cover::Annotation::\u$a"; eval ("use $annotation"); if ($@) { print "Error: $a is not a recognised annotation\n\n$@"; exit 1; } my $ann = $annotation->new; $ann->get_options($Options) if $ann->can("get_options"); push @{$Options->{annotations}}, $ann; } print "$0 version $VERSION\n" and exit 0 if $Options->{version}; pod2usage(-exitval => 0, -verbose => 1) if $Options->{help}; pod2usage(-exitval => 0, -verbose => 2) if $Options->{info}; my @argv = @ARGV; my $options = dclone($Options); my $report = $Options->{report}[0]; my $format = "Devel::Cover::Report::\u$report"; $format->get_options($options) if $format->can("get_options"); my $dbname = File::Spec->rel2abs(@ARGV ? shift @ARGV : "cover_db"); die "Can't open database $dbname\n" if !$Options->{delete} && !$Options->{test} && !-d $dbname; $Options->{outputdir} = $dbname unless exists $Options->{outputdir}; my $od = File::Spec->rel2abs($Options->{outputdir}); $Options->{outputdir} = $od if defined $od; mkpath($Options->{outputdir}) unless -d $Options->{outputdir}; if ($Options->{delete}) { delete_db($dbname, @ARGV); exit 0 } my $test_result = 0; if ($Options->{test}) { # TODO - make this a little more robust # system "$^X Makefile.PL" unless -e "Makefile"; delete_db($dbname, @ARGV) unless defined $Options->{delete}; my $env_db_name = $dbname; $env_db_name =~ s/\\/\\\\/g if $^O eq 'MSWin32'; $env_db_name =~ s/ /\\ /g; my $extra = ""; $extra .= ",-coverage,$_" for @{$Options->{coverage}}; $extra .= ",-ignore,$_" for @{$Options->{ignore_re}}, map quotemeta, map glob, @{$Options->{ignore}}; $extra .= ",-select,$_" for @{$Options->{select_re}}, map quotemeta, map glob, @{$Options->{select}}; $Options->{$_} = [] for qw( ignore ignoring select select_re ); local $ENV{ -d "t" ? "HARNESS_PERL_SWITCHES" : "PERL5OPT" } = ($ENV{DEVEL_COVER_TEST_OPTS} || "") . " -MDevel::Cover=-db,$env_db_name$extra"; my $test = test_command(); # touch the XS, C and H files so they rebuild if ($Options->{gcov}) { my $t = $] > 5.7 ? undef : time; my $xs = sub { utime $t, $t, $_ if /\.(xs|cc?|cpp|hh?|hpp)$/ }; File::Find::find({ wanted => $xs, no_chdir => 0 }, "."); } # print STDERR "$_: $ENV{$_}\n" for qw(PERL5OPT HARNESS_PERL_SWITCHES); print STDERR "cover: running $test\n"; $test_result = system $test; $test_result >>= 8; $Options->{report} = ["html"] unless @{$Options->{report}}; } if ($Options->{gcov}) { my $gc = sub { return unless /\.(xs|cc?|hh?)$/; for my $re (@{$Options->{ignore_re}}) { return if /$re/; } my ($name) = /([^\/]+$)/; # Don't bother running gcov if there's no index files. # Otherwise it's noisy. my $graph_file = $_; $graph_file =~ s{\.\w+$}{.gcno}; return unless -e $graph_file; my $gcov_flags = "-abc"; $gcov_flags .= "r" if $Options->{relative_only}; my @args = $Options->{gcov_chdir} ? () : ("-o", $File::Find::dir); my @c = ("gcov", $gcov_flags, @args, $name); print STDERR "cover: running @c\n"; system @c; }; File::Find::find( { wanted => $gc, no_chdir => !$Options->{gcov_chdir} }, "." ); my @gc; my $gp = sub { return unless /\.gcov$/; my $xs = $_; return if $xs =~ s/\.(cc?|hh?)\.gcov$/.xs.gcov/ && -e $xs; s/^\.\///; push @gc, $_; }; File::Find::find({ wanted => $gp, no_chdir => 1 }, "."); if (@gc) { # Find the right gcov2perl based on this current script require Cwd; my $path = Cwd::abs_path($0); my ($vol, $dir, $cover) = File::Spec->splitpath($path); my $gcov2perl = File::Spec->catpath($vol, $dir, 'gcov2perl'); my $o = $ENV{DEVEL_COVER_TEST_OPTS}; my @opts = defined $o ? split " ", $o : (); # print STDERR "cover: test [$o]\n"; my @c = ($^X, @opts, $gcov2perl, "-db", $dbname, @gc); print STDERR "cover: running @c\n"; system @c; } } print "Reading database from $dbname\n" unless $Options->{silent}; my $db = Devel::Cover::DB->new( db => $dbname, prefer_lib => $Options->{prefer_lib}, uncoverable_file => $Options->{uncoverable_file}, ); $db = $db->merge_runs; $db->add_uncoverable ($Options->{add_uncoverable_point} ); $db->delete_uncoverable ($Options->{delete_uncoverable_point}); $db->clean_uncoverable if $Options->{clean_uncoverable_points} ; exit $test_result if @{$Options->{add_uncoverable_point}} || @{$Options->{delete_uncoverable_point}} || $Options->{clean_uncoverable_points}; my $structure; my $read_structure = sub { unless ($structure) { $structure = Devel::Cover::DB::Structure->new(base => $dbname); $structure->read_all; } }; for my $merge (@ARGV) { $read_structure->(); print "Merging database from $merge\n" unless $Options->{silent}; my $mdb = Devel::Cover::DB->new(db => $merge); $mdb = $mdb->merge_runs; $db->merge($mdb); my $mst = Devel::Cover::DB::Structure->new(base => $merge); $mst->read_all; # print STDERR "Merging structure", Dumper($structure), # "From ", Dumper($mst); $structure->merge($mst); $db->set_structure($structure); # print STDERR "Merged structure", Dumper($structure); } if ($Options->{dump_db}) { my $d = Data::Dumper->new([$db], ["db"]); $d->Indent(1); $d->Sortkeys(1) if $] >= 5.008; print $d->Dump; $read_structure->(); my $s = Data::Dumper->new([$structure], ["structure"]); $s->Indent(1); $s->Sortkeys(1) if $] >= 5.008; print $s->Dump; exit $test_result; } if (exists $Options->{write}) { $dbname = $Options->{write} if length $Options->{write}; print "Writing database to $dbname\n" unless $Options->{silent}; $db->write($dbname); $read_structure->(); $structure->write($dbname); } $db->clean; exit $test_result unless $Options->{summary} || @{$Options->{report}}; $Options->{coverage} = [ $db->collected ] unless @{$Options->{coverage}}; $Options->{show} = { map { $_ => 1 } @{$Options->{coverage}} }; $Options->{show}{total} = 1 if keys %{$Options->{show}}; $db->calculate_summary(map { $_ => 1 } @{$Options->{coverage}}); print "\n\n" unless $Options->{silent}; # TODO - The sense of select and ignore should be reversed to match # collection - check this my %f = map { $_ => 1 } (@{$Options->{select}} ? map glob, @{$Options->{select}} : $db->cover->items); delete @f{map glob, @{$Options->{ignore}}}; my $keep = sub { my ($f) = @_; return 0 unless exists $db->{summary}{$_}; for (@{$Options->{ignore_re}}) { return 0 if $f =~ /$_/ } for (@{$Options->{select_re}}) { return 1 if $f =~ /$_/ } !@{$Options->{select_re}} }; @{$Options->{file}} = sort grep $keep->($_), keys %f; $db->print_summary($Options->{file}, $Options->{coverage}, {force => 1}) if $Options->{summary}; for my $report (@{$Options->{report}}) { @ARGV = @argv; my $options = dclone($Options); my $format = "Devel::Cover::Report::\u$report"; $format->get_options($options) if $format->can("get_options"); $format->report($db, $options); if ($options->{launch}) { if ($format->can("launch")) { $format->launch($options); } else { print STDERR "The launch option is not available for the ", "$options->{report} report.\n" } } } exit $test_result; } main __END__ =head1 NAME cover - report coverage statistics =head1 VERSION version 1.44 =head1 SYNOPSIS cover -test cover -report html_basic =head1 DESCRIPTION Report coverage statistics in a variety of formats. The summary option produces a short textual summary. Other reports are available by using the report option. The following reports are currently available: html - detailed HTML reports (default) html_basic - detailed HTML reports with syntax highlighting text - detailed textual summary compilation - output in a format similar to Perl errors json - output in a JSON format vim - show coverage information in vim gutter =head1 OPTIONS The following command line options are supported: -h -help - show help -i -info - show documentation -v -version - show version -silent - don't print informational messages (default off) -summary - give summary report (default on) -report report_format - report format (default html) -outputdir dir - directory for output (default given db) -launch - launch report in viewer (if avail) (default off) -select filename - only report on the file (default all) -ignore filename - don't report on the file (default none) -select_re RE - append to REs of files to select (default none) -ignore_re RE - append to REs of files to ignore (default none) -relative_only - for XS, ignore absolute paths (default off) -gcov_chdir - for XS, run gcov in subdirs (default off) -write [db] - write the merged database (default off) -delete - drop database(s) (default off) -dump_db - dump database(s) (for debugging) (default off) -coverage criterion - report on criterion (default all available) -test - drop database(s) and run make test (default off) -gcov - run gcov to cover XS code (default on if using gcc) -make make_prog - use the given 'make' program for 'make test' -prefer_lib - prefer files in lib (default off) -ignore_covered_err - allow coverung uncoverable code (default off) -add_uncoverable_point string -delete_uncoverable_point string -clean_uncoverable_points -uncoverable_file file other options specific to the report format coverage_database [coverage_database ...] The C<-report>, C<-select>, C<-ignore>, C<-select_re>, C<-ignore_re>, and C<-coverage> options may be specified multiple times. =head1 REPORT FORMATS The following C<-report> options are available in the core module. Other reports may be available if they've been installed from external packages. =over 4 =item html|html_minimal (default) HTML reporting. Percentage thresholds are colour-coded and configurable via -report_c0 , -report_c1 and -report_c2 .: 0% 75% 90% 100% | .. | .. | .. | or L module is detected. Like html|html_minimal reporting, percentage thresholds are colour-coded and configurable. =item text Plain text reporting. =item compilation A textual report in a format similar to that output by Perl itself such that the report may be used by your editor or other reporting tools to show where coverage is missing. =item json A report in JSON format. =item vim A report suitable for use with the vim editor to show coverage data in the sign column. =back =head1 DETAILS Any number of coverage databases may be specified on the command line. These databases will be merged and the reports will be based on the merged information. If no databases are specified the default database (cover_db) will be used. The C<-write> option will write out the merged database. If no name is given for the new database, the first database read in will be overwritten. When this option is used no reports are generated by default. Specify the C<-select>, C<-select_re>, C<-ignore>, and C<-ignore_re> options to report on specific files. C<-select> and C<-ignore> are interpreted as shell globs; C<-select_re> and C<-ignore_re> are interpreted as regular expressions. Specify C<-coverage> options to report on specific criteria. By default all available information on all criteria in all files will be reported. Available coverage options are statement, branch, condition, subroutine, pod, and default (which equates to all available options). However, if you know you only want coverage information for certain criteria it is better to only collect data for those criteria in the first place by specifying them at that point. This will make the data collection and reporting processes faster and less memory intensive. See the documentation for L for more information. If you want all *except* some criteria, then you can say something like C<-coverage default,-pod>. If you specify multiple C<-report> options, make sure that they do not conflict. For example, the different HTML reports will overwrite each other's results. The C<-test> option will delete the databases and run your tests to generate new coverage data before reporting on it. L knows how to work with standard Perl Makefiles as well as L based distributions. For detailed instructions see the documentation for ExtUtils::MakeMaker at L or for Module::Build at L both of which come as standard in recent Perl distributions. The C<-gcov> option will try to run gcov on any XS code. This requires that you are using gcc of course. If you are using the C<-test> option will be turned on by default. If you have XS code in subdirectories, you will probably need to add the C<-gcov_chdir> option since gcov seems to work better with that. The C<-prefer_lib> option tells Devel::Cover to report on files in the lib directory even if they were used from the blib directory. The C<-ignore_covered_err> option will not flag an error if uncoverable code is covered. =head1 EXIT STATUS The following exit values are returned: 0 All operations were completed successfully. >0 An error occurred. With the -test option the exit status of the underlying test run is returned. =head1 SEE ALSO L =head1 BUGS Did I mention that this is alpha code? See the BUGS file. =head1 LICENCE Copyright 2001-2024, Paul Johnson (paul@pjcj.net) This software is free. It is licensed under the same terms as Perl itself. The latest version of this software should be available from my homepage: http://www.pjcj.net =cut pod100644000765000024 115314631552031 14717 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net # __COVER__ criteria pod-also_private-xx # __COVER__ skip_test eval "use Pod::Coverage::CountParents"; $@ # __COVER__ skip_reason Pod::Coverage::CountParents unavailable use strict; use warnings; use lib "tests"; use PodMod; my @x; sub xx { $x[shift]++; Module1::zz(0); } for (0 .. 10) { if (time) { xx(0); } else { $x[1]++; } } and100644000765000024 66714631552031 14670 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2013-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net my $x = 1; my $y = 1; if ($x && !$y) { die "Urgh"; } if ($x && $y) { } unless ($x && $y) { die "Urgh"; } if (!($x && $y)) { die "Urgh"; } if (!$x || !$y) { die "Urgh"; } cop100644000765000024 52314631552031 14676 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2011-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; use lib "tests"; $SIG{__WARN__} = sub { die @_ }; require COP; docs000755000765000024 014631552031 13640 5ustar00pjcjstaff000000000000Devel-Cover-1.44BUGS100644000765000024 150514631552031 14464 0ustar00pjcjstaff000000000000Devel-Cover-1.44/docs- BEGIN and CHECK blocks and code in modules is not reported. - Doesn't play nicely with all of Perl's testsuite. - elsif and else coverage is reported on the same line as the if statement. This is because perl doesn't store the line number for the elsif and elses. For the same reason the following warning is reported on line 1 rather than line 2: perl -we 'if ($a) {} elsif ($a + 1) {}' Use of uninitialized value in addition (+) at -e line 1. - Pod coverage only reports data for modules, not top level scripts. This is a limitation in Pod::Coverage. - Pod coverage does not work well with source filters including Switch. Line numbers are reported incorrectly. - If an END block installs another END block it won't be covered. More generally, any code run after Devel::Cover's END block won't be covered. TODO100644000765000024 532414631552031 14474 0ustar00pjcjstaff000000000000Devel-Cover-1.44/docs- Enhancements: - Different criteria for different runs - Marking of unreachable code - commandline tool and gui - Threads support - at least for some coverage criteria - Test analysis - Profiling and speedups - Collect data for path coverage - Mutation coverage - Regular Expression coverage - Indicate how to increase coverage? - BEGIN and CHECK blocks and code in modules. Requires callbacks from perl? - Create a base class for Devel::Cover::Branch and Devel::Cover::Condition - Handle C< $y || "${p}qqq" > - 22:09 <@nothingmuch> return, redo, next, last, goto should probably all be treated as short circuiting - Add aliased subroutines to subroutine coverage - Accommodate reloading modules at runtime (Mark Glines) - Don't count BEGIN blocks as subroutines - Only collect boolean data for coverage information (no counts) - cpancover - Extend cpancover so people can upload databases - Provide a view by author - Add verbosity option and set silent option from it - Get Sort report working - Reports: - Improve textual output - Remove >= 100% in customisable thresholds - Move HTML version and platform info to main page and allow for multiples - Add -db option to cover - Diff functionality - Merge CSS from basic_html and cpancover - Provide a way to control syntax colouring - Cyclomatic complexity annotation - Bugs: - Work with memoize. Is this still a problem? - See if the XS code leaks, and fix it if it does - Look at time coverage again - collecting for too many ops? - Sort out time coverage on Windows - Check for core dumps with pod coverage - Fix "ignored" errors - see IO::Pager - cpancover on CPAN: - PerlIO-eol-0.13 hangs - CPAN@1432 hangs with bleadperl@29642 - cover -delete uses too much memory when cover_db doesn't exist. (clkao) - Games::Bingo broken - Class::Unload only giving 50% coverage on return unless ... (losing data?) - JSON error in Archive::Extract and Test::LeakTrace - cover -write new_db doesn't work (needs structure?) - Testing: - Be able to run Devel::Cover on itself - More comprehensive - Functional tests - Overhaul test system. Include patt? - Tests for INIT and END blocks included in required files when the files are used in some runs - Make sure dor is handled correctly and add more tests to cond_or - Build: - Fix up make text and friends for module_ignore - Check for matching threadedness, 64bits etc. between build and run? - Documentation: - General improvement - Examples - Cookbook including +/-inc, +/-ignore and +/-select - Document cpancover options - Pod in private modules - Developer documentation - Better DB API docs (including writing?) META.json100644000765000024 4755514631552031 14531 0ustar00pjcjstaff000000000000Devel-Cover-1.44{ "abstract" : "Code coverage metrics for Perl", "author" : [ "Paul Johnson " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.032, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Devel-Cover", "no_index" : { "directory" : [ "t", "tests", "utils" ] }, "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "recommends" : { "Browser::Open" : "0", "Capture::Tiny" : "0", "Class::XSAccessor" : "0", "HTML::Parser" : "0", "JSON::MaybeXS" : "1.003003", "Moo" : "0", "PPI::HTML" : "1.07", "Parallel::Iterator" : "0", "Perl::Tidy" : "20060719", "Pod::Coverage" : "0.06", "Pod::Coverage::CountParents" : "0", "Sereal::Decoder" : "0", "Sereal::Encoder" : "0", "Template" : "2.00", "Test::Differences" : "0", "namespace::clean" : "0" }, "requires" : { "Digest::MD5" : "0", "HTML::Entities" : "3.69", "Storable" : "0", "perl" : "5.012000" } }, "test" : { "recommends" : { "Test::Differences" : "0" }, "requires" : { "Math::BigInt" : "0", "Test::More" : "0.88" } } }, "provides" : { "Devel::Cover" : { "file" : "lib/Devel/Cover.pm", "version" : "1.44" }, "Devel::Cover::Annotation::Git" : { "file" : "lib/Devel/Cover/Annotation/Git.pm", "version" : "1.44" }, "Devel::Cover::Annotation::Random" : { "file" : "lib/Devel/Cover/Annotation/Random.pm", "version" : "1.44" }, "Devel::Cover::Annotation::Svk" : { "file" : "lib/Devel/Cover/Annotation/Svk.pm", "version" : "1.44" }, "Devel::Cover::Branch" : { "file" : "lib/Devel/Cover/Branch.pm", "version" : "1.44" }, "Devel::Cover::Collection" : { "file" : "lib/Devel/Cover/Collection.pm", "version" : "1.44" }, "Devel::Cover::Collection::Template::Provider" : { "file" : "lib/Devel/Cover/Collection.pm", "version" : "1.44" }, "Devel::Cover::Condition" : { "file" : "lib/Devel/Cover/Condition.pm", "version" : "1.44" }, "Devel::Cover::Condition_and_2" : { "file" : "lib/Devel/Cover/Condition_and_2.pm", "version" : "1.44" }, "Devel::Cover::Condition_and_3" : { "file" : "lib/Devel/Cover/Condition_and_3.pm", "version" : "1.44" }, "Devel::Cover::Condition_or_2" : { "file" : "lib/Devel/Cover/Condition_or_2.pm", "version" : "1.44" }, "Devel::Cover::Condition_or_3" : { "file" : "lib/Devel/Cover/Condition_or_3.pm", "version" : "1.44" }, "Devel::Cover::Condition_xor_4" : { "file" : "lib/Devel/Cover/Condition_xor_4.pm", "version" : "1.44" }, "Devel::Cover::Criterion" : { "file" : "lib/Devel/Cover/Criterion.pm", "version" : "1.44" }, "Devel::Cover::DB" : { "file" : "lib/Devel/Cover/DB.pm", "version" : "1.44" }, "Devel::Cover::DB::Criterion" : { "file" : "lib/Devel/Cover/Truth_Table.pm", "version" : "1.44" }, "Devel::Cover::DB::Digests" : { "file" : "lib/Devel/Cover/DB/Digests.pm", "version" : "1.44" }, "Devel::Cover::DB::File" : { "file" : "lib/Devel/Cover/DB/File.pm", "version" : "1.44" }, "Devel::Cover::DB::IO" : { "file" : "lib/Devel/Cover/DB/IO.pm", "version" : "1.44" }, "Devel::Cover::DB::IO::Base" : { "file" : "lib/Devel/Cover/DB/IO/Base.pm", "version" : "1.44" }, "Devel::Cover::DB::IO::JSON" : { "file" : "lib/Devel/Cover/DB/IO/JSON.pm", "version" : "1.44" }, "Devel::Cover::DB::IO::Sereal" : { "file" : "lib/Devel/Cover/DB/IO/Sereal.pm", "version" : "1.44" }, "Devel::Cover::DB::IO::Storable" : { "file" : "lib/Devel/Cover/DB/IO/Storable.pm", "version" : "1.44" }, "Devel::Cover::DB::Run" : { "file" : "lib/Devel/Cover/DB.pm", "version" : "1.44" }, "Devel::Cover::DB::Structure" : { "file" : "lib/Devel/Cover/DB/Structure.pm", "version" : "1.44" }, "Devel::Cover::Html_Common" : { "file" : "lib/Devel/Cover/Html_Common.pm", "version" : "1.44" }, "Devel::Cover::Op" : { "file" : "lib/Devel/Cover/Op.pm", "version" : "1.44" }, "Devel::Cover::Pod" : { "file" : "lib/Devel/Cover/Pod.pm", "version" : "1.44" }, "Devel::Cover::Report::Compilation" : { "file" : "lib/Devel/Cover/Report/Compilation.pm", "version" : "1.44" }, "Devel::Cover::Report::Html" : { "file" : "lib/Devel/Cover/Report/Html.pm", "version" : "1.44" }, "Devel::Cover::Report::Html_basic" : { "file" : "lib/Devel/Cover/Report/Html_basic.pm", "version" : "1.44" }, "Devel::Cover::Report::Html_basic::Template::Provider" : { "file" : "lib/Devel/Cover/Report/Html_basic.pm", "version" : "1.44" }, "Devel::Cover::Report::Html_minimal" : { "file" : "lib/Devel/Cover/Report/Html_minimal.pm", "version" : "1.44" }, "Devel::Cover::Report::Html_subtle" : { "file" : "lib/Devel/Cover/Report/Html_subtle.pm", "version" : "1.44" }, "Devel::Cover::Report::Html_subtle::Template::Provider" : { "file" : "lib/Devel/Cover/Report/Html_subtle.pm", "version" : "1.44" }, "Devel::Cover::Report::Json" : { "file" : "lib/Devel/Cover/Report/Json.pm", "version" : "1.44" }, "Devel::Cover::Report::Sort" : { "file" : "lib/Devel/Cover/Report/Sort.pm", "version" : "1.44" }, "Devel::Cover::Report::Text" : { "file" : "lib/Devel/Cover/Report/Text.pm", "version" : "1.44" }, "Devel::Cover::Report::Text2" : { "file" : "lib/Devel/Cover/Report/Text2.pm", "version" : "1.44" }, "Devel::Cover::Report::Vim" : { "file" : "lib/Devel/Cover/Report/Vim.pm", "version" : "1.44" }, "Devel::Cover::Report::Vim::Template::Provider" : { "file" : "lib/Devel/Cover/Report/Vim.pm", "version" : "1.44" }, "Devel::Cover::Statement" : { "file" : "lib/Devel/Cover/Statement.pm", "version" : "1.44" }, "Devel::Cover::Subroutine" : { "file" : "lib/Devel/Cover/Subroutine.pm", "version" : "1.44" }, "Devel::Cover::Test" : { "file" : "lib/Devel/Cover/Test.pm", "version" : "1.44" }, "Devel::Cover::Time" : { "file" : "lib/Devel/Cover/Time.pm", "version" : "1.44" }, "Devel::Cover::Truth_Table" : { "file" : "lib/Devel/Cover/Truth_Table.pm", "version" : "1.44" }, "Devel::Cover::Truth_Table::Row" : { "file" : "lib/Devel/Cover/Truth_Table.pm", "version" : "1.44" }, "Devel::Cover::Util" : { "file" : "lib/Devel/Cover/Util.pm", "version" : "1.44" }, "Devel::Cover::Web" : { "file" : "lib/Devel/Cover/Web.pm", "version" : "1.44" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/pjcj/Devel--Cover/issues" }, "homepage" : "http://www.pjcj.net/perl.html", "license" : [ "http://dev.perl.org/licenses" ], "repository" : { "type" : "git", "url" : "http://github.com/pjcj/Devel--Cover", "web" : "http://github.com/pjcj/Devel--Cover" }, "x_IRC" : "irc://irc.perl.org/#perl-qa", "x_mailing_list" : "http://lists.perl.org/list/perl-qa.html" }, "version" : "1.44", "x_Dist_Zilla" : { "perl" : { "version" : "5.040000" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::VersionFromScript", "name" : "VersionFromScript", "version" : "0.017" }, { "class" : "Dist::Zilla::Plugin::Run::BeforeBuild", "config" : { "Dist::Zilla::Plugin::Run::Role::Runner" : { "fatal_errors" : 1, "quiet" : 0, "run" : [ "perl Makefile.PL" ], "version" : "0.050" } }, "name" : "Run::BeforeBuild", "version" : "0.050" }, { "class" : "Dist::Zilla::Plugin::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [], "exclude_match" : [], "follow_symlinks" : 0, "include_dotfiles" : 1, "prefix" : "", "prune_directory" : [ "^\\.build$" ], "root" : "." } }, "name" : "GatherDir", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "ManifestSkip", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::ExecDir", "name" : "ExecDir", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::OurPkgVersion", "name" : "OurPkgVersion", "version" : "0.21" }, { "class" : "Dist::Zilla::Plugin::PodVersion", "name" : "PodVersion", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "MetaYAML", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "MetaJSON", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "MetaConfig", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaResources", "name" : "MetaResources", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaNoIndex", "name" : "MetaNoIndex", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::MetaProvides::Package", "config" : { "Dist::Zilla::Plugin::MetaProvides::Package" : { "finder_objects" : [ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.032" } ], "include_underscores" : 0 }, "Dist::Zilla::Role::MetaProvider::Provider" : { "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", "inherit_missing" : 1, "inherit_version" : 1, "meta_noindex" : 1 }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000038", "version" : "0.006" } }, "name" : "MetaProvides::Package", "version" : "2.004003" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "License", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "Manifest", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "runtime", "type" : "requires" } }, "name" : "Prereqs", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "runtime", "type" : "recommends" } }, "name" : "Recommends", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "configure", "type" : "requires" } }, "name" : "ConfigureRequires", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "TestRequires", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "recommends" } }, "name" : "TestRecommends", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Run::Test", "config" : { "Dist::Zilla::Plugin::Run::Role::Runner" : { "fatal_errors" : 1, "quiet" : 0, "run" : [ "perl Makefile.PL && make t" ], "version" : "0.050" }, "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "Run::Test", "version" : "0.050" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.45.2", "repo_root" : "." } }, "name" : "Git::Check", "version" : "2.049" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "NextRelease", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [], "commit_msg" : "v%V%n%n%c", "signoff" : 0 }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.45.2", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "Git::Commit", "version" : "2.049" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "changelog" : "Changes", "signed" : 0, "tag" : "v1.44", "tag_format" : "v%V", "tag_message" : "v%V" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.45.2", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "Git::Tag", "version" : "2.049" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "TestRelease", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "ConfirmRelease", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "UploadToCPAN", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.45.2", "repo_root" : "." } }, "name" : "Git::Push", "version" : "2.049" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "6.032" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.032" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : 0 }, "version" : "6.032" } }, "x_generated_by_perl" : "v5.40.0", "x_serialization_backend" : "Cpanel::JSON::XS version 4.38", "x_spdx_expression" : "Artistic-1.0-Perl OR GPL-1.0-or-later" } .gitignore100644000765000024 50714631552031 15022 0ustar00pjcjstaff000000000000Devel-Cover-1.44*.org *.bak *~ # for Mac OSX ._* .DS_Store Cover.bs Cover.c Cover.o Makefile Makefile.old blib/ cover_db*/ t/e2e/ lib/Devel/Cover/Inc.pm pm_to_blib *.out *.tar.bz2 *.tar.gz *.patch *.orig *.rej tmp/ MYMETA.* Cover.def dll.base dll.exp Devel-Cover-* tags* README .build/ callgrind.out.* staging/ *.sw? .perl-version queue.db fork100644000765000024 73514631552031 15063 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net # __COVER__ skip_test $^O eq "MSWin32" || $] == 5.008007 # __COVER__ skip_reason Fork unreliable $x = 1; die unless defined ($pid = fork); if ($pid) { $x = 2; waitpid $pid, 0; } else { $x = 3; } print "$x: $$\n"; sort100644000765000024 124414631552031 15125 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl -w use strict; my %sort = ( B => \&backwards, F => \&forwards ); sub backwards { return $b cmp $a; } sub forwards { return $a cmp $b; } sub GetAlgorithm { my ($alg) = @_; return $sort{$alg}; } my @list = qw( a d e c g ); # my $alg = GetAlgorithm(('B', 'F')[int(rand(2))]); my $alg = GetAlgorithm(('B', 'F')[0]); @list = sort {&{$alg}} @list; use Data::Dumper; print STDERR Dumper(\@list); package Failure; sub fail { my @x = 1 .. 5; my @y = sort { Failure->xyz( $a, $b ) } @x; } sub xyz { my $self = shift; my ($a, $b) = @_; $a <=> $b; } package main; my @l = Failure->fail; print STDERR Dumper(\@l); skip100644000765000024 61214631552031 15062 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net sub main { my ($debug) = @_; print "main\n"; print "debug1\n" if $debug; if ($debug) { print "debug2\n"; } } main 0; exec100644000765000024 44614631552031 15045 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2007-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net $x = 1; exec "echo foo"; die "Unreachable"; Makefile.PL100644000765000024 3110314631552031 15040 0ustar00pjcjstaff000000000000Devel-Cover-1.44#!/usr/bin/perl ## no critic (ProhibitExcessMainComplexity) # Copyright 2001-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net require 5.012000; use strict; use warnings; use Cwd; use ExtUtils::MakeMaker; use File::Copy; require Data::Dumper; local $| = 1; my $Version = "1.44"; my $Latest_t = "5.040000"; my $Author = 'paul@pjcj.net'; my $Inc_str = do { my %inc = map { -d () ? (($_ eq "." ? $_ : Cwd::abs_path($_)) => 1) : () } @INC; my $dumper = Data::Dumper->new([ [ sort keys %inc ] ]); $dumper->Indent(1)->Terse(1); $dumper->Sortkeys(1) if $dumper->can("Sortkeys"); chomp(my $str = $dumper->Dump); $str }; open my $i, ">", "lib/Devel/Cover/Inc.pm" or die "Cannot open lib/Devel/Cover/Inc.pm: $!"; print $i <<"EOI"; # Copyright 2001-2024, Paul Johnson (paul\@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net # This file was automatically generated by Makefile.PL. package Devel::Cover::Inc; use strict; use warnings; our \$VERSION = "$Version"; our \$Perl_version = '$]'; our \@Inc = \@{ $Inc_str }; chomp (our \$Perl = <<'EOV'); # Careful with \\\\ in the path $^X EOV if (\$Perl_version ne \$]) { print STDERR <<"EOM"; This version of Devel::Cover was built with Perl version \$Perl_version. It is now being run with Perl version \$]. Attempting to make adjustments, but you may find that some of your modules do not have coverage data collected. You may need to alter the +-inc, +-ignore and +-select options. EOM eval "use Cwd"; my \%inc = map { -d \$_ ? ((\$_ eq "." ? \$_ : Cwd::abs_path(\$_)) => 1) : () } \@INC; \@Inc = sort keys \%inc; } # TODO - check for threadedness, 64bits etc. ? 1 EOI close $i or die "Cannot close lib/Devel/Cover/Inc.pm: $!"; print "Writing tests ........ "; for my $d (qw( t t/e2e )) { unless (mkdir $d) { die "Cannot mkdir $d: $!" unless -d $d; } } my @Tests; opendir my $dir, "tests" or die "Cannot opendir tests: $!"; for my $t (readdir $dir) { next unless -f "tests/$t"; next if $t =~ /\.(pm|pl|org|bak|uncoverable|swp)$/; next if $t =~ /~$/; push @Tests, $t; if ($t =~ /\.t/) { copy("tests/$t", "t/e2e/$t") or die "Cannot copy tests/$t to t/e2e/$t: $!"; next } open my $test, ">", "t/e2e/a$t.t" or die "Cannot open t/e2e/a$t.t: $!"; print $test <new("$t"); \$test->run_test; no warnings; \$test # for create_gold EOT close $test or die "Cannot close t/e2e/a$t.t: $!"; } closedir $dir or die "Cannot closedir tests: $!"; s/^/tests\// for @Tests; push @Tests, grep !/e2e/, glob "t/*/*.t"; if ($ENV{DEVEL_COVER_NO_TESTS}) { # don't run tests under p5cover print "removing all tests with DEVEL_COVER_NO_TESTS\n"; system "rm -rf t/*"; # TODO portability @Tests = (); } print "done\n\n"; my %Checked; sub check { my ($module, $text, $version) = @_; printf "checking for %-18s %-16s .... ", $module, $version ? "version $version" : ""; { local $SIG{__WARN__} = sub { }; eval "use $module"; } (my $mod = $module) =~ s/::/\//g; if (my $m = $INC{"$mod.pm"}) { ## no critic (ProhibitNoWarnings, ProhibitStringyEval) my $v = eval { no warnings; eval "\$${module}::VERSION" }; printf "%-8s $m\n", $v; if ($version && $v < $version) { print "\n\n\n$text\n" unless $Checked{$text}++; print "\n"; } } else { print "not found"; print "\n\n\n$text\n" unless $Checked{$text}++; print "\n"; } } my $D = < $Latest_t; Devel::Cover $Version has not been tested with perl $]. Testing will take place against expected output from perl $Latest_t. You may well find failing tests. EOM print "\n" x 3; ## no critic (ProhibitPackageVars) $ExtUtils::MakeMaker::Verbose = 0; my $Opts = { NAME => "Devel::Cover", VERSION => $Version, AUTHOR => 'Paul Johnson ', ABSTRACT_FROM => "lib/Devel/Cover.pm", DIR => [], EXE_FILES => [ map "bin/$_", qw( cover gcov2perl cpancover ) ], PERL_MALLOC_OK => 1, PREREQ_PM => { "Storable" => 0, "Digest::MD5" => 0, "HTML::Entities" => 3.69, $ENV{DEVEL_COVER_NO_TESTS} ? () : ("Test::More" => 0), }, TYPEMAPS => ["utils/typemap"], clean => { FILES => "t/e2e/* cover_db* t/e2e/*cover_db " . "README *.gcov *.out" }, dist => { COMPRESS => "gzip --best --force" }, test => { TESTS => $ENV{DEVEL_COVER_NO_TESTS} ? "" : "t/*.t t/*/*.t" }, realclean => { FILES => "lib/Devel/Cover/Inc.pm cover_db t/e2e" }, }; # use Data::Dumper; print Dumper $Opts; WriteMakefile(%$Opts); print "\n"; sub MY::postamble { my %tests; @tests{@Tests} = map { (my $t = $_) =~ s/\W/_/g; "cover_db_$t" } @Tests; my @reports = qw( compilation html_basic html_minimal html html_subtle sort text2 text vim ); qq[ tags : pure_all \t ctags --recurse --exclude=blib --exclude=Devel-Cover-* . show_version : \t \@echo \$(VERSION) ppm : ppd pure_all \t tar cf Devel-Cover.tar blib \t gzip --best --force Devel-Cover.tar \t \$(PERL) -pi.bak \\ -e 's/(OS NAME=")[^"]*/\$\$1MSWin32/;' \\ -e 's/(ARCHITECTURE NAME=")[^"]*/\$\$1MSWin32-x86-multi-thread/;' \\ -e 's/(CODEBASE HREF=")[^"]*/\$\$1Devel-Cover.tar.gz/;' \\ Devel-Cover.ppd TAINT = -T TAINT = COVER_OPTIONS = PERL5OPT = _run : pure_all \t \$(PERL) \$(TAINT) -Iblib/lib -Iblib/arch -MDevel::Cover=-merge,0,`\$(PERL) -e '\$\$l = qx|grep __COVER__ \$\$ARGV[0]|; \$\$l =~ /__COVER__\\s+criteria\\s+(.*)/; (\$\$c = \$\$1 || "all") =~ s/\\s+/,/g; \$\$p = "\$\$1," if \$\$l =~ /__COVER__\\s+test_parameters\\s+(.*)/; print "\$\$p-coverage,\$\$c"' tests/\$(TEST)`,\$(COVER_OPTIONS) tests/\$(TEST) COVER_PARAMETERS = \$(PERL) -e '\$\$l = qx|grep __COVER__ \$\$ARGV[0]|; \$\$u = "-uncoverable_file \$\$1" if \$\$l =~ /__COVER__\\s+uncoverable_file\\s+(.*)/; (\$\$p) = \$\$l =~ /__COVER__\\s+cover_parameters\\s+(.*)/; print "\$\$u \$\$p"' tests/\$(TEST) html : _run \t \$(PERL) -Mblib bin/cover `\$(COVER_PARAMETERS)` -report html basic : _run \t \$(PERL) -Mblib bin/cover `\$(COVER_PARAMETERS)` -report html_basic subtle : _run \t \$(PERL) -Mblib bin/cover `\$(COVER_PARAMETERS)` -report html_subtle out : _run \t \$(PERL) -Mblib bin/cover `\$(COVER_PARAMETERS)` -report text > \$(TEST).out text : out \t \$(PAGER) \$(TEST).out wrun : pure_all \t \$(PERL) \$(TAINT) -Iblib/lib -Iblib/arch -MDevel::Cover=-ignore,blib,-merge,0 tests/\$(TEST) prove : pure_all \t \$(PERL) -Iutils -MDevel::Cover::BuildUtils=prove_command -le '\$\$c = prove_command and print \$\$c and system \$\$c' t : pure_all \t \$(PERL) -Mblib bin/cover -delete \t exec make test HARNESS_OPTIONS=j`\$(PERL) -Iutils -MDevel::Cover::BuildUtils=nice_cpus -e 'print nice_cpus'`:c HARNESS_TIMER=1 no_replace_ops_t : pure_all \t DEVEL_COVER_OPTIONS=-replace_ops,0 exec make t DB = cover_db dump : \t \$(PERL) -Mblib bin/cover -dump_db \$(DB) diff : out \t \$(PERL) utils/makeh strip_criterion 'time' \$(TEST).out \t \$(PERL) utils/makeh strip_criterion ' pod' \$(TEST).out \t gold="`\$(PERL) -Mblib -MDevel::Cover::Test -e '\$\$t = Devel::Cover::Test->new(qq(\$(TEST))); print join qq(.), \$\$t->cover_gold'`" && \$(EDITOR) -d "\$\$gold" \$(TEST).out gold : pure_all \t \$(PERL) utils/create_gold \$(TEST) all_test : \t exec \$(PERL) utils/all_versions make t all_gold : \t \$(PERL) utils/create_all_gold \$(TEST) _delete_db : pure_all \t rm -rf cover_db _self_cover_tests : @{[sort values %tests]} \t DEVEL_COVER_SELF=1 \$(PERL) -Mblib -MDevel::Cover bin/cover -silent -write cover_db @{[sort values %tests]} self_cover : _self_cover_reports \t \$(PERL) -Mblib bin/cover -report html_basic -launch \t \$(PERL) -Mblib bin/cover -report vim ] . "\n" . join "\n", map("$tests{$_} : _delete_db\n" . "\t \@echo Running $tests{$_}\n" . "\t \@rm -rf $tests{$_}\n" . "\t \@DEVEL_COVER_SELF=1 \$(PERL) -Mblib -MDevel::Cover=-db,$tests{$_},-silent,1,-coverage,all,-ignore,tests/,-coverage,pod-also_private-xx $_\n", sort keys %tests), "_self_cover_reports : @{[map qq(report_$_), @reports]}\n", ( map "report_$_ : _self_cover_tests\n" . "\t \@echo Generating $_ report\n" . "\t \@DEVEL_COVER_SELF=1 \$(PERL) -Mblib -MDevel::Cover bin/cover -silent -report $_ > /dev/null\n", @reports, ) } .typos.toml100644000765000024 61014631552031 15156 0ustar00pjcjstaff000000000000Devel-Cover-1.44[files] extend-exclude = [ ".codespell" ] ignore-hidden = false [default.extend-words] thr = "thr" [default.extend-identifiers] [default] extend-ignore-words-re = [ ] extend-ignore-identifiers-re = [ ] extend-ignore-re = [ '"[^"]+"\n\n__END__\n\n', # quotes '::ProhibitMultipleWiths\b', # perl critic 'Gisle Aas', # author ] .perltidyrc100644000765000024 604614631552031 15240 0ustar00pjcjstaff000000000000Devel-Cover-1.44-utf8 # input is UTF-8 --converge # keep running until no changes --output-line-ending=unix # output uses unix line endings --indent-columns=2 # indent level is 2 cols --extended-continuation-indentation # indent extended continuations --no-outdent-long-lines # don't outdent long lines --no-outdent-labels # don't outdent labels --no-outdent-long-comments # don't outdent long comments --paren-tightness=2 # keep parentheses tight --space-prototype-paren=2 # space before prototype parentheses # --space-signature-paren=2 # space before signature parentheses # needs a recent Perl::Tidy --keyword-paren-inner-tightness=2 # keep keyword parentheses tight --space-backslash-quote=0 # no space between backslash and quote --minimum-space-to-comment=2 # spaces before side comments --break-before-all-operators # break before all operators --break-after-all-operators # break after all operators --no-space-for-semicolon # no space before semicolons in for loops --no-add-semicolons # no optional semicolons at end of blocks --one-line-block-semicolons=0 # no semicolons after one-line blocks --one-line-block-nesting=1 # use one line block nesting --delete-closing-side-comments # delete closing side comments --no-blanks-before-comments # no blank lines before comments --cuddled-else # cuddle elses --cuddled-block-list=sort,map,grep # cuddle blocks for sort, map, grep --cuddled-paren-brace # cuddle paren-brace blocks ) { --opening-token-right # no break between comma and bracket , { --vertical-tightness=0 # break after every bracket --brace-follower-vertical-tightness=2 # keep code after brace on same line --weld-nested-containers # allow container delimiters on same line --weld-fat-comma # allow fat comma on same line # --comma-arrow-breakpoints=3 # commas after => aren't special # we only want this sometimes --break-after-labels=2 # never break after labels --valign-if-unless # vertically align if and unless --delete-repeated-commas # delete repeated commas --want-trailing-commas="w(h W(m [m {m" # trailing commas for arrays and hashes --add-trailing-commas # add trailing commas --delete-trailing-commas # delete trailing commas --delete-weld-interfering-commas # delete commas that interfere with welds --ignore-old-breakpoints # ignore all old breakpoints --keep-old-blank-lines=1 # keep existing blank lines --keyword-group-blanks # add blank lines between keyword groups --keyword-group-blanks-size=5 # size of keyword groups alias100644000765000024 76514631552031 15216 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net package Foo; sub is_3digits { my $val = shift; my $retval = undef; $retval=1 if $val =~ /^\d{3}$/; return $retval; } package main; *main::is_3digits = *Foo::is_3digits; # delete $Foo::{is_3digits}; is_3digits(1234); is_3digits(123); eval1100644000765000024 74714631552031 15135 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; use lib -d "t" ? "t" : ".."; my $x; eval <<'EOS'; sub e { $x++; $x } EOS eval <<'EOS'; sub f { $x++; $x } sub g { $x++; } sub h { $x++; } EOS e(); e(); e(); f(); f(); h(); h(); h(); empty100644000765000024 36714631552031 15261 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2015-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net taint100644000765000024 50114631552031 15230 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2013-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; use lib "tests"; use Taint; print "taint\n"; E4.pm100644000765000024 44214631552031 15000 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests# Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net package E4; print "E4\n"; sub E4 { print "E4::E4\n" } 1 md5.t100644000765000024 203114631552031 15060 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; use File::Copy; use Devel::Cover::Test; my $t = "md5"; my $ft = "./tests/$t"; my $fg = "./tests/trivial"; my $run_test = sub { my $test = shift; copy($fg, $ft) or die "Cannot copy $fg to $ft: $!"; open T, ">>$ft" or die "Cannot open $ft: $!"; print T "# blah blah\n"; close T or die "Cannot close $ft: $!"; $test->run_command($test->test_command); copy($fg, $ft) or die "Cannot copy $fg to $ft: $!"; $test->{test_parameters} .= " -merge 1"; $test->run_command($test->test_command); }; my $test = Devel::Cover::Test->new( $t, db_name => "complex_$t", run_test => $run_test, end => sub { unlink $ft }, delay_after_run => 0.50, ); $test->run_test; no warnings; $test # for create_gold eval3100644000765000024 77614631552031 15141 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use lib "tests"; $x = shift || 0; print "1 - $x\n"; if ($x) { eval 'sub s1 { print "s1\n" }'; s1() } print "3 - $x\n"; if ($x < 4) { eval 'sub s2 { print "s2\n" }'; s2() } print "4 - $x\n"; if ($x < 6) { eval 'sub s3 { print "s3\n" }'; s3() } print "5 - $x\n"; eval2100644000765000024 67114631552031 15132 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use lib "tests"; $x = shift || 0; print "1 - $x\n"; if ($x) { eval 'use E2' } print "3 - $x\n"; if ($x < 4) { eval 'use E3' } print "4 - $x\n"; if ($x < 6) { eval 'use E4' } print "5 - $x\n"; v-58x100644000765000024 41714631552031 15006 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use 5.006; my $x = 1; E3.pm100644000765000024 44214631552031 14777 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests# Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net package E3; print "E3\n"; sub E3 { print "E3::E3\n" } 1 E2.pm100644000765000024 44214631552031 14776 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests# Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net package E2; print "E2\n"; sub E2 { print "E2::E2\n" } 1 setup100644000765000024 45714631552031 15261 0ustar00pjcjstaff000000000000Devel-Cover-1.44/utils#!/bin/sh # . ./utils/setup tidy () { echo -n $1 | perl -naF: -e 'print join ":", grep !$s{$_}++ && -e, @F'; } dc_home=$PWD export PATH=$(tidy $dc_home/utils:$PATH) if [ ! -z $ZSH_VERSION ]; then _dc() { reply=(`utils/dc options`) } compctl -K _dc dc fi export CPANCOVER_LOCAL=1 makeh100755000765000024 142314631552031 15223 0ustar00pjcjstaff000000000000Devel-Cover-1.44/utils#!/usr/bin/perl # Copyright 2001-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; my $Command = { strip_criterion => sub { my ($command, $criterion, $file) = @_; my $t; local ($^I, @ARGV) = (".bak", $file); while (<>) { $t = index($_, "$criterion code") - 3 if !defined $t || $t < 0; substr $_, $t, 7, "" if /^line err stmt/ .. /^--------/ and $t > -1 and length > $t; print; } } }; sub main { my ($command) = @ARGV; die "No such command: $command" unless $Command->{$command}; $Command->{$command}->(@ARGV) } main Contributors100644000765000024 1527414631552031 15521 0ustar00pjcjstaff000000000000Devel-Cover-1.44The following people have helped to make Devel::Cover what it is today, either by sending pull requests, patches or suggestions, or by reporting or working to fix bugs. Thank-you to one and all! Alexandr Evstigneev hurricup@evstigneev.com Alex Balhatchet alex@balhatchet.net Alexey Sokolov Allison Regier penneraa@acm.org Andrew Billeb [private] Andy Lester andy@petdance.com Arthur Axel 'fREW' Schmidt frioux@gmail.com Artur Bergman arthur@contiller.se Audrey Tang (唐鳳) audreyt@audreyt.org Axel Beckert abe@deuxchevaux.org B Fraser fraserbn@gmail.com Brandon Black blblack@gmail.com Brian Cassidy bricas@cpan.org brian d foy brian.d.foy@gmail.com Buddy Burden barefootcoder@gmail.com Celogeek me@celogeek.com Chad Granum exodist7@gmail.com Chia-liang Kao clkao@clkao.org Chisel Wright chisel@chizography.net Christian Walde walde.christian@gmail.com cono q@cono.org.ua Curtis Jewell csjewell@cpan.org Dagfinn Ilmari Mannsåker ilmari@ilmari.org Daisuke Maki dmaki@cpan.org Dan Collins dcollinsn@gmail.com Daniel Coupal dcoupal@cisco.com Daniel Egeberg daniel.egeberg@gmail.com Daniel Perrett perrettdl@googlemail.com Dave Rolsky autarch@urth.org David Cantrell david@cantrell.org.uk David E. Wheeler david@justatheory.com David Steinbrunner dsteinbrunner@pobox.com Denis Howe denis.howe@gmail.com Dick Franks rwfranks@acm.org Dinis Rebolo dinisrebolo@gmail.com Dominic Mitchell dom@happygiraffe.net Eden Hochbaum eden.hochbaum@gmail.com Ed J etj at cpan.org Emiliya Boyadjieva emiliya.boyadjieva@sap.com Erwan Lemonnier erwan@cpan.org Felipe Gasper felipe@felipegasper.com Florian Ragwitz rafl@debian.org Gábor Szabó szabgab@gmail.com Gisle Aas gisle@ActiveState.com Goro Fuji gfuji@cpan.org Graham Knop haarg@haarg.org Gregor Herrmann gregoa@debian.org Guillaume Aubert aubertg@cpan.org Guillermo O. Freschi kedrot@gmail.com Haydn Newport haydn@catalyst.net.nz Heikki J Laaksonen heikki.j.laaksonen@kolumbus.fi Heinz Knutzen heinz.knutzen@gmail.com Helmut Wollmersdorfer helmut@wollmersdorfer.at H.Merijn Brand h.m.brand@xs4all.nl Ivan Wills ivan.wills@gmail.com Jacques Germishuys jacquesg@cpan.org James E Keenan jkeenan@cpan.org James Raspass jraspass@gmail.com Jeff Wren jeffrey.wren@paradigm-works.com Jens Rehsack sno@netbsd.org Jesús Alonso Abad https://github.com/Kencho Jim Cromie jcromie@cpan.org jkahrman Joel Berger joel.a.berger@gmail.com John Lightsey jd@cpanel.net John LoVerso jloverso@mathworks.com Jonathan "Duke" Leto jonathan@leto.net jpsalvesen Kan Fushihara kan.fushihara@gmail.com Karen Etheridge ether@cpan.org Keith Wissing Kent Fredric kentfredric@gmail.com Kevin Brannen kbrannen@pwhome.com Kirk Kimmel kimmel@cpan.org Larry Leszczynski larryl@cpan.org Lasse Makholm lasse@unity3d.com Lee Johnson lee@givengain.ch Léon Brocard acme@astray.com Marcel Grünauer marcel@cpan.org Marc-Philip mpw96@gmx.de Mark Stosberg mark@summersault.com Matthew Horsfall wolfsage@gmail.com mauke Max Maischein corion@cpan.org Michael Carman mjcarman@cpan.org Michael G Schwern schwern@pobox.com Mohammad S Anwar mohammad.anwar@yahoo.com Nathan Haigh n.haigh@sheffield.ac.uk Nicholas Clark nick@ccl4.org ℕicolas ℝ. nicolas@atoomic.org Niko Tyni ntyni@debian.org Norman Nunley nnunley@gmail.com Olaf Alders olaf@wundersolutions.com Olivier Mengué dolmen@cpan.org Oliver Youle youle.oliver@gmail.com Opera Wang Opera.Wang+step@gmail.com Pau Amma pauamma@cpan.org Paul Hirst paulhirst@bearandgiraffe.org Paul Johnson paul@pjcj.net Paul "LeoNerd" Evans leonerd@leonerd.org.uk Philippe M. Chiasson gozer@cpan.org philip r brenan philiprbrenan@gmail.com pjuhasz https://github.com/pjuhasz Reini Urban rurban@cpan.org Robert Freimuth rfreimuth@cpan.org Robin Barker RMBarker@cpan.org Rob Kinyon rob.kinyon@gmail.com Ruslan Zakirov Ruslan.Zakirov@gmail.com Ryan Voots simcop2387@simcop2387.info sago35 sago35@gmail.com Sebastian Paaske Tørholm eckankar@gmail.com Sébastien Aperghis-Tramoni saper@cpan.org Sergiy Borodych Sergiy.Borodych@gmail.com Slaven Rezić slaven@rezic.de Stefan Becker Stefan.Becker@nokia.com Steffen Schwigon ss5@renormalist.net Stephan Loyd stephanloyd9@gmail.com Stephen Thirlwall sdt@dr.com Steve Hay shay@cpan.org Steve Peters smpeters@cpan.org Steve Rogerson Steve Sanbeg sanbeg@cpan.org Sullivan Beck sbeck@cpan.org Tatsuhiko Miyagawa miyagawa@bulknews.net Thomas Dorner dorner (AT) cpan.org Tina Müller tinita at cpan.org Todd Rinaldo toddr@cpan.org Vadim O. Ustiansky ustiansky@cpan.org waterbeetle Xavier Caron xcaron@gmail.com Zakariyya Mughal zmughal@cpan.org Zefram zefram@fysh.org If you should be on this list and I have overlooked your contribution, please accept my apologies and let me know what your entry should look like. Similarly, if you would like your entry changed or deleted, please let me know. .autoenv.zsh100644000765000024 10514631552031 15311 0ustar00pjcjstaff000000000000Devel-Cover-1.44if [[ $autoenv_event == "enter" ]]; then . ./utils/setup else fi bigint100644000765000024 64214631552031 15373 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2012-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net # __COVER__ skip_test $] < 5.032 # __COVER__ skip_reason Too fagile below 5.32 use strict; use warnings; use Math::BigInt ":constant"; my $x = 1; print $x if 1 >= $x; alias1100644000765000024 53314631552031 15270 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#!/usr/bin/perl # Copyright 2004-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use strict; use warnings; use lib "tests"; use Alias1; is_3digits(1234); is_3digits(123); exit; COP.pm100644000765000024 3014631552031 15122 0ustar00pjcjstaff000000000000Devel-Cover-1.44/tests#line 64 "Parser.yp" 1; .shellcheckrc100644000765000024 26114631552031 15462 0ustar00pjcjstaff000000000000Devel-Cover-1.44shell=bash external-sources=true enable=add-default-case enable=avoid-nullary-conditions enable=check-unassigned-uppercase enable=deprecate-which enable=require-double-brackets .editorconfig100644000765000024 32514631552031 15505 0ustar00pjcjstaff000000000000Devel-Cover-1.44root = true [*] charset = utf-8 end_of_line = lf indent_style = space indent_size = 2 tab_width = 2 insert_final_newline = true max_line_length = 80 trim_trailing_whitespace = true [Makefile] indent_style = tab MANIFEST.SKIP100644000765000024 41614631552031 14727 0ustar00pjcjstaff000000000000Devel-Cover-1.44\.org$ \.bak$ ~$ \.orig$ Makefile$ Makefile\.old$ blib/ pm_to_blib$ \.version$ ^t/e2e/ \.gz$ \.c$ \.o$ \.bs$ cover_db/ core$ \.out$ lib/Devel/Cover/Inc.pm$ ^Devel-Cover- \.patch$ \.rej$ \.debug$ ^tmp/ ^bugs/ \.git/ \.tar.bz2$ MYMETA\. tags .perl-version \.db ^\.build\b .perlcriticrc100644000765000024 16700014631552031 15602 0ustar00pjcjstaff000000000000Devel-Cover-1.44# Globals severity = 2 # force = 0 # only = 0 allow-unsafe = 1 # profile-strictness = warn # color = 0 # pager = # top = 0 verbose = 8 # include = # exclude = # single-policy = # theme = color-severity-highest = red color-severity-high = magenta color-severity-medium = bold magenta color-severity-low = blue color-severity-lowest = cyan # program-extensions = # Use `any' from `List::Util', `List::SomeUtils', or `List::MoreUtils' instead of `grep' in boolean context. [BuiltinFunctions::ProhibitBooleanGrep] # set_themes = certrec core pbp performance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Map blocks should have a single statement. [BuiltinFunctions::ProhibitComplexMappings] # set_themes = complexity core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum number of statements to allow within a map block. # Minimum value 1. No maximum. max_statements = 5 # Use 4-argument `substr' instead of writing `substr($foo, 2, 6) = $bar'. [BuiltinFunctions::ProhibitLvalueSubstr] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Forbid $b before $a in sort blocks. [BuiltinFunctions::ProhibitReverseSortBlock] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # Prohibit `\shift' in code [BuiltinFunctions::ProhibitShiftRef] # set_themes = bugs core tests # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Use Time::HiRes instead of something like `select(undef, undef, undef, .05)'. [-BuiltinFunctions::ProhibitSleepViaSelect] # set_themes = bugs core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Write `eval { my $foo; bar($foo) }' instead of `eval "my $foo; bar($foo);"'. [BuiltinFunctions::ProhibitStringyEval] # set_themes = bugs certrule core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Allow eval of "use" and "require" strings. allow_includes = 1 # Write `split /-/, $string' instead of `split '-', $string'. [BuiltinFunctions::ProhibitStringySplit] # set_themes = certrule core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Write `eval { $foo->can($name) }' instead of `UNIVERSAL::can($foo, $name)'. [BuiltinFunctions::ProhibitUniversalCan] # set_themes = certrule core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `eval { $foo->isa($pkg) }' instead of `UNIVERSAL::isa($foo, $pkg)'. [BuiltinFunctions::ProhibitUniversalIsa] # set_themes = certrule core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Don't pass $_ to built-in functions that assume it, or to most filetest operators. [BuiltinFunctions::ProhibitUselessTopic] # set_themes = core # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't use `grep' in void contexts. [BuiltinFunctions::ProhibitVoidGrep] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Don't use `map' in void contexts. [BuiltinFunctions::ProhibitVoidMap] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `grep { /$pattern/ } @list' instead of `grep /$pattern/, @list'. [-BuiltinFunctions::RequireBlockGrep] # set_themes = bugs core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `map { /$pattern/ } @list' instead of `map /$pattern/, @list'. [-BuiltinFunctions::RequireBlockMap] # set_themes = bugs core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Use `glob q{*}' instead of <*>. [-BuiltinFunctions::RequireGlobFunction] # set_themes = bugs core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Sort blocks should have a single statement. [-BuiltinFunctions::RequireSimpleSortBlock] # set_themes = complexity core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # AUTOLOAD methods should be avoided. [-ClassHierarchies::ProhibitAutoloading] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Employ `use parent' instead of `@ISA'. [ClassHierarchies::ProhibitExplicitISA] # set_themes = certrec core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `bless {}, $class;' instead of just `bless {};'. [ClassHierarchies::ProhibitOneArgBless] # set_themes = bugs core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Use spaces instead of tabs. [CodeLayout::ProhibitHardTabs] # set_themes = core cosmetic pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Allow hard tabs before first non-whitespace character. # allow_leading_tabs = 1 # Write `open $handle, $path' instead of `open($handle, $path)'. [CodeLayout::ProhibitParensWithBuiltins] # set_themes = core cosmetic pbp # add_themes = severity = 2 # maximum_violations_per_document = no_limit # Write `qw(foo bar baz)' instead of `('foo', 'bar', 'baz')'. [CodeLayout::ProhibitQuotedWordLists] # set_themes = core cosmetic # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The minimum number of words in a list that will be complained about. # Minimum value 1. No maximum. # min_elements = 2 # Complain even if there are non-word characters in the values. # strict = 0 # Don't use whitespace at the end of lines. [CodeLayout::ProhibitTrailingWhitespace] # set_themes = core maintenance # add_themes = severity = 2 # maximum_violations_per_document = no_limit # Use the same newline through the source. [CodeLayout::RequireConsistentNewlines] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Must run code through perltidy. [CodeLayout::RequireTidyCode] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # The Perl::Tidy configuration file to use, if any. # perltidyrc = # Put a comma at the end of every multi-line list declaration, including the last one. [CodeLayout::RequireTrailingCommas] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # We would like to use this policy for simple loops but for loops have their # place in more complicated cases so we'll turn this off. # Write `for(0..20)' instead of `for($i=0; $i<=20; $i++)'. [-ControlStructures::ProhibitCStyleForLoops] # set_themes = core maintenance pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't write long "if-elsif-elsif-elsif-elsif...else" chains. [ControlStructures::ProhibitCascadingIfElse] # set_themes = complexity core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum number of alternatives that will be allowed. # Minimum value 1. No maximum. max_elsif = 10 # Don't write deeply nested loops and conditionals. [ControlStructures::ProhibitDeepNests] # set_themes = complexity core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum number of nested constructs to allow. # Minimum value 1. No maximum. # max_nests = 5 # Don't use labels that are the same as the special block names. [ControlStructures::ProhibitLabelsWithSpecialBlockNames] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Don't modify `$_' in list functions. [ControlStructures::ProhibitMutatingListFunctions] # set_themes = bugs certrule core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # The base set of functions to check. # list_funcs = map grep List::Util::first List::MoreUtils::any List::SomeUtils::any List::MoreUtils::all List::SomeUtils::all List::MoreUtils::none List::SomeUtils::none List::MoreUtils::notall List::SomeUtils::notall List::MoreUtils::true List::SomeUtils::true List::MoreUtils::false List::SomeUtils::false List::MoreUtils::firstidx List::SomeUtils::firstidx List::MoreUtils::first_index List::SomeUtils::first_index List::MoreUtils::lastidx List::SomeUtils::lastidx List::MoreUtils::last_index List::SomeUtils::last_index List::MoreUtils::insert_after List::SomeUtils::insert_after List::MoreUtils::insert_after_string List::SomeUtils::insert_after_string # The set of functions to check, in addition to those given in list_funcs. # add_list_funcs = # Don't use operators like `not', `!~', and `le' within `until' and `unless'. [-ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `if($condition){ do_something() }' instead of `do_something() if $condition'. [-ControlStructures::ProhibitPostfixControls] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The permitted postfix controls. # Valid values: for, foreach, if, unless, until, when, while. # allow = # The exempt flow control functions. # flowcontrol = carp cluck confess croak die exit goto warn # Write `if(! $condition)' instead of `unless($condition)'. [-ControlStructures::ProhibitUnlessBlocks] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't write code after an unconditional `die, exit, or next'. [ControlStructures::ProhibitUnreachableCode] # set_themes = bugs certrec core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `while(! $condition)' instead of `until($condition)'. [-ControlStructures::ProhibitUntilBlocks] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Never use `...' in production code. [ControlStructures::ProhibitYadaOperator] # set_themes = core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Check your spelling. [Documentation::PodSpelling] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # The command to invoke to check spelling. # spell_command = aspell list # The words to not consider as misspelled. # stop_words = # A file containing words to not consider as misspelled. # stop_words_file = # The `=head1 NAME' section should match the package. [Documentation::RequirePackageMatchesPodName] # set_themes = core cosmetic # add_themes = severity = 3 # maximum_violations_per_document = no_limit # All POD should be after `__END__'. [Documentation::RequirePodAtEnd] # set_themes = core cosmetic pbp # add_themes = severity = 3 # maximum_violations_per_document = no_limit # Organize your POD into the customary sections. [Documentation::RequirePodSections] # set_themes = core maintenance pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The sections to require for modules (separated by qr/\s* [|] \s*/xms). # We'd like at least one of ATTRIBUTES | LAZY-ATTRIBUTES | METHODS | SUBROUTINES # but can't specify that. lib_sections = NAME | SYNOPSIS | DESCRIPTION # The sections to require for programs (separated by qr/\s* [|] \s*/xms). script_sections = NAME | SYNOPSIS | DESCRIPTION # The origin of sections to use. # Valid values: book, book_first_edition, module_starter_pbp, module_starter_pbp_0_0_3. # source = book_first_edition # The spelling of sections to use. # Valid values: en_AU, en_US. # language = # Use functions from Carp instead of `warn' or `die'. [-ErrorHandling::RequireCarping] # set_themes = certrule core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Don't complain about die or warn if the message ends in a newline. # allow_messages_ending_with_newlines = 1 # Don't complain about die or warn in main::, unless in a subroutine. # allow_in_main_unless_in_subroutine = 0 # You can't depend upon the value of `$@'/`$EVAL_ERROR' to tell whether an `eval' failed. [ErrorHandling::RequireCheckingReturnValueOfEval] # set_themes = bugs core # add_themes = severity = 1 # maximum_violations_per_document = no_limit # Discourage stuff like `@files = `ls $directory`'. [InputOutput::ProhibitBacktickOperators] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Allow backticks everywhere except in void contexts. only_in_void_context = 1 # Write `opendir my $dh, $dirname;' instead of `opendir DH, $dirname;'. [InputOutput::ProhibitBarewordDirHandles] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Write `open my $fh, q{<}, $filename;' instead of `open FH, q{<}, $filename;'. [InputOutput::ProhibitBarewordFileHandles] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Use "<>" or "" or a prompting module instead of "". [InputOutput::ProhibitExplicitStdin] # set_themes = core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Use prompt() instead of -t. [-InputOutput::ProhibitInteractiveTest] # set_themes = bugs certrule core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Use `local $/ = undef' or Path::Tiny instead of joined readline. [InputOutput::ProhibitJoinedReadline] # set_themes = core pbp performance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Never write `select($fh)'. [InputOutput::ProhibitOneArgSelect] # set_themes = bugs certrule core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `while( $line = <> ){...}' instead of `for(<>){...}'. [InputOutput::ProhibitReadlineInForLoop] # set_themes = bugs core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `open $fh, q{<}, $filename;' instead of `open $fh, "<$filename";'. [InputOutput::ProhibitTwoArgOpen] # set_themes = bugs certrule core pbp security # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Write `print {$FH} $foo, $bar;' instead of `print $FH $foo, $bar;'. [-InputOutput::RequireBracedFileHandleWithPrint] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # Close filehandles as soon as possible after opening them. [-InputOutput::RequireBriefOpen] # set_themes = core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The maximum number of lines between an open() and a close(). # Minimum value 1. No maximum. # Write `my $error = close $fh;' instead of `close $fh;'. [InputOutput::RequireCheckedClose] # set_themes = certrule core maintenance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Modules which export autodie. # autodie_modules = autodie # Write `my $error = open $fh, $mode, $filename;' instead of `open $fh, $mode, $filename;'. [InputOutput::RequireCheckedOpen] # set_themes = certrule core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Modules which export autodie. # autodie_modules = autodie # Return value of flagged function ignored. [InputOutput::RequireCheckedSyscalls] # set_themes = certrule core maintenance # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # The set of functions to require checking the return value of. # functions = open close print say # The set of functions to not require checking the return value of. # exclude_functions = # Modules which export autodie. # autodie_modules = autodie # Write `open $fh, q{<:encoding(UTF-8)}, $filename;' instead of `open $fh, q{<:utf8}, $filename;'. [InputOutput::RequireEncodingWithUTF8Layer] # set_themes = bugs core security # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Do not use `format'. [Miscellanea::ProhibitFormats] # set_themes = certrule core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Do not use `tie'. [Miscellanea::ProhibitTies] # set_themes = core maintenance pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Forbid a bare `## no critic' [Miscellanea::ProhibitUnrestrictedNoCritic] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Remove ineffective "## no critic" annotations. [Miscellanea::ProhibitUselessNoCritic] # set_themes = core maintenance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Export symbols via `@EXPORT_OK' or `%EXPORT_TAGS' instead of `@EXPORT'. [Modules::ProhibitAutomaticExportation] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Avoid putting conditional logic around compile-time includes. [Modules::ProhibitConditionalUseStatements] # set_themes = bugs core # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Ban modules that aren't blessed by your shop. [Modules::ProhibitEvilModules] # set_themes = bugs certrule core # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # The names of or patterns for modules to forbid. # modules = Class::ISA {Found use of Class::ISA. This module is deprecated by the Perl 5 Porters.} Pod::Plainer {Found use of Pod::Plainer. This module is deprecated by the Perl 5 Porters.} Shell {Found use of Shell. This module is deprecated by the Perl 5 Porters.} Switch {Found use of Switch. This module is deprecated by the Perl 5 Porters.} # A file containing names of or patterns for modules to forbid. # modules_file = # Minimize complexity in code that is outside of subroutines. [Modules::ProhibitExcessMainComplexity] # set_themes = complexity core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum complexity score allowed. # Minimum value 1. No maximum. # max_mccabe = 20 # Allow for a little code in "around" subs and similar. max_mccabe = 3 # Put packages (especially subclasses) in separate files. # There can be good reasons to do this but since there is no additional config # we'll turn this off. [-Modules::ProhibitMultiplePackages] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `require Module' instead of `require 'Module.pm''. [Modules::RequireBarewordIncludes] # set_themes = core portability # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # End each module with an explicitly `1;' instead of some funky expression. [-Modules::RequireEndWithOne] # set_themes = bugs certrule core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Always make the `package' explicit. [Modules::RequireExplicitPackage] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = 1 # Don't require programs to contain a package statement. # exempt_scripts = 1 # Allow the specified modules to be imported outside a package. # allow_import_of = # Package declaration must match filename. [Modules::RequireFilenameMatchesPackage] # set_themes = bugs core # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # `use English' must be passed a `-no_match_vars' argument. [Modules::RequireNoMatchVarsWithUseEnglish] # set_themes = core performance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Give every module a `$VERSION' number. [-Modules::RequireVersionVar] # set_themes = core pbp readability # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Use DEMOLISH instead of DESTROY [Moose::ProhibitDESTROYMethod] # set_themes = bugs moose # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The additional modules to treat as equivalent to "Moose", "Moose::Role", or "MooseX::Role::Parameterized". # Values that are always included: Moose, Moose::Role, MooseX::Role::Parameterized. # equivalent_modules = equivalent_modules = Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base::Moose Perceptyx::Base::Moose::Role # Avoid lazy_build [-Moose::ProhibitLazyBuild] # set_themes = bugs moose # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The additional modules to treat as equivalent to "Moose", "Moose::Role", "MooseX::Role::Parameterized", or "MooseX::Singleton". # Values that are always included: Moose, Moose::Role, MooseX::Role::Parameterized, MooseX::Singleton. # equivalent_modules = Moose Moose::Role MooseX::Role::Parameterized MooseX::Singleton equivalent_modules = Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base::Moose Perceptyx::Base::Moose::Role # Require role composition [Moose::ProhibitMultipleWiths] # set_themes = bugs moose roles # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The additional modules to treat as equivalent to "Moose", "Moose::Role", or "MooseX::Role::Parameterized". # Values that are always included: Moose, Moose::Role, MooseX::Role::Parameterized. # equivalent_modules = Moose Moose::Role MooseX::Role::Parameterized equivalent_modules = Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base::Moose Perceptyx::Base::Moose::Role # Don't override Moose's standard constructors. [Moose::ProhibitNewMethod] # set_themes = bugs moose # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The additional modules to treat as equivalent to "Moose", "Moose::Role", or "MooseX::Role::Parameterized". # Values that are always included: Moose, Moose::Role, MooseX::Role::Parameterized. # equivalent_modules = Moose Moose::Role MooseX::Role::Parameterized equivalent_modules = Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base::Moose Perceptyx::Base::Moose::Role # Require removing implementation details from you packages. [Moose::RequireCleanNamespace] # set_themes = maintenance moose # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The modules that need to be unimported. # modules = Moose Moose::Role Moose::Util::TypeConstraints MooseX::Role::Parameterized # Modules that clean imports. # cleaners = namespace::autoclean # Ensure that you've made your Moose code fast [Moose::RequireMakeImmutable] # set_themes = moose performance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The additional modules to treat as equivalent to "Moose". # Values that are always included: Moose. # equivalent_modules = Moose equivalent_modules = Repobase::Base::Moose Perceptyx::Base::Moose # Distinguish different program components by case. [NamingConventions::Capitalization] # set_themes = core cosmetic pbp # add_themes = severity = 2 # maximum_violations_per_document = no_limit # How package name components should be capitalized. Valid values are :single_case, :all_lower, :all_upper:, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. packages = via|[A-Z][a-z0-9_]* # Package names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # package_exemptions = main # How subroutine names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. subroutines = :all_lower # Subroutine names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. subroutine_exemptions = AUTOLOAD BUILD BUILDARGS CLEAR CLOSE DELETE DEMOLISH DESTROY EXISTS EXTEND FETCH FETCHSIZE FIRSTKEY GETC NEXTKEY POP PRINT PRINTF PUSH READ READLINE SCALAR SHIFT SPLICE STORE STORESIZE TIEARRAY TIEHANDLE TIEHASH TIESCALAR UNSHIFT UNTIE PUSHED OPEN WRITE CXT LOG CFG TRC # How local lexical variables names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. local_lexical_variables = :all_lower # Local lexical variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # local_lexical_variable_exemptions = # How lexical variables that are scoped to a subset of subroutines, should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. scoped_lexical_variables = :all_lower # Names for variables in anonymous blocks that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # scoped_lexical_variable_exemptions = # How lexical variables at the file level should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. file_lexical_variables = [A-Z][a-z0-9_]* # File-scope lexical variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # file_lexical_variable_exemptions = # How global (package) variables should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. global_variables = [A-Z][a-z0-9_]* # Global variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. global_variable_exemptions = VERSION ISA EXPORT(?:_OK)? EXPORT_TAGS AUTOLOAD ENV SIG # How constant names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. # constants = :all_upper # Constant names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # constant_exemptions = # How labels should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex. # labels = :all_upper # Labels that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z. # label_exemptions = # Don't use vague variable or subroutine names like 'last' or 'record'. [NamingConventions::ProhibitAmbiguousNames] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The variable names that are not to be allowed. forbid = abstract bases contract left no record right second # Prohibit indirect object call syntax. [Objects::ProhibitIndirectSyntax] # set_themes = certrule core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Indirect method syntax is forbidden for these methods. # Values that are always included: new. # forbid = # Write `@{ $array_ref }' instead of `@$array_ref'. [-References::ProhibitDoubleSigils] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Capture variable used outside conditional. [RegularExpressions::ProhibitCaptureWithoutTest] # set_themes = certrule core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Names of ways to generate exceptions. # Values that are always included: confess, croak, die. # exception_source = # Split long regexps into smaller `qr//' chunks. [-RegularExpressions::ProhibitComplexRegexes] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum number of characters to allow in a regular expression. # Minimum value 1. No maximum. # max_characters = 60 # Use named character classes instead of explicit character lists. [RegularExpressions::ProhibitEnumeratedClasses] # set_themes = core cosmetic pbp unicode # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # Use character classes for literal meta-characters instead of escapes. [RegularExpressions::ProhibitEscapedMetacharacters] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # Use `eq' or hash instead of fixed-pattern regexps. [RegularExpressions::ProhibitFixedStringMatches] # set_themes = core pbp performance # add_themes = severity = 1 # maximum_violations_per_document = no_limit # Use `[abc]' instead of `a|b|c'. [RegularExpressions::ProhibitSingleCharAlternation] # set_themes = core pbp performance # add_themes = # severity = 1 severity = 2 # maximum_violations_per_document = no_limit # Only use a capturing group if you plan to use the captured value. [RegularExpressions::ProhibitUnusedCapture] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Use only `//' or `{}' to delimit regexps. [-RegularExpressions::ProhibitUnusualDelimiters] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # In addition to allowing '{}', allow '()', '[]', and '{}'. # allow_all_brackets = # Don't use $_ to match against regexes. [RegularExpressions::ProhibitUselessTopic] # set_themes = core # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Use `{' and `}' to delimit multi-line regexps. [-RegularExpressions::RequireBracesForMultiline] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # In addition to allowing '{}', allow '()', '[]', and '{}'. # allow_all_brackets = # Always use the `/s' modifier with regular expressions. [-RegularExpressions::RequireDotMatchAnything] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Always use the `/x' modifier with regular expressions. [-RegularExpressions::RequireExtendedFormatting] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The number of characters that a regular expression must contain before this policy will complain. # Minimum value 0. No maximum. # minimum_regex_length_to_complain_about = 0 # Should regexes that only contain whitespace and word characters be complained about?. # strict = 0 # Always use the `/m' modifier with regular expressions. [-RegularExpressions::RequireLineBoundaryMatching] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't call functions with a leading ampersand sigil. [Subroutines::ProhibitAmpersandSigils] # set_themes = core maintenance pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't declare your own `open' function. # When used as method names this is fine. [-Subroutines::ProhibitBuiltinHomonyms] # set_themes = bugs certrule core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Subroutines matching the name regex to allow under this policy. # allow = print # Minimize complexity by factoring code into smaller subroutines. [Subroutines::ProhibitExcessComplexity] # set_themes = complexity core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum complexity score allowed. # Minimum value 1. No maximum. # max_mccabe = 20 # Return failure with bare `return' instead of `return undef'. [-Subroutines::ProhibitExplicitReturnUndef] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Too many arguments. [Subroutines::ProhibitManyArgs] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The maximum number of arguments to allow a subroutine to have. # Minimum value 1. No maximum. # NOTE: underscores create separate arguments: # https://github.com/Perl-Critic/Perl-Critic/issues/1027 max_arguments = 5 # Don't count $self or $class first argument. skip_object = 1 # `sub never { sub correct {} }'. [Subroutines::ProhibitNestedSubs] # set_themes = bugs core # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Behavior of `sort' is not defined if called in scalar context. [Subroutines::ProhibitReturnSort] # set_themes = bugs certrule core # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Don't write `sub my_function (@@) {}'. [-Subroutines::ProhibitSubroutinePrototypes] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Prevent unused private subroutines. [Subroutines::ProhibitUnusedPrivateSubroutines] # set_themes = certrec core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Pattern that determines what a private subroutine is. # private_name_regex = \b_\w+\b # Subroutines matching the private name regex to allow under this policy. # allow = # Modules that, if used within a file, will cause the policy to be disabled for this file. # skip_when_using = # Pattern defining private subroutine names that are always allowed. allow_name_regex = ^(?:_build_\w+|_data_printer)$ # Prevent access to private subs in other packages. [Subroutines::ProtectPrivateSubs] # set_themes = certrule core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Pattern that determines what a private subroutine is. # private_name_regex = \b_\w+\b # Subroutines matching the private name regex to allow under this policy. # Values that are always included: POSIX::_PC_CHOWN_RESTRICTED, POSIX::_PC_LINK_MAX, POSIX::_PC_MAX_CANON, POSIX::_PC_MAX_INPUT, POSIX::_PC_NAME_MAX, POSIX::_PC_NO_TRUNC, POSIX::_PC_PATH_MAX, POSIX::_PC_PIPE_BUF, POSIX::_PC_VDISABLE, POSIX::_POSIX_ARG_MAX, POSIX::_POSIX_CHILD_MAX, POSIX::_POSIX_CHOWN_RESTRICTED, POSIX::_POSIX_JOB_CONTROL, POSIX::_POSIX_LINK_MAX, POSIX::_POSIX_MAX_CANON, POSIX::_POSIX_MAX_INPUT, POSIX::_POSIX_NAME_MAX, POSIX::_POSIX_NGROUPS_MAX, POSIX::_POSIX_NO_TRUNC, POSIX::_POSIX_OPEN_MAX, POSIX::_POSIX_PATH_MAX, POSIX::_POSIX_PIPE_BUF, POSIX::_POSIX_SAVED_IDS, POSIX::_POSIX_SSIZE_MAX, POSIX::_POSIX_STREAM_MAX, POSIX::_POSIX_TZNAME_MAX, POSIX::_POSIX_VDISABLE, POSIX::_POSIX_VERSION, POSIX::_SC_ARG_MAX, POSIX::_SC_CHILD_MAX, POSIX::_SC_CLK_TCK, POSIX::_SC_JOB_CONTROL, POSIX::_SC_NGROUPS_MAX, POSIX::_SC_OPEN_MAX, POSIX::_SC_PAGESIZE, POSIX::_SC_SAVED_IDS, POSIX::_SC_STREAM_MAX, POSIX::_SC_TZNAME_MAX, POSIX::_SC_VERSION, POSIX::_exit. # allow = # Always unpack `@_' first. [Subroutines::RequireArgUnpacking] # set_themes = core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The number of statements to allow without unpacking. # Minimum value 0. No maximum. # short_subroutine_statements = 0 # Should unpacking from array slices and elements be allowed?. # allow_subscripts = 0 # Allow the usual delegation idiom to these namespaces/subroutines. # Values that are always included: NEXT::, SUPER::. # allow_delegation_to = # Allow unpacking by a closure. # allow_closures = 0 # End every path through a subroutine with an explicit `return' statement. [-Subroutines::RequireFinalReturn] # set_themes = bugs certrec core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The additional subroutines to treat as terminal. # Values that are always included: ..., Carp::confess, Carp::croak, confess, croak, die, exec, exit, throw. # terminal_funcs = # The additional methods to treat as terminal. # Values that are always included: . # terminal_methods = # Prohibit various flavors of `no strict'. [TestingAndDebugging::ProhibitNoStrict] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Allow vars, subs, and/or refs. allow = refs # Prohibit various flavors of `no warnings'. [TestingAndDebugging::ProhibitNoWarnings] # set_themes = bugs certrec core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Permitted warning categories. # allow = # Allow "no warnings" if it restricts the kinds of warnings that are turned off. allow_with_category_restriction = 1 # Don't turn off strict for large blocks of code. [TestingAndDebugging::ProhibitProlongedStrictureOverride] # set_themes = bugs certrec core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # The maximum number of statements in a no strict block. # Minimum value 1. No maximum. # If we're doing this it's probably deliberate and might be for quite a few # subs. statements = 10 # Tests should all have labels. [TestingAndDebugging::RequireTestLabels] # set_themes = core maintenance tests # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The additional modules to require labels for. # Values that are always included: Test::More. # modules = # Always `use strict'. [TestingAndDebugging::RequireUseStrict] # set_themes = bugs certrec certrule core pbp # add_themes = # severity = 5 # maximum_violations_per_document = 1 # The additional modules to treat as equivalent to "strict". # Values that are always included: Any::Moose, Dancer, Dancer2, Mo, Modern::Perl, Mojo::Base, Mojolicious::Lite, Moo, Moo::Role, Moos, Moose, Moose::Exporter, Moose::Role, Moose::Util::TypeConstraints, MooseX::MethodAttributes::Role, MooseX::NonMoose, MooseX::Role::Parameterized, MooseX::Singleton, Mouse, Mouse::Exporter, Mouse::Role, Mouse::Util, Mouse::Util::TypeConstraints, Mousse, Object::Simple, Role::Tiny, Test::Class::Moose, Test::Spec, sane, strict, strictures. equivalent_modules = Repobase::Base Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base Perceptyx::Base::Moose Perceptyx::Base::Moose::Role Test::Perceptyx::Base # Always `use warnings'. [TestingAndDebugging::RequireUseWarnings] # set_themes = bugs certrule core pbp # add_themes = # severity = 4 # maximum_violations_per_document = 1 # The additional modules to treat as equivalent to "warnings". # Values that are always included: Any::Moose, Dancer, Dancer2, Mo, Modern::Perl, Mojo::Base, Mojolicious::Lite, Moo, Moo::Role, Moos, Moose, Moose::Exporter, Moose::Role, Moose::Util::TypeConstraints, MooseX::MethodAttributes::Role, MooseX::NonMoose, MooseX::Role::Parameterized, MooseX::Singleton, Mouse, Mouse::Exporter, Mouse::Role, Mouse::Util, Mouse::Util::TypeConstraints, Mousse, Object::Simple, Role::Tiny, Test::Class::Moose, Test::Spec, sane, strictures, warnings. equivalent_modules = Repobase::Base Repobase::Base::Moose Repobase::Base::Moose::Role Perceptyx::Base Perceptyx::Base::Moose Perceptyx::Base::Moose::Role Test::Perceptyx::Base # Don't use the comma operator as a statement separator. [-ValuesAndExpressions::ProhibitCommaSeparatedStatements] # set_themes = bugs certrule core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Allow map and grep blocks to return lists. # allow_last_statement_to_be_comma_separated_in_map_and_grep = 0 # Prohibit version values from outside the module. [ValuesAndExpressions::ProhibitComplexVersion] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Make "use version; our $VERSION = qv('1.2.3');" a violation of this policy. # forbid_use_version = 0 # Don't `use constant FOO => 15'. [ValuesAndExpressions::ProhibitConstantPragma] # set_themes = bugs core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Write `q{}' instead of `'''. [-ValuesAndExpressions::ProhibitEmptyQuotes] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Write `"\N{DELETE}"' instead of `"\x7F"', etc. [-ValuesAndExpressions::ProhibitEscapedCharacters] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Use concatenation or HEREDOCs instead of literal line breaks in strings. [ValuesAndExpressions::ProhibitImplicitNewlines] # set_themes = core cosmetic pbp # add_themes = severity = 1 # maximum_violations_per_document = no_limit # Always use single quotes for literal strings. [-ValuesAndExpressions::ProhibitInterpolationOfLiterals] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # Kinds of delimiters to permit, e.g. "qq{", "qq(", "qq[", "qq/". # allow = # If the string contains ' characters, allow "" to quote it. # allow_if_string_contains_single_quote = 0 # Write `oct(755)' instead of `0755'. [-ValuesAndExpressions::ProhibitLeadingZeros] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Don't allow any leading zeros at all. Otherwise builtins that deal with Unix permissions, e.g. chmod, don't get flagged. # strict = 0 # Long chains of method calls indicate tightly coupled code. [ValuesAndExpressions::ProhibitLongChainsOfMethodCalls] # set_themes = core maintenance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The number of chained calls to allow. # Minimum value 1. No maximum. # max_chain_length = 3 # Don't use values that don't explain themselves. [ValuesAndExpressions::ProhibitMagicNumbers] # set_themes = certrec core maintenance # add_themes = severity = 1 # maximum_violations_per_document = 10 # Individual and ranges of values to allow, and/or "all_integers". # allowed_values = 0 1 2 # Kind of literals to allow. # Valid values: Binary, Exp, Float, Hex, Octal. # allowed_types = Float # Should anything to the right of a "=>" be allowed?. # allow_to_the_right_of_a_fat_comma = 1 # Names of subroutines that create constants. # Values that are always included: Readonly, Readonly::Array, Readonly::Hash, Readonly::Scalar, const. # constant_creator_subroutines = # Don't mix numeric operators with string operands, or vice-versa. [ValuesAndExpressions::ProhibitMismatchedOperators] # set_themes = bugs certrule core # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write ` !$foo && $bar || $baz ' instead of ` not $foo && $bar or $baz'. [ValuesAndExpressions::ProhibitMixedBooleanOperators] # set_themes = bugs certrec core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Use `q{}' or `qq{}' instead of quotes for awkward-looking strings. [-ValuesAndExpressions::ProhibitNoisyQuotes] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Don't use quotes (`'', `"', ``') as delimiters for the quote-like operators. [ValuesAndExpressions::ProhibitQuotesAsQuotelikeOperatorDelimiters] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The operators to allow single-quotes as delimiters for. # Valid values: m, q, qq, qr, qw, qx, s, tr, y. # single_quote_allowed_operators = m s qr qx # The operators to allow double-quotes as delimiters for. # Valid values: m, q, qq, qr, qw, qx, s, tr, y. # double_quote_allowed_operators = # The operators to allow back-quotes (back-ticks) as delimiters for. # Valid values: m, q, qq, qr, qw, qx, s, tr, y. # back_quote_allowed_operators = # Don't write ` print <<'__END__' '. [ValuesAndExpressions::ProhibitSpecialLiteralHeredocTerminator] # set_themes = core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Don't use strings like `v1.4' or `1.4.5' when including other modules. [-ValuesAndExpressions::ProhibitVersionStrings] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Require $VERSION to be a constant rather than a computed value. [ValuesAndExpressions::RequireConstantVersion] # set_themes = core maintenance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Allow qv() and version->new() without a 'use version' on the same line. # allow_version_without_use_on_same_line = 0 # Warns that you might have used single quotes when you really wanted double-quotes. [-ValuesAndExpressions::RequireInterpolationOfMetachars] # set_themes = core cosmetic pbp # add_themes = # severity = 1 # maximum_violations_per_document = no_limit # RCS keywords to ignore in potential interpolation. # rcs_keywords = # Write ` 141_234_397.0145 ' instead of ` 141234397.0145 '. [ValuesAndExpressions::RequireNumberSeparators] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The minimum absolute value to require separators in. # Minimum value 10. No maximum. # min_value = 10_000 # Write ` print <<'THE_END' ' or ` print <<"THE_END" '. [-ValuesAndExpressions::RequireQuotedHeredocTerminator] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write ` <<'THE_END'; ' instead of ` <<'theEnd'; '. [ValuesAndExpressions::RequireUpperCaseHeredocTerminator] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Do not write ` my $foo .= 'bar'; '. [Variables::ProhibitAugmentedAssignmentInDeclaration] # set_themes = bugs core # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Allow augmented assignment for our variables. # allow_our = 0 # Do not write ` my $foo = $bar if $baz; '. [Variables::ProhibitConditionalDeclarations] # set_themes = bugs core # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Use `my' instead of `local', except when you have to. [Variables::ProhibitLocalVars] # set_themes = core maintenance pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Avoid `$`', `$&', `$'' and their English equivalents. [Variables::ProhibitMatchVars] # set_themes = core pbp performance # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Eliminate globals declared with `our' or `use vars'. [Variables::ProhibitPackageVars] # set_themes = core maintenance pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The base set of packages to allow variables for. # packages = Data::Dumper File::Find FindBin Log::Log4perl Test::Builder Text::Wrap # The set of packages to allow variables for, in addition to those given in "packages". add_packages = Devel::Cover::DB # Use double colon (::) to separate package name components instead of single quotes ('). [Variables::ProhibitPerl4PackageNames] # set_themes = certrec core maintenance # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # Write `$EVAL_ERROR' instead of `$@'. [-Variables::ProhibitPunctuationVars] # set_themes = core cosmetic pbp # add_themes = # severity = 2 # maximum_violations_per_document = no_limit # The additional variables to allow. # Values that are always included: $1, $2, $3, $4, $5, $6, $7, $8, $9, $], $_, @_, _. # allow = # Controls checking interpolated strings for punctuation variables. # Valid values: disable, simple, thorough. # string_mode = thorough # Do not reuse a variable name in a lexical scope [Variables::ProhibitReusedNames] # set_themes = bugs core # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # The variables to not consider as duplicates. # allow = $self $class # Don't ask for storage you don't need. [Variables::ProhibitUnusedVariables] # set_themes = certrec core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Prevent access to private vars in other packages. [Variables::ProtectPrivateVars] # set_themes = certrule core maintenance # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `local $foo = $bar;' instead of just `local $foo;'. [-Variables::RequireInitializationForLocalVars] # set_themes = bugs certrec core pbp # add_themes = # severity = 3 # maximum_violations_per_document = no_limit # Write `for my $element (@list) {...}' instead of `for $element (@list) {...}'. [Variables::RequireLexicalLoopIterators] # set_themes = bugs certrec core pbp # add_themes = # severity = 5 # maximum_violations_per_document = no_limit # Magic variables should be assigned as "local". [Variables::RequireLocalizedPunctuationVars] # set_themes = bugs certrec core pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit # Global variables to exclude from this policy. # Values that are always included: $ARG, $_, @_. allow = %ENV %SIG $> $0 # Negative array index should be used. [Variables::RequireNegativeIndices] # set_themes = core maintenance pbp # add_themes = # severity = 4 # maximum_violations_per_document = no_limit gcov2perl100755000765000024 1363114631552031 15475 0ustar00pjcjstaff000000000000Devel-Cover-1.44/bin#!/usr/bin/perl # Copyright 2001-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net require 5.12.0; use strict; use warnings; our $VERSION = '1.44'; # VERSION use Devel::Cover::DB; use File::Path; use File::Spec; use Getopt::Long; use Pod::Usage; my $Options = { db => "cover_db", }; sub get_options { die "Bad option" unless GetOptions($Options, # Store the options in the Options hash qw( db=s help|h! info|i! version|v! )); print "$0 version " . __PACKAGE__->VERSION . "\n" and exit 0 if $Options->{version}; pod2usage(-exitval => 0, -verbose => 0) if $Options->{help}; pod2usage(-exitval => 0, -verbose => 2) if $Options->{info}; } sub add_cover { my ($file) = @_; my ($vol, $dir) = File::Spec->splitpath(File::Spec->rel2abs($file)); $dir = File::Spec->catpath($vol, $dir); my $f = $file; $f =~ s/.gcov$//; my %run; $run{collected} = ["statement"]; $run{start} = $run{finish} = time; my $structure = Devel::Cover::DB::Structure->new; $structure->add_criteria("statement"); $structure->add_criteria("branch"); my $statement_re = qr/^\s*([-0-9#]+\*?):\s*(\d+):(.*)/; my $branch_re = qr/^branch\s+(\d+)\s+(?:taken|never)\s+(\w+)/; my ($line, $text); open F, $file or die "Can't open $file: $!\n"; gcov_line: while (my $gcov_text = ) { # print "Processing line [$gcov_text]\n"; if ($gcov_text =~ /^[^:]+:[^:]+:Source:(.*)$/) { $f = $1; $f = File::Spec->abs2rel(File::Spec->catfile($dir, $f)) unless File::Spec->file_name_is_absolute($f); } unless (defined $run{digests}{$f}) { unless (-f $f) { warn "no source $f found for $file\n"; close F or die "Can't close $file: $!\n"; return; } $run{digests}{$f} = $structure->set_file($f); } if ($gcov_text =~ $statement_re) { my $count = $1; $line = $2; $text = $3; next if $count eq "-"; $count = 0 if $count eq "#####"; # Remove asterisk after execution count. Gcov outputs an asterisk # symbol for certain lines as noted at # . $count =~ s/\*$//; # print "$f:$line - $count\n"; push @{$run{count}{$f}{statement}}, $count; $structure->add_statement($f, $line); } elsif ($gcov_text =~ $branch_re) { my @branches; # look for: # branch 0 taken 0 (fallthrough) # branch 1 taken 19 # branch 0 never executed # branch 1 never executed while ($gcov_text =~ $branch_re) { push @branches, $2 eq "executed" ? 0 : $2; $gcov_text = ; } # print "branches on $f:$line are: @branches\n"; if (@branches == 2) { $structure->add_branch($f, [ $line, { text => $text } ]); push @{$run{count}{$f}{branch}}, \@branches; } else { warn "gcov2perl: Warning: ignoring branch with ", scalar @branches, " targets at $f:$line $text\n"; } redo gcov_line; # process the line after the branch data } } close F or die "Can't close $file: $!\n"; my $run = $run{start} . ".$$." . sprintf "%05d", rand 2 ** 16; my $db = $Options->{db}; my $cover = Devel::Cover::DB->new( base => $db, runs => { $run => \%run }, structure => $structure, ); $db .= "/runs"; mkpath $db unless -d $db; $db .= "/$run"; $cover->{db} = $db; print STDOUT "gcov2perl: Writing coverage database to $db\n"; $cover->write; } sub main { get_options; add_cover $_ for @ARGV; } main __END__ =head1 NAME gcov2perl - convert gcov files to Devel::Cover databases =head1 VERSION version 1.44 =head1 SYNOPSIS gcov2perl -h -i -v -db database gcov_files =head1 DESCRIPTION Convert gcov files to Devel::Cover databases. =head1 OPTIONS The following command line options are supported: -db database - specify the database to use -h -help - show help -i -info - show documentation -v -version - show version =head1 DETAILS To obtain coverage of XS files they must first be compiled with the appropriate options. In a standard Makefile environment, such as that created by ExtUtils::MakeMaker, this can be accomplished with the command: HARNESS_PERL_SWITCHES=-MDevel::Cover make test \ CCFLAGS=-O0\ -fprofile-arcs\ -ftest-coverage \ OTHERLDFLAGS=-fprofile-arcs\ -ftest-coverage If you have already built your object files it may be necessary to run make clean first, or to find some other way to ensure that they get rebuilt with the options gcov requires. Now the code coverage data has been collected C needs to be run: gcov Mylib.xs This will create one or more gcov files on which you can run C: gcov2perl Mylib.xs.gcov Finally, C should be run as usual with any options required: cover If you are running everything with standard options, you can do all this with one command: cover -test =head1 EXIT STATUS The following exit values are returned: 0 All files converted successfully >0 An error occurred. =head1 SEE ALSO Devel::Cover =head1 BUGS Huh? =head1 LICENCE Copyright 2001-2024, Paul Johnson (paul@pjcj.net) This software is free. It is licensed under the same terms as Perl itself. The latest version of this software should be available from my homepage: http://www.pjcj.net =cut cpancover100755000765000024 1237514631552031 15556 0ustar00pjcjstaff000000000000Devel-Cover-1.44/bin#!/usr/bin/perl # Copyright 2002-2024, Paul Johnson (paul@pjcj.net) # This software is free. It is licensed under the same terms as Perl itself. # The latest version of this software should be available from my homepage: # http://www.pjcj.net use 5.38.0; use warnings; our $VERSION = '1.44'; # VERSION use Devel::Cover::Collection; use Cwd qw( abs_path cwd ); use Fcntl ":flock"; use Getopt::Long; use Pod::Usage; # use Carp; $SIG{__DIE__} = \&Carp::confess; $|++; my $Options = { bin_dir => abs_path($0) =~ s|/cpancover$||r, build => 1, compress_old_versions => 0, docker => "docker", dryrun => 0, force => 0, generate_html => 0, latest => 0, local => 0, local_build => 0, modules => [], output_file => "index.html", report => "html_basic", results_dir => cwd(), timeout => 7200, # two hours verbose => 0, workers => 0, }; sub get_options { die "Bad option" unless GetOptions( $Options, qw( bin_dir=s build! compress_old_versions=i docker=s dryrun! force! generate_html! help|h! info|i! latest! local! local_build! module_file=s modules=s output_file=s report=s results_dir=s timeout=i verbose! version|v! workers=i ) ); say "$0 version " . __PACKAGE__->VERSION and exit 0 if $Options->{version}; pod2usage(-exitval => 0, -verbose => 0) if $Options->{help}; pod2usage(-exitval => 0, -verbose => 2) if $Options->{info}; } sub newcp { Devel::Cover::Collection->new( map { $_ => $Options->{$_} } qw( bin_dir docker dryrun force local modules output_file report results_dir timeout verbose workers ) ) } sub main { # TODO - only one instance should run at a time get_options; if ($Options->{latest}) { my $cp = newcp; $cp->get_latest; return; } if ($Options->{local_build}) { my $cp = newcp; $cp->set_modules(@ARGV); $cp->local_build; return; } if ($Options->{module_file}) { my $cp = newcp; $cp->set_module_file($Options->{module_file}); $cp->cover_modules; } if ($Options->{build}) { if (@ARGV) { my $cp = newcp; $cp->set_modules(@ARGV); $cp->cover_modules; } elsif (!-t STDIN) { my @modules; while (<>) { chomp; push @modules, split; } my $cp = newcp; $cp->set_modules(@modules); $cp->cover_modules; } else { my $cp = newcp; $cp->cover_modules; } } if ($Options->{generate_html}) { my $cp = newcp; $cp->generate_html; } if ($Options->{compress_old_versions}) { my $cp = newcp; $cp->compress_old_versions($Options->{compress_old_versions}); } } main __END__ =head1 NAME cpancover - report coverage statistics on CPAN modules =head1 VERSION version 1.44 =head1 SYNOPSIS cpancover --help --info --version --collect --redo_cpancover_html --redo_html --force --dryrun --modules module_name --results_dir /path/to/dir --outputdir /path/to/dir --outputfile filename.html --report report_name --generate_html --compress_old_versions number_to_keep --local =head1 DESCRIPTION =head1 OPTIONS The following command line options are supported: -h --help - show help -i --info - show documentation -v --version - show version --collect - collect coverage from modules (on) --directory - location of the modules ($cwd) --dryrun - don't execute (for some commands) (off) --force - recollect coverage (off) --modules - modules to use (all in $dir) --outputdir - where to store output ($directory) --outputfile - top level index (coverage.html) --redo_cpancover_html - don't set default modules (off) --redo_html - force html generation for modules (off) --report - report to use (html_basic) --generate_html - generate html (off) --compress_old_versions - compress data older than n versions (3) --local - use local (uninstalled) code (off) =head1 DETAILS =head1 REQUIREMENTS Collect coverage for results and create html, csv and json output. The modules L