IO-CaptureOutput-1.1105/000755 000766 000024 00000000000 13554665671 015207 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/LICENSE000644 000766 000024 00000043735 13554665671 016230 0ustar00davidstaff000000 000000 This software is copyright (c) 2019 by Simon Flack and David Golden. 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) 2019 by Simon Flack and David Golden. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2019 by Simon Flack and David Golden. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End IO-CaptureOutput-1.1105/cpanfile000644 000766 000024 00000002767 13554665671 016727 0ustar00davidstaff000000 000000 requires "Carp" => "0"; requires "Exporter" => "0"; requires "File::Basename" => "0"; requires "File::Temp" => "0.16"; requires "Symbol" => "0"; requires "perl" => "5.006"; requires "strict" => "0"; requires "vars" => "0"; requires "warnings" => "0"; on 'test' => sub { requires "ExtUtils::MakeMaker" => "0"; requires "File::Spec" => "3.27"; requires "IO::File" => "0"; requires "Test::More" => "0.62"; requires "perl" => "5.006"; }; on 'test' => sub { recommends "CPAN::Meta" => "2.120900"; }; on 'configure' => sub { requires "ExtUtils::MakeMaker" => "6.17"; requires "perl" => "5.006"; }; on 'develop' => sub { requires "Dist::Zilla" => "5"; requires "Dist::Zilla::Plugin::Deprecated" => "0"; requires "Dist::Zilla::Plugin::OSPrereqs" => "0"; requires "Dist::Zilla::Plugin::RemovePrereqs" => "0"; requires "Dist::Zilla::PluginBundle::DAGOLDEN" => "0.072"; requires "File::Spec" => "0"; requires "File::Temp" => "0"; requires "IO::Handle" => "0"; requires "IPC::Open3" => "0"; requires "Pod::Coverage::TrustPod" => "0"; requires "Pod::Wordlist" => "0"; requires "Software::License::Perl_5" => "0"; requires "Test::CPAN::Meta" => "0"; requires "Test::MinimumVersion" => "0"; requires "Test::More" => "0"; requires "Test::Perl::Critic" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Portability::Files" => "0"; requires "Test::Spelling" => "0.12"; requires "Test::Version" => "1"; requires "perl" => "5.006"; }; IO-CaptureOutput-1.1105/Changes000644 000766 000024 00000012401 13554665671 016500 0ustar00davidstaff000000 000000 Revision history for IO::CaptureOutput 1.1105 2019-10-25 17:40:04-04:00 America/New_York [META] - Add deprecation data to META file. 1.1104 2015-01-23 22:03:57-05:00 America/New_York [PREREQS] - Drop File::Spec 3.27 prereq except on MSWin32 1.1103 2014-02-27 19:54:14-05:00 America/New_York [FIXED] - Fixed rt.cpan.org #71775: test failure on non-threaded Win32 perls [CHANGED] - Updated metadata, repo and bugtracker - Switched distribution management to Dist::Zilla 1.1102 Mon Feb 15 07:36:53 EST 2010 - Fixed: RT#45160 test that confused archname and osname (reported by Dolmen and Tux) 1.1101 Tue Mar 3 23:30:45 EST 2009 - Fixed Makefile.PL; no functional changes 1.11 Mon Feb 9 21:47:37 EST 2009 - Fixed: bug in creation of STDERR capture proxy object 1.1001 Tue Jan 20 18:32:27 EST 2009 - Test fix: marked some wperl.exe tests as TODO on Windows Vista/Win7 1.10 Sun Sep 21 09:34:31 EDT 2008 - Added: functions to capture output from external command now also return a success flag and the exit code - Documented: shorter, punchier synopsis 1.09 Thu Jul 3 09:17:35 EDT 2008 - Added: parameter validation and error messages - Documented: examples of capturing only to a file and parameter errors 1.08_50 Mon May 19 23:19:01 EDT 2008 - Changed: doesn't bother to read captured output back from file if no scalar reference is provided to receive it - Fixed: 'capture { .. } undef, undef, $capture_file' now correctly merges STDOUT and STDERR 1.0801 Sat Feb 9 09:41:11 EST 2008 - testfix: skip some error handling tests if temp files can't be made read-only (e.g. running test as root) - added some prerequisites and meta information to Build.PL - added an 'examples' directory 1.08 Wed Feb 6 22:43:37 EST 2008 - added additional tests and revised documentation 1.07_01 Wed Jan 30 20:57:15 EST 2008 - added support for capturing to named files instead of anonymous temporary ones (adapted from patch from Anton Berezin) - added support to pass through STDOUT or STDERR without capture while capturing the other one (adapted from patch from Anton Berezin) 1.0601 Sun Dec 30 17:31:31 EST 2007 - relaxed capture_exec.t to avoid failing under noisy perl configurations 1.06 Mon, 26 Nov 2007 16:40:40 EST - no changes from 1.05_53 1.05_53 Sat Nov 17 18:45:08 EST 2007 - MSVC++ fixes for Inline::C testing breaks on other compilers; this version uses separate C routines for MSVC++ and other compilers 1.05_52 Sat Nov 17 14:47:52 EST 2007 - changed Inline::C code for printing to stdout to match that for stderr; works around a bug if the intalled MSVC++ version doesn't match the version used to build ActiveState Perl on MSWin32. 1.05_51 Sat Nov 17 13:36:39 EST 2007 - changed Inline::C code for printing to stderr to attempt to work around a segfault bug on some MSWin32 systems (Alternative described by BrowserUK at http://www.perlmonks.org/?node_id=649021 ) - minor Perl::Critic cleanup to pass xt tests 1.05 Fri Nov 16 08:44:06 EST 2007 *** No changes since 1.04_03; key changes since 1.03 follows *** - added support for capture() merging STDERR and STDOUT to the same scalar, i.e. "capture( \&foo, \$out, \$out )" (RT#24695) - added capture_exec_combined() and alias qxy() to merge STDERR and STDOUT for subprocess execution (RT#29289) - bugfix: stop crashing if output filehandles are previously closed or if running without a console on MSWin32 (i.e. wperl.exe) (RT#23676) - bugfix: capture.t would fail on Win32 if Inline::C was installed; fixed the sample C code used in testing to flush stderr (RT#21712) - bugfix: was failing on perl 5.8.0 due to extraneous space in call to open(); removing the space fixed the bug (RT#22044) 1.04_03 Sun Nov 4 11:35:57 EST 2007 - suppress warnings included in captured output when console output handles were previously closed; only affects some versions/builds of perl on some platforms (found by Slaven Rezic 5.6.2 on FreeBSD 6.2) 1.04_02 Wed Oct 31 00:52:49 EDT 2007 - added support for capture() merging STDERR and STDOUT to the same scalar, i.e. "capture( \&foo, \$out, \$out )" (RT#24695) - added capture_exec_combined() and alias qxy() to merge STDERR and STDOUT for subprocess execution (RT#29289) - bugfix: stop crashing if output filehandles are previously closed or if running without a console on MSWin32 (i.e. wperl.exe) (RT#23676) - cleaned up documentation for consistency 1.04_01 Mon Oct 29 22:56:45 EDT 2007 - DAGOLDEN added as maintainer; updated build system and packaging for ongoing maintenance - bugfix: capture.t would fail on Win32 if Inline::C was installed; fixed the sample C code used in testing to flush stderr (RT#21712) - bugfix: was failing on perl 5.8.0 due to extraneous space in call to open(); removing the space fixed the bug (RT#22044) 1.03 2005-03-25 - Add t/pod_coverage.t 1.02 2004-11-22 - add extra quoting on Win32 platform - Win32 won't unlink a file that is open in write mode, so close it first - minor POD tweaks 1.0 2004-11-21 - Initial revision IO-CaptureOutput-1.1105/MANIFEST000644 000766 000024 00000001162 13554665671 016340 0ustar00davidstaff000000 000000 # This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.012. CONTRIBUTING.mkdn Changes LICENSE MANIFEST META.json META.yml Makefile.PL README cpanfile dist.ini examples/capture.pl lib/IO/CaptureOutput.pm perlcritic.rc t/00-report-prereqs.dd t/00-report-prereqs.t t/capture.t t/capture_exec.t t/capture_file.t t/errors.t t/noconsole.t t/scripts/wperl-capture.pl t/scripts/wperl-exec.pl t/wperl.t xt/author/00-compile.t xt/author/critic.t xt/author/minimum-version.t xt/author/pod-coverage.t xt/author/pod-spell.t xt/author/pod-syntax.t xt/author/portability.t xt/author/test-version.t xt/release/distmeta.t IO-CaptureOutput-1.1105/perlcritic.rc000644 000766 000024 00000001166 13554665671 017701 0ustar00davidstaff000000 000000 severity = 5 verbose = 8 [Variables::ProhibitPunctuationVars] allow = $@ $! [TestingAndDebugging::ProhibitNoStrict] allow = refs [Variables::ProhibitEvilVariables] variables = $DB::single # Turn these off [-BuiltinFunctions::ProhibitStringyEval] [-ControlStructures::ProhibitPostfixControls] [-ControlStructures::ProhibitUnlessBlocks] [-Documentation::RequirePodSections] [-InputOutput::ProhibitInteractiveTest] [-References::ProhibitDoubleSigils] [-RegularExpressions::RequireExtendedFormatting] [-InputOutput::ProhibitTwoArgOpen] [-Modules::ProhibitEvilModules] # Turn this on [Lax::ProhibitStringyEval::ExceptForRequire] IO-CaptureOutput-1.1105/CONTRIBUTING.mkdn000644 000766 000024 00000005751 13554665671 020001 0ustar00davidstaff000000 000000 ## HOW TO CONTRIBUTE Thank you for considering contributing to this distribution. This file contains instructions that will help you work with the source code. The distribution is managed with Dist::Zilla. This means than many of the usual files you might expect are not in the repository, but are generated at release time, as is much of the documentation. Some generated files are kept in the repository as a convenience (e.g. Makefile.PL or cpanfile). Generally, **you do not need Dist::Zilla to contribute patches**. You do need Dist::Zilla to create a tarball. See below for guidance. ### Getting dependencies If you have App::cpanminus 1.6 or later installed, you can use `cpanm` to satisfy dependencies like this: $ cpanm --installdeps . Otherwise, look for either a `Makefile.PL` or `cpanfile` file for a list of dependencies to satisfy. ### Running tests You can run tests directly using the `prove` tool: $ prove -l $ prove -lv t/some_test_file.t For most of my distributions, `prove` is entirely sufficient for you to test any patches you have. I use `prove` for 99% of my testing during development. ### Code style and tidying Please try to match any existing coding style. If there is a `.perltidyrc` file, please install Perl::Tidy and use perltidy before submitting patches. If there is a `tidyall.ini` file, you can also install Code::TidyAll and run `tidyall` on a file or `tidyall -a` to tidy all files. ### Patching documentation Much of the documentation Pod is generated at release time. Some is generated boilerplate; other documentation is built from pseudo-POD directives in the source like C<=method> or C<=func>. If you would like to submit a documentation edit, please limit yourself to the documentation you see. If you see typos or documentation issues in the generated docs, please email or open a bug ticket instead of patching. ### Installing and using Dist::Zilla Dist::Zilla is a very powerful authoring tool, optimized for maintaining a large number of distributions with a high degree of automation, but it has a large dependency chain, a bit of a learning curve and requires a number of author-specific plugins. To install it from CPAN, I recommend one of the following approaches for the quickest installation: # using CPAN.pm, but bypassing non-functional pod tests $ cpan TAP::Harness::Restricted $ PERL_MM_USE_DEFAULT=1 HARNESS_CLASS=TAP::Harness::Restricted cpan Dist::Zilla # using cpanm, bypassing *all* tests $ cpanm -n Dist::Zilla In either case, it's probably going to take about 10 minutes. Go for a walk, go get a cup of your favorite beverage, take a bathroom break, or whatever. When you get back, Dist::Zilla should be ready for you. Then you need to install any plugins specific to this distribution: $ cpan `dzil authordeps` $ dzil authordeps | cpanm Once installed, here are some dzil commands you might try: $ dzil build $ dzil test $ dzil xtest You can learn more about Dist::Zilla at http://dzil.org/ IO-CaptureOutput-1.1105/t/000755 000766 000024 00000000000 13554665671 015452 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/xt/000755 000766 000024 00000000000 13554665671 015642 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/README000644 000766 000024 00000016003 13554665671 016067 0ustar00davidstaff000000 000000 NAME IO::CaptureOutput - (DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS VERSION version 1.1105 SYNOPSIS use IO::CaptureOutput qw(capture qxx qxy); # STDOUT and STDERR separately capture { noisy_sub(@args) } \$stdout, \$stderr; # STDOUT and STDERR together capture { noisy_sub(@args) } \$combined, \$combined; # STDOUT and STDERR from external command ($stdout, $stderr, $success) = qxx( @cmd ); # STDOUT and STDERR together from external command ($combined, $success) = qxy( @cmd ); DESCRIPTION This module is no longer recommended by the maintainer - see Capture::Tiny instead. This module provides routines for capturing STDOUT and STDERR from perl subroutines, forked system calls (e.g. "system()", "fork()") and from XS or C modules. NAME FUNCTIONS The following functions will be exported on demand. capture() capture \&subroutine, \$stdout, \$stderr; Captures everything printed to "STDOUT" and "STDERR" for the duration of &subroutine. $stdout and $stderr are optional scalars that will contain "STDOUT" and "STDERR" respectively. "capture()" uses a code prototype so the first argument can be specified directly within brackets if desired. # shorthand with prototype capture C< print __PACKAGE__ > \$stdout, \$stderr; Returns the return value(s) of &subroutine. The sub is called in the same context as "capture()" was called e.g.: @rv = capture C< wantarray > ; # returns true $rv = capture C< wantarray > ; # returns defined, but not true capture C< wantarray >; # void, returns undef "capture()" is able to capture output from subprocesses and C code, which traditional "tie()" methods of output capture are unable to do. Note: "capture()" will only capture output that has been written or flushed to the filehandle. If the two scalar references refer to the same scalar, then "STDERR" will be merged to "STDOUT" before capturing and the scalar will hold the combined output of both. capture \&subroutine, \$combined, \$combined; Normally, "capture()" uses anonymous, temporary files for capturing output. If desired, specific file names may be provided instead as additional options. capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; Files provided will be clobbered, overwriting any previous data, but will persist after the call to "capture()" for inspection or other manipulation. By default, when no references are provided to hold STDOUT or STDERR, output is captured and silently discarded. # Capture STDOUT, discard STDERR capture \&subroutine, \$stdout; # Discard STDOUT, capture STDERR capture \&subroutine, undef, \$stderr; However, even when using "undef", output can be captured to specific files. # Capture STDOUT to a specific file, discard STDERR capture \&subroutine, \$stdout, undef, $outfile; # Discard STDOUT, capture STDERR to a specific file capture \&subroutine, undef, \$stderr, undef, $err_file; # Discard both, capture merged output to a specific file capture \&subroutine, undef, undef, $mergedfile; It is a fatal error to merge STDOUT and STDERR and request separate, specific files for capture. # ERROR: capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; capture \&subroutine, undef, undef, $out_file, $err_file; If either STDOUT or STDERR should be passed through to the terminal instead of captured, provide a reference to undef -- "\undef" -- instead of a capture variable. # Capture STDOUT, display STDERR capture \&subroutine, \$stdout, \undef; # Display STDOUT, capture STDERR capture \&subroutine, \undef, \$stderr; capture_exec() ($stdout, $stderr, $success, $exit_code) = capture_exec(@args); Captures and returns the output from "system(@args)". In scalar context, "capture_exec()" will return what was printed to "STDOUT". In list context, it returns what was printed to "STDOUT" and "STDERR" as well as a success flag and the exit value. $stdout = capture_exec('perl', '-e', 'print "hello world"'); ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test"'); "capture_exec" passes its arguments to "system()" and on MSWin32 will protect arguments with shell quotes if necessary. This makes it a handy and slightly more portable alternative to backticks, piped "open()" and "IPC::Open3". The $success flag returned will be true if the command ran successfully and false if it did not (if the command could not be run or if it ran and returned a non-zero exit value). On failure, the raw exit value of the "system()" call is available both in the $exit_code returned and in the $? variable. ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test" and exit 1'); if ( ! $success ) { print "The exit code was " . ($exit_code >> 8) . "\n"; } See perlvar for more information on interpreting a child process exit code. capture_exec_combined() ($combined, $success, $exit_code) = capture_exec_combined( 'perl', '-e', 'print "hello\n"', 'warn "Test\n" ); This is just like "capture_exec()", except that it merges "STDERR" with "STDOUT" before capturing output. Note: there is no guarantee that text printed to "STDOUT" and "STDERR" in the subprocess will be appear in order. The actual order will depend on how IO buffering is handled in the subprocess. qxx() This is an alias for "capture_exec()". qxy() This is an alias for "capture_exec_combined()". SEE ALSO * Capture::Tiny * IPC::Open3 * IO::Capture * IO::Utils * IPC::System::Simple SUPPORT Bugs / Feature Requests Please report any bugs or feature requests through the issue tracker at . You will be notified automatically of any progress on your issue. Source Code This is open source software. The code repository is available for public review and contribution under the terms of the license. git clone https://github.com/dagolden/IO-CaptureOutput.git AUTHORS * Simon Flack * David Golden CONTRIBUTORS * David Golden * José Joaquín Atria * Mike Latimer * Olivier Mengué * Tony Cook COPYRIGHT AND LICENSE This software is copyright (c) 2019 by Simon Flack and David Golden. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. IO-CaptureOutput-1.1105/examples/000755 000766 000024 00000000000 13554665671 017025 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/META.yml000644 000766 000024 00000002672 13554665671 016467 0ustar00davidstaff000000 000000 --- abstract: '(DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS' author: - 'Simon Flack ' - 'David Golden ' build_requires: ExtUtils::MakeMaker: '0' File::Spec: '3.27' IO::File: '0' Test::More: '0.62' perl: '5.006' configure_requires: ExtUtils::MakeMaker: '6.17' perl: '5.006' dynamic_config: 1 generated_by: 'Dist::Zilla version 6.012, 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: IO-CaptureOutput no_index: directory: - corpus - examples - t - xt package: - DB provides: IO::CaptureOutput: file: lib/IO/CaptureOutput.pm version: '1.1105' requires: Carp: '0' Exporter: '0' File::Basename: '0' File::Temp: '0.16' Symbol: '0' perl: '5.006' strict: '0' vars: '0' warnings: '0' resources: bugtracker: https://github.com/dagolden/IO-CaptureOutput/issues homepage: https://github.com/dagolden/IO-CaptureOutput repository: https://github.com/dagolden/IO-CaptureOutput.git version: '1.1105' x_authority: cpan:DAGOLDEN x_contributors: - 'David Golden ' - 'José Joaquín Atria ' - 'Mike Latimer ' - 'Olivier Mengué ' - 'Tony Cook ' x_deprecated: 1 x_generated_by_perl: v5.30.0 x_serialization_backend: 'YAML::Tiny version 1.73' IO-CaptureOutput-1.1105/lib/000755 000766 000024 00000000000 13554665671 015755 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/Makefile.PL000644 000766 000024 00000003231 13554665671 017160 0ustar00davidstaff000000 000000 # This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.012. use strict; use warnings; use 5.006; use ExtUtils::MakeMaker 6.17; my %WriteMakefileArgs = ( "ABSTRACT" => "(DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS", "AUTHOR" => "Simon Flack , David Golden ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => "6.17" }, "DISTNAME" => "IO-CaptureOutput", "LICENSE" => "perl", "MIN_PERL_VERSION" => "5.006", "NAME" => "IO::CaptureOutput", "PREREQ_PM" => { "Carp" => 0, "Exporter" => 0, "File::Basename" => 0, "File::Temp" => "0.16", "Symbol" => 0, "strict" => 0, "vars" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "ExtUtils::MakeMaker" => 0, "File::Spec" => "3.27", "IO::File" => 0, "Test::More" => "0.62" }, "VERSION" => "1.1105", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Carp" => 0, "Exporter" => 0, "ExtUtils::MakeMaker" => 0, "File::Basename" => 0, "File::Spec" => "3.27", "File::Temp" => "0.16", "IO::File" => 0, "Symbol" => 0, "Test::More" => "0.62", "strict" => 0, "vars" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; if ( $^O eq 'MSWin32' ) { $WriteMakefileArgs{PREREQ_PM}{'File::Spec'} = $FallbackPrereqs{'File::Spec'} = '3.27'; } WriteMakefile(%WriteMakefileArgs); IO-CaptureOutput-1.1105/META.json000644 000766 000024 00000006516 13554665671 016640 0ustar00davidstaff000000 000000 { "abstract" : "(DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS", "author" : [ "Simon Flack ", "David Golden " ], "dynamic_config" : 1, "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "IO-CaptureOutput", "no_index" : { "directory" : [ "corpus", "examples", "t", "xt" ], "package" : [ "DB" ] }, "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.17", "perl" : "5.006" } }, "develop" : { "requires" : { "Dist::Zilla" : "5", "Dist::Zilla::Plugin::Deprecated" : "0", "Dist::Zilla::Plugin::OSPrereqs" : "0", "Dist::Zilla::Plugin::RemovePrereqs" : "0", "Dist::Zilla::PluginBundle::DAGOLDEN" : "0.072", "File::Spec" : "0", "File::Temp" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "Pod::Coverage::TrustPod" : "0", "Pod::Wordlist" : "0", "Software::License::Perl_5" : "0", "Test::CPAN::Meta" : "0", "Test::MinimumVersion" : "0", "Test::More" : "0", "Test::Perl::Critic" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", "Test::Portability::Files" : "0", "Test::Spelling" : "0.12", "Test::Version" : "1", "perl" : "5.006" } }, "runtime" : { "requires" : { "Carp" : "0", "Exporter" : "0", "File::Basename" : "0", "File::Temp" : "0.16", "Symbol" : "0", "perl" : "5.006", "strict" : "0", "vars" : "0", "warnings" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "ExtUtils::MakeMaker" : "0", "File::Spec" : "3.27", "IO::File" : "0", "Test::More" : "0.62", "perl" : "5.006" } } }, "provides" : { "IO::CaptureOutput" : { "file" : "lib/IO/CaptureOutput.pm", "version" : "1.1105" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/dagolden/IO-CaptureOutput/issues" }, "homepage" : "https://github.com/dagolden/IO-CaptureOutput", "repository" : { "type" : "git", "url" : "https://github.com/dagolden/IO-CaptureOutput.git", "web" : "https://github.com/dagolden/IO-CaptureOutput" } }, "version" : "1.1105", "x_authority" : "cpan:DAGOLDEN", "x_contributors" : [ "David Golden ", "Jos\u00e9 Joaqu\u00edn Atria ", "Mike Latimer ", "Olivier Mengu\u00e9 ", "Tony Cook " ], "x_deprecated" : 1, "x_generated_by_perl" : "v5.30.0", "x_serialization_backend" : "Cpanel::JSON::XS version 4.15" } IO-CaptureOutput-1.1105/dist.ini000644 000766 000024 00000000441 13554665671 016652 0ustar00davidstaff000000 000000 name = IO-CaptureOutput author = Simon Flack author = David Golden license = Perl_5 copyright_holder = Simon Flack and David Golden [@DAGOLDEN] :version = 0.072 [RemovePrereqs] remove = Win32 [OSPrereqs / MSWin32] File::Spec = 3.27 [Deprecated] IO-CaptureOutput-1.1105/lib/IO/000755 000766 000024 00000000000 13554665671 016264 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/lib/IO/CaptureOutput.pm000644 000766 000024 00000033637 13554665671 021462 0ustar00davidstaff000000 000000 use strict; use warnings; package IO::CaptureOutput; # ABSTRACT: (DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS our $VERSION = '1.1105'; use vars qw/@ISA @EXPORT_OK %EXPORT_TAGS $CarpLevel/; use Exporter; use Carp qw/croak/; @ISA = 'Exporter'; @EXPORT_OK = qw/capture capture_exec qxx capture_exec_combined qxy/; %EXPORT_TAGS = (all => \@EXPORT_OK); $CarpLevel = 0; # help capture report errors at the right level sub _capture (&@) { ## no critic my ($code, $output, $error, $output_file, $error_file) = @_; # check for valid combinations of input { local $Carp::CarpLevel = 1; my $error = _validate($output, $error, $output_file, $error_file); croak $error if $error; } # if either $output or $error are defined, then we need a variable for # results; otherwise we only capture to files and don't waste memory if ( defined $output || defined $error ) { for ($output, $error) { $_ = \do { my $s; $s = ''} unless ref $_; $$_ = '' if $_ != \undef && !defined($$_); } } # merge if same refs for $output and $error or if both are undef -- # i.e. capture \&foo, undef, undef, $merged_file # this means capturing into separate files *requires* at least one # capture variable my $should_merge = (defined $error && defined $output && $output == $error) || ( !defined $output && !defined $error ) || 0; my ($capture_out, $capture_err); # undef means capture anonymously; anything other than \undef means # capture to that ref; \undef means skip capture if ( !defined $output || $output != \undef ) { $capture_out = IO::CaptureOutput::_proxy->new( 'STDOUT', $output, undef, $output_file ); } if ( !defined $error || $error != \undef ) { $capture_err = IO::CaptureOutput::_proxy->new( 'STDERR', $error, ($should_merge ? 'STDOUT' : undef), $error_file ); } # now that output capture is setup, call the subroutine # results get read when IO::CaptureOutput::_proxy objects go out of scope &$code(); } # Extra indirection for symmetry with capture_exec, etc. Gets error reporting # to the right level sub capture (&@) { ## no critic return &_capture; } sub capture_exec { my @args = @_; my ($output, $error); my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$error; my $success = ($exit == 0 ) ? 1 : 0 ; $? = $exit; return wantarray ? ($output, $error, $success, $exit) : $output; } *qxx = \&capture_exec; sub capture_exec_combined { my @args = @_; my $output; my $exit = _capture sub { system _shell_quote(@args) }, \$output, \$output; my $success = ($exit == 0 ) ? 1 : 0 ; $? = $exit; return wantarray ? ($output, $success, $exit) : $output; } *qxy = \&capture_exec_combined; # extra quoting required on Win32 systems *_shell_quote = ($^O =~ /MSWin32/) ? \&_shell_quote_win32 : sub {@_}; sub _shell_quote_win32 { my @args; for (@_) { if (/[ \"]/) { # TODO: check if ^ requires escaping (my $escaped = $_) =~ s/([\"])/\\$1/g; push @args, '"' . $escaped . '"'; next; } push @args, $_ } return @args; } # detect errors and return an error message or empty string; sub _validate { my ($output, $error, $output_file, $error_file) = @_; # default to "ok" my $msg = q{}; # \$out, \$out, $outfile, $errfile if ( defined $output && defined $error && defined $output_file && defined $error_file && $output == $error && $output != \undef && $output_file ne $error_file ) { $msg = "Merged STDOUT and STDERR, but specified different output and error files"; } # undef, undef, $outfile, $errfile elsif ( !defined $output && !defined $error && defined $output_file && defined $error_file && $output_file ne $error_file ) { $msg = "Merged STDOUT and STDERR, but specified different output and error files"; } return $msg; } # Captures everything printed to a filehandle for the lifetime of the object # and then transfers it to a scalar reference package IO::CaptureOutput::_proxy; use File::Temp 0.16 'tempfile'; use File::Basename qw/basename/; use Symbol qw/gensym qualify qualify_to_ref/; use Carp; sub _is_wperl { $^O eq 'MSWin32' && basename($^X) eq 'wperl.exe' } sub new { my $class = shift; my ($orig_fh, $capture_var, $merge_fh, $capture_file) = @_; $orig_fh = qualify($orig_fh); # e.g. main::STDOUT my $fhref = qualify_to_ref($orig_fh); # e.g. \*STDOUT # Duplicate the filehandle my $saved_fh; { no strict 'refs'; ## no critic - needed for 5.005 if ( defined fileno($orig_fh) && ! _is_wperl() ) { $saved_fh = gensym; open $saved_fh, ">&$orig_fh" or croak "Can't redirect <$orig_fh> - $!"; } } # Create replacement filehandle if not merging my ($newio_fh, $newio_file); if ( ! $merge_fh ) { $newio_fh = gensym; if ($capture_file) { $newio_file = $capture_file; } else { (undef, $newio_file) = tempfile; } open $newio_fh, "+>$newio_file" or croak "Can't write temp file for $orig_fh - $!"; } else { $newio_fh = qualify($merge_fh); } # Redirect (or merge) { no strict 'refs'; ## no critic -- needed for 5.005 open $fhref, ">&".fileno($newio_fh) or croak "Can't redirect $orig_fh - $!"; } bless [$$, $orig_fh, $saved_fh, $capture_var, $newio_fh, $newio_file, $capture_file], $class; } sub DESTROY { my $self = shift; my ($pid, $orig_fh, $saved_fh, $capture_var, $newio_fh, $newio_file, $capture_file) = @$self; return unless $pid eq $$; # only cleanup in the process that is capturing # restore the original filehandle my $fh_ref = Symbol::qualify_to_ref($orig_fh); select((select ($fh_ref), $|=1)[0]); if (defined $saved_fh) { open $fh_ref, ">&". fileno($saved_fh) or croak "Can't restore $orig_fh - $!"; } else { close $fh_ref; } # transfer captured data to the scalar reference if we didn't merge # $newio_file is undef if this file handle is merged to another if (ref $capture_var && $newio_file) { # some versions of perl complain about reading from fd 1 or 2 # which could happen if STDOUT and STDERR were closed when $newio # was opened, so we just squelch warnings here and continue local $^W; seek $newio_fh, 0, 0; $$capture_var = do {local $/; <$newio_fh>}; } close $newio_fh if $newio_file; # Cleanup return unless defined $newio_file && -e $newio_file; return if $capture_file; # the "temp" file was explicitly named unlink $newio_file or carp "Couldn't remove temp file '$newio_file' - $!"; } 1; __END__ =pod =encoding UTF-8 =head1 NAME IO::CaptureOutput - (DEPRECATED) capture STDOUT and STDERR from Perl code, subprocesses or XS =head1 VERSION version 1.1105 =head1 SYNOPSIS use IO::CaptureOutput qw(capture qxx qxy); # STDOUT and STDERR separately capture { noisy_sub(@args) } \$stdout, \$stderr; # STDOUT and STDERR together capture { noisy_sub(@args) } \$combined, \$combined; # STDOUT and STDERR from external command ($stdout, $stderr, $success) = qxx( @cmd ); # STDOUT and STDERR together from external command ($combined, $success) = qxy( @cmd ); =head1 DESCRIPTION B - see L instead. This module provides routines for capturing STDOUT and STDERR from perl subroutines, forked system calls (e.g. C, C) and from XS or C modules. =head1 NAME =head1 FUNCTIONS The following functions will be exported on demand. =head2 capture() capture \&subroutine, \$stdout, \$stderr; Captures everything printed to C and C for the duration of C<&subroutine>. C<$stdout> and C<$stderr> are optional scalars that will contain C and C respectively. C uses a code prototype so the first argument can be specified directly within brackets if desired. # shorthand with prototype capture C< print __PACKAGE__ > \$stdout, \$stderr; Returns the return value(s) of C<&subroutine>. The sub is called in the same context as C was called e.g.: @rv = capture C< wantarray > ; # returns true $rv = capture C< wantarray > ; # returns defined, but not true capture C< wantarray >; # void, returns undef C is able to capture output from subprocesses and C code, which traditional C methods of output capture are unable to do. B C will only capture output that has been written or flushed to the filehandle. If the two scalar references refer to the same scalar, then C will be merged to C before capturing and the scalar will hold the combined output of both. capture \&subroutine, \$combined, \$combined; Normally, C uses anonymous, temporary files for capturing output. If desired, specific file names may be provided instead as additional options. capture \&subroutine, \$stdout, \$stderr, $out_file, $err_file; Files provided will be clobbered, overwriting any previous data, but will persist after the call to C for inspection or other manipulation. By default, when no references are provided to hold STDOUT or STDERR, output is captured and silently discarded. # Capture STDOUT, discard STDERR capture \&subroutine, \$stdout; # Discard STDOUT, capture STDERR capture \&subroutine, undef, \$stderr; However, even when using C, output can be captured to specific files. # Capture STDOUT to a specific file, discard STDERR capture \&subroutine, \$stdout, undef, $outfile; # Discard STDOUT, capture STDERR to a specific file capture \&subroutine, undef, \$stderr, undef, $err_file; # Discard both, capture merged output to a specific file capture \&subroutine, undef, undef, $mergedfile; It is a fatal error to merge STDOUT and STDERR and request separate, specific files for capture. # ERROR: capture \&subroutine, \$stdout, \$stdout, $out_file, $err_file; capture \&subroutine, undef, undef, $out_file, $err_file; If either STDOUT or STDERR should be passed through to the terminal instead of captured, provide a reference to undef -- C<\undef> -- instead of a capture variable. # Capture STDOUT, display STDERR capture \&subroutine, \$stdout, \undef; # Display STDOUT, capture STDERR capture \&subroutine, \undef, \$stderr; =head2 capture_exec() ($stdout, $stderr, $success, $exit_code) = capture_exec(@args); Captures and returns the output from C. In scalar context, C will return what was printed to C. In list context, it returns what was printed to C and C as well as a success flag and the exit value. $stdout = capture_exec('perl', '-e', 'print "hello world"'); ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test"'); C passes its arguments to C and on MSWin32 will protect arguments with shell quotes if necessary. This makes it a handy and slightly more portable alternative to backticks, piped C and C. The C<$success> flag returned will be true if the command ran successfully and false if it did not (if the command could not be run or if it ran and returned a non-zero exit value). On failure, the raw exit value of the C call is available both in the C<$exit_code> returned and in the C<$?> variable. ($stdout, $stderr, $success, $exit_code) = capture_exec('perl', '-e', 'warn "Test" and exit 1'); if ( ! $success ) { print "The exit code was " . ($exit_code >> 8) . "\n"; } See L for more information on interpreting a child process exit code. =head2 capture_exec_combined() ($combined, $success, $exit_code) = capture_exec_combined( 'perl', '-e', 'print "hello\n"', 'warn "Test\n" ); This is just like C, except that it merges C with C before capturing output. B there is no guarantee that text printed to C and C in the subprocess will be appear in order. The actual order will depend on how IO buffering is handled in the subprocess. =head2 qxx() This is an alias for C. =head2 qxy() This is an alias for C. =head1 SEE ALSO =over 4 =item * L =item * L =item * L =item * L =item * L =back =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan =head1 SUPPORT =head2 Bugs / Feature Requests Please report any bugs or feature requests through the issue tracker at L. You will be notified automatically of any progress on your issue. =head2 Source Code This is open source software. The code repository is available for public review and contribution under the terms of the license. L git clone https://github.com/dagolden/IO-CaptureOutput.git =head1 AUTHORS =over 4 =item * Simon Flack =item * David Golden =back =head1 CONTRIBUTORS =for stopwords David Golden José Joaquín Atria Mike Latimer Olivier Mengué Tony Cook =over 4 =item * David Golden =item * José Joaquín Atria =item * Mike Latimer =item * Olivier Mengué =item * Tony Cook =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2019 by Simon Flack and David Golden. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut IO-CaptureOutput-1.1105/examples/capture.pl000755 000766 000024 00000000421 13554665671 021025 0ustar00davidstaff000000 000000 use strict; use warnings; use IO::CaptureOutput qw/capture/; my ($stdout, $stderr); capture sub { print "This prints to STDOUT\n"; print STDERR "This prints to STDERR\n"; } => \$stdout, \$stderr; print "STDOUT was:\n$stdout\n"; print "STDERR was:\n$stderr\n"; IO-CaptureOutput-1.1105/xt/author/000755 000766 000024 00000000000 13554665671 017144 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/xt/release/000755 000766 000024 00000000000 13554665671 017262 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/xt/release/distmeta.t000644 000766 000024 00000000172 13554665671 021261 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::MetaTests. use Test::CPAN::Meta; meta_yaml_ok(); IO-CaptureOutput-1.1105/xt/author/critic.t000644 000766 000024 00000000201 13554665671 020577 0ustar00davidstaff000000 000000 #!perl use strict; use warnings; use Test::Perl::Critic (-profile => "perlcritic.rc") x!! -e "perlcritic.rc"; all_critic_ok(); IO-CaptureOutput-1.1105/xt/author/minimum-version.t000644 000766 000024 00000000152 13554665671 022465 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; use Test::MinimumVersion; all_minimum_version_ok( qq{5.010} ); IO-CaptureOutput-1.1105/xt/author/test-version.t000644 000766 000024 00000000637 13554665671 022001 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::Version 1.09 use Test::Version; my @imports = qw( version_all_ok ); my $params = { is_strict => 0, has_version => 1, multiple => 0, }; push @imports, $params if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); Test::Version->import(@imports); version_all_ok; done_testing; IO-CaptureOutput-1.1105/xt/author/00-compile.t000644 000766 000024 00000002665 13554665671 021207 0ustar00davidstaff000000 000000 use 5.006; use strict; use warnings; # this test was generated with Dist::Zilla::Plugin::Test::Compile 2.058 use Test::More; plan tests => 2; my @module_files = ( 'IO/CaptureOutput.pm' ); # fake home for cpan-testers use File::Temp; local $ENV{HOME} = File::Temp::tempdir( CLEANUP => 1 ); my @switches = ( -d 'blib' ? '-Mblib' : '-Ilib', ); use File::Spec; use IPC::Open3; use IO::Handle; open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!"; my @warnings; for my $lib (@module_files) { # see L my $stderr = IO::Handle->new; diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} } $^X, @switches, '-e', "require q[$lib]")) if $ENV{PERL_COMPILE_TEST_DEBUG}; my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-e', "require q[$lib]"); binmode $stderr, ':crlf' if $^O eq 'MSWin32'; my @_warnings = <$stderr>; waitpid($pid, 0); is($?, 0, "$lib loaded ok"); shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/ and not eval { +require blib; blib->VERSION('1.01') }; if (@_warnings) { warn @_warnings; push @warnings, @_warnings; } } is(scalar(@warnings), 0, 'no warnings found') or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ); IO-CaptureOutput-1.1105/xt/author/pod-syntax.t000644 000766 000024 00000000252 13554665671 021436 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. use strict; use warnings; use Test::More; use Test::Pod 1.41; all_pod_files_ok(); IO-CaptureOutput-1.1105/xt/author/portability.t000644 000766 000024 00000000322 13554665671 021670 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; eval 'use Test::Portability::Files'; plan skip_all => 'Test::Portability::Files required for testing portability' if $@; options(test_one_dot => 0); run_tests(); IO-CaptureOutput-1.1105/xt/author/pod-spell.t000644 000766 000024 00000000605 13554665671 021231 0ustar00davidstaff000000 000000 use strict; use warnings; use Test::More; # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007005 use Test::Spelling 0.12; use Pod::Wordlist; add_stopwords(); all_pod_files_spelling_ok( qw( bin lib ) ); __DATA__ Atria CaptureOutput Cook David Flack Golden IO Joaquín José Latimer Mengué Mike Olivier Simon Tony and dagolden dolmen jjatria lib mlatimer simonflk tony xdg IO-CaptureOutput-1.1105/xt/author/pod-coverage.t000644 000766 000024 00000000334 13554665671 021704 0ustar00davidstaff000000 000000 #!perl # This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests. use Test::Pod::Coverage 1.08; use Pod::Coverage::TrustPod; all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); IO-CaptureOutput-1.1105/t/capture.t000755 000766 000024 00000011652 13554665671 017312 0ustar00davidstaff000000 000000 #!/usr/bin/perl -w #$Id: capture.t,v 1.3 2004/11/22 19:51:09 simonflack Exp $ use strict; use Test::More 0.62 tests => 21; use IO::CaptureOutput qw/capture/; use Config; my $is_cl = $Config{cc} =~ /cl/i; my ($out, $err, $out2, $err2); sub _reset { $_ = '' for ($out, $err, $out2, $err2); 1}; # Basic test _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err; is($out, __PACKAGE__, 'captured stdout from perl function'); is($err, __FILE__, 'captured stderr from perl function'); # merge STDOUT and STDERR _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$out; like($out, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'captured stdout into one scalar'); like($out, q{/} . quotemeta(__FILE__) . q{$/}, 'captured stderr into same scalar'); # nesting and passing ref to undef to get passthrough _reset && capture sub { capture sub { print __PACKAGE__; print STDERR __FILE__}, \undef, \$err2; }, \$out, \$err; like($out, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'stdout passed through to outer capture'); like($err2, q{/} . quotemeta(__FILE__) . q{$/}, 'captured stderr in inner'); is($err, q{}, 'outer stderr empty'); # repeat with error _reset && capture sub { capture sub { print __PACKAGE__; print STDERR __FILE__}, \$out2, \undef; }, \$out, \$err; like($out2, q{/^} . quotemeta(__PACKAGE__) . q{/}, 'captured stdout in inner'); like($err, q{/} . quotemeta(__FILE__) . q{$/}, 'stderr passed through to outer capture'); is($out, q{}, 'outer stdout empty'); # Check we still get return values _reset; my @arg = capture sub {print 'Testing'; return (1,2,3)}, \$out, \$err; ok($out eq 'Testing' && eq_array(\@arg, [1,2,3]), 'capture() proxies the return values'); # Check that the captured sub is called in the right context my $context = capture sub {wantarray}; ok(defined $context && ! $context, 'capture() calls subroutine in scalar context when appropriate'); ($context) = capture sub {wantarray}; ok($context, 'capture() calls subroutine in list context when appropriate'); capture sub {$context = wantarray}; ok(! defined($context), 'capture() calls subroutine in void context when appropriate'); # Test external program, see t/capture_exec.t for more _reset; capture sub {system($^X, '-V:osname')}, \$out; like($out, "/$^O/", 'capture() caught stdout from external command'); # check we still get stdout/stderr if the code dies eval { capture sub {print "."; print STDERR "5..4..3..2..1.."; die "self-terminating"}, \$out,\$err; }; like($@, "/^self-terminating at " . quotemeta(__FILE__) . "/", '$@ still available after capture'); ok($out eq '.' && $err eq '5..4..3..2..1..', 'capture() still populates output and error variables if the code dies'); SKIP: { my $can_fork = $Config{d_fork} || $Config{d_pseudofork} || ( $^O eq "MSWin32" && $Config{useithreads} && $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS\b/ ); skip "fork not available", 1 unless $can_fork; # test fork() sub forked_output { fork or do { print "forked"; print STDERR "Child pid $$"; exit; }; select undef, undef, undef, 0.2; } capture \&forked_output, \$out, \$err; ok($out eq 'forked' && $err =~ /^Child pid /, 'capture() traps fork() output'); } # Test printing via C code SKIP: { eval "require Inline::C"; skip "Inline::C not available", 3 if $@; eval { my $c_code = do {local $/; }; # Inline->bind( 'C' => $c_code, FORCE_BUILD => 1, BUILD_NOISY => 1 ); Inline->bind( 'C' => $c_code, FORCE_BUILD => 1); }; skip "Inline->bind failed : $@", 3 if $@; ok(test_inline_c(), 'Inline->bind succeeded'); _reset && capture sub { $is_cl ? cl_print_stdout("Hello World") : print_stdout("Hello World"); }, \$out, \$err; is($out, 'Hello World', 'captured stdout from C function'); _reset && capture sub { $is_cl ? cl_print_stderr("Testing stderr") : print_stderr("Testing stderr"); }, \$out, \$err; is($err, 'Testing stderr', 'captured stderr from C function'); } __DATA__ // A basic sub to test that the bind() succeeded #include int test_inline_c () { return 42; } // print to stdout -- regular void print_stdout (char* text) { printf("%s", text); fflush(stdout); } // print to stdout -- for MSVC void cl_print_stdout (const char *template, ... ) { va_list ap; va_start( ap, template ); vfprintf( stdout, template, ap ); va_end( ap ); fflush(stdout); } // print to stdout -- regular void print_stderr (char* text) { fprintf(stderr, "%s", text); fflush(stderr); } // print to stderr -- for MSVC // avoiding fprintf because of segfaults on MSWin32 with some versions of // ActiveState and some combinations of MSVC compiler void cl_print_stderr (const char *template, ... ) { va_list ap; va_start( ap, template ); vfprintf( stderr, template, ap ); va_end( ap ); fflush(stderr); } IO-CaptureOutput-1.1105/t/noconsole.t000644 000766 000024 00000003322 13554665671 017636 0ustar00davidstaff000000 000000 use strict; use Symbol qw/gensym/; my ($save_out, $save_err); BEGIN { $save_out = gensym(); $save_err = gensym(); open $save_out, ">&main::STDOUT"; open $save_err, ">&main::STDERR"; } use Test::More tests => 7; #--------------------------------------------------------------------------# # close and restore console #--------------------------------------------------------------------------# sub _close_console { close STDOUT or die "Can't close STDOUT"; close STDERR or die "Can't close STDERR"; return; } sub _restore_console { open STDOUT, ">&" . fileno($save_out) or die "Can't restore STDOUT"; open STDERR, ">&" . fileno($save_err) or die "Can't restore STDERR"; return; } #--------------------------------------------------------------------------# # _test_print #--------------------------------------------------------------------------# sub _test_print { print STDOUT "Test to STDOUT\n"; print STDERR "Test to STDERR\n"; return; } #--------------------------------------------------------------------------# my ($stdout, $stderr, $err); BEGIN{ use_ok("IO::CaptureOutput", "capture") } eval { capture \&_test_print, \$stdout, \$stderr; }; $err = $@; is( $err, q{}, "no errors capturing with console open" ); is( $stdout, "Test to STDOUT\n", "STDOUT test with console open" ); is( $stderr, "Test to STDERR\n", "STDERR test with console open" ); $stdout = $stderr = q{}; _close_console; eval { capture \&_test_print, \$stdout, \$stderr; }; $err = $@; _restore_console; is( $err, q{}, "no errors capturing with console closed" ); is( $stdout, "Test to STDOUT\n", "STDOUT test with console closed" ); is( $stderr, "Test to STDERR\n", "STDERR test with console closed" ); IO-CaptureOutput-1.1105/t/capture_file.t000644 000766 000024 00000011104 13554665671 020276 0ustar00davidstaff000000 000000 use strict; use Test::More; use IO::CaptureOutput qw/capture/; use File::Temp qw/tempfile/; use Config; plan tests => 30; my ($out, $err); sub _reset { $_ = '' for ($out, $err); 1}; sub _readf { return undef unless -r "$_[0]"; local $/; open FF, "< $_[0]"; my $c = ; close FF; return $c } sub _touch { open FF, "> $_[0]"; close FF } # save output to specified files (undef, my $saved_out) = tempfile; unlink $saved_out; (undef, my $saved_err) = tempfile; unlink $saved_err; _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, $saved_out, $saved_err; is($out, __PACKAGE__, 'save both: captured stdout from perl function 2'); is($err, __FILE__, 'save both: captured stderr from perl function 2'); ok(-s $saved_out, "save both: saved stdout file contains something"); ok(-s $saved_err, "save both: saved stderr file contains something"); is(_readf($saved_out), __PACKAGE__, 'saved both: saved stdout file content ok'); is(_readf($saved_err), __FILE__, 'saved both: saved stderr file content ok'); # confirm that files are clobbered _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, $saved_out, $saved_err; ok(-s $saved_out, "clobber: saved stdout file contains something"); ok(-s $saved_err, "clobber: saved stderr file contains something"); is(_readf($saved_out), __PACKAGE__, 'clobber: stdout file correct'); is(_readf($saved_err), __FILE__, 'clobber: stderr correct:'); # save only stderr unlink $saved_out, $saved_err; _reset && capture sub {print __PACKAGE__; print STDERR __FILE__}, \$out, \$err, undef, $saved_err; ok(!-e $saved_out, "only stderr: stdout file does not exist"); ok(-s $saved_err, "only stderr: file contains something"); is(_readf($saved_err), __FILE__, 'only stdout: stderr file'); # check that the merged stdout and stderr are saved where they should unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$out, $saved_out; like($out, q{/^} . quotemeta(__FILE__) . q{/}, 'merge: captured stdout into one scalar 2'); like($out, q{/} . quotemeta(__PACKAGE__) . q{/}, 'merge: captured stderr into same scalar 2'); ok(-s $saved_out, "merge: saved stdout file contains something"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'merge: saved merged file stdout content ok'); like(_readf($saved_out), q{/} . quotemeta(__PACKAGE__) . q{/}, 'merge: saved merged file stderr content ok'); # capture only stdout to a file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, undef, $saved_out; ok(-s $saved_out, "fileonly stdout: saved stdout file contains something"); ok(!-e $saved_err, "fileonly stdout: saved stderr file does not exist"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'fileonly stdout: saved merged file stdout content ok'); # capture only stderr to a file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, undef, \$err, undef, $saved_err; ok(!-e $saved_out, "fileonly stderr: saved stdout file does not exist"); ok(-s $saved_err, "fileonly stderr: saved stderr file contains something"); like(_readf($saved_err), q{/} . quotemeta(__PACKAGE__) . q{/}, 'fileonly stderr: undef, undef file stderr content ok'); # don't capture merged to scalar, only to file unlink $saved_out, $saved_err; _reset && capture sub {print __FILE__; print STDERR __PACKAGE__}, undef, undef, $saved_out; ok(-s $saved_out, "fileonly merge: saved stdout file contains something"); ok(!-e $saved_err, "fileonly merge: saved stderr file does not exist"); like(_readf($saved_out), q{/^} . quotemeta(__FILE__) . q{/}, 'fileonly merge: file stdout content ok'); like(_readf($saved_out), q{/} . quotemeta(__PACKAGE__) . q{/}, 'fileonly merge: file stderr content ok'); # confirm error handling on read-only files _touch($_) for ($saved_out, $saved_err); chmod 0444, $saved_out, $saved_err; SKIP: { skip "Can't make temp files read-only to test error handling", 2 if ( -w $saved_out || -w $saved_err ); eval { capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$err, $saved_out }; like( $@, q{/Can't write temp file for main::STDOUT/}, "error handling: can't write to stdout file" ); eval { capture sub {print __FILE__; print STDERR __PACKAGE__}, \$out, \$err, undef, $saved_err }; like( $@, q{/Can't write temp file for main::STDERR/}, "error handling: can't write to stderr file" ); } # restore permissions chmod 0666, $saved_out, $saved_err; unlink $saved_out, $saved_err; IO-CaptureOutput-1.1105/t/errors.t000644 000766 000024 00000002252 13554665671 017154 0ustar00davidstaff000000 000000 use strict; use Test::More; use IO::CaptureOutput qw/capture/; use File::Temp qw/tempfile/; use Config; # save output to specified files my ($out, $err); (undef, my $saved_out) = tempfile; unlink $saved_out; (undef, my $saved_err) = tempfile; unlink $saved_err; sub _reset { $_ = '' for ($out, $err); 1}; sub _print_stuff { print __PACKAGE__; print STDERR __FILE__} my @valid_args = ( q[ ], q[ \$out ], q[ undef, \$err ], q[ \$out, \$err ], q[ \$out, \$out ], q[ undef, undef ], q[ \$out, undef, $saved_out ], q[ \$out, undef, $saved_out, $saved_err ], q[ undef, \$err, undef, $saved_err ], q[ undef, \$err, $saved_out, $saved_err ], q[ \$out, \$err, $saved_out, $saved_err ], q[ \$out, \$out, $saved_out, $saved_out ], q[ undef, undef, $saved_out, $saved_out ], ); my @invalid_args = ( q[ \$out, \$out, $saved_out, $saved_err ], q[ undef, undef, $saved_out, $saved_err ], ); plan tests => @valid_args + @invalid_args; for my $arg ( @valid_args ) { _reset; eval "capture { _print_stuff() } $arg"; is( $@, q{}, "no error: '$arg'" ); } for my $arg ( @invalid_args ) { _reset; eval "capture { _print_stuff() } $arg"; ok( $@, "error: '$arg'" ); } IO-CaptureOutput-1.1105/t/capture_exec.t000755 000766 000024 00000007132 13554665671 020314 0ustar00davidstaff000000 000000 #!/usr/bin/perl -w use strict; use Test::More; plan tests => 31; use IO::CaptureOutput qw/capture_exec capture_exec_combined qxx qxy/; my ($out, $err, $suc, $ec); my @perl_e = ($^X, '-e'); # perl -e sub _reset { $_ = '' for ($out, $err); undef $suc; undef $ec; 1}; # low-level debugging #print capture_exec($^X, '-e', 'print join "|", @ARGV'), "\n"; #print join '|', IO::CaptureOutput::_shell_quote($^X, '-e', 'print join "|", @ARGV'), "\n"; # simple test ($out, $err, $suc, $ec) = capture_exec(@perl_e, q[print 'Hello World!'; print STDERR "PID=$$"]); is($out, 'Hello World!', 'capture_exec() caught stdout from external command'); like($err, '/PID=\d+/', 'capture_exec() caught stderr from external command'); ok($suc, 'capture_exec() returned success'); is($ec >> 8, 0, 'capture_exec() exit value'); # with alias _reset; ($out, $err, $suc, $ec) = qxx(@perl_e, q[print 'Hello World!'; print STDERR "PID=$$"]); is($out, 'Hello World!', 'capture_exec() caught stdout from external command'); like($err, '/PID=\d+/', 'capture_exec() caught stderr from external command'); ok($suc, 'capture_exec() returned success'); is($ec >> 8, 0, 'capture_exec() exit value'); # check exit code of system() _reset; ($out, $err, $suc, $ec) = capture_exec(@perl_e, 'print "ok"'); ok($out eq 'ok' && $? == 0, '$? set to 0 after successful execution'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); _reset; ($out, $err, $suc, $ec) = capture_exec(@perl_e, 'exit 5'); is($? >> 8, 5, '$? contains child error after failed execution'); ok(!$suc, 'returned success flag correct on exit N'); is($ec >> 8, 5, 'returned exit value correct on exit N'); # check that output is returned if called in scalar context _reset; $out = capture_exec(@perl_e, 'print "stdout"; print STDERR "stderr"'); is($out, 'stdout', 'capture_exec() returns stdout in scalar context'); # merge STDOUT and STDERR _reset; ($out, $suc, $ec) = capture_exec_combined(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); # with alias _reset; ($out, $suc, $ec) = qxy(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); # check exit code of system() _reset; ($out, $suc, $ec) = qxy(@perl_e, 'print "ok"'); ok($out eq 'ok' && $? == 0, '$? set to 0 after successful execution'); ok($suc, 'returned success flag correct on exit 0'); is($ec >> 8, 0, 'returned exit value correct on exit 0'); _reset; ($out, $suc, $ec) = qxy(@perl_e, 'exit 5'); is($? >> 8, 5, '$? contains child error after failed execution'); ok(!$suc, 'returned success flag correct on exit N'); is($ec >> 8, 5, 'returned exit value correct on exit N'); # merge STDOUT and STDERR _reset; $out = capture_exec_combined(@perl_e, q[select STDERR; $|++; select STDOUT; $|++; print "Hello World!\n"; print STDERR "PID=$$\n"]); like($out, '/Hello World!/', 'capture_exec_combined() caught stdout from external command'); like($out, '/PID=\d+/', 'capture_exec_combined() caught stderr from external command'); IO-CaptureOutput-1.1105/t/scripts/000755 000766 000024 00000000000 13554665671 017141 5ustar00davidstaff000000 000000 IO-CaptureOutput-1.1105/t/00-report-prereqs.t000644 000766 000024 00000013426 13554665671 021054 0ustar00davidstaff000000 000000 #!perl use strict; use warnings; # This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.027 use Test::More tests => 1; use ExtUtils::MakeMaker; use File::Spec; # from $version::LAX my $lax_version_re = qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )? | (?:\.[0-9]+) (?:_[0-9]+)? ) | (?: v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )? | (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)? ) )/x; # hide optional CPAN::Meta modules from prereq scanner # and check if they are available my $cpan_meta = "CPAN::Meta"; my $cpan_meta_pre = "CPAN::Meta::Prereqs"; my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic # Verify requirements? my $DO_VERIFY_PREREQS = 1; sub _max { my $max = shift; $max = ( $_ > $max ) ? $_ : $max for @_; return $max; } sub _merge_prereqs { my ($collector, $prereqs) = @_; # CPAN::Meta::Prereqs object if (ref $collector eq $cpan_meta_pre) { return $collector->with_merged_prereqs( CPAN::Meta::Prereqs->new( $prereqs ) ); } # Raw hashrefs for my $phase ( keys %$prereqs ) { for my $type ( keys %{ $prereqs->{$phase} } ) { for my $module ( keys %{ $prereqs->{$phase}{$type} } ) { $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module}; } } } return $collector; } my @include = qw( ); my @exclude = qw( ); # Add static prereqs to the included modules list my $static_prereqs = do './t/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ), $static_prereqs ); # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; my $cpan_meta_error; if ( $source && $HAS_CPAN_META && (my $meta = eval { CPAN::Meta->load_file($source) } ) ) { $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } else { $cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source) $source = 'static metadata'; } my @full_reports; my @dep_errors; my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs; # Add static includes into a fake section for my $mod (@include) { $req_hash->{other}{modules}{$mod} = 0; } for my $phase ( qw(configure build test runtime develop other) ) { next unless $req_hash->{$phase}; next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING}); for my $type ( qw(requires recommends suggests conflicts modules) ) { next unless $req_hash->{$phase}{$type}; my $title = ucfirst($phase).' '.ucfirst($type); my @reports = [qw/Module Want Have/]; for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) { next if $mod eq 'perl'; next if grep { $_ eq $mod } @exclude; my $file = $mod; $file =~ s{::}{/}g; $file .= ".pm"; my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC; my $want = $req_hash->{$phase}{$type}{$mod}; $want = "undef" unless defined $want; $want = "any" if !$want && $want == 0; my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required"; if ($prefix) { my $have = MM->parse_version( File::Spec->catfile($prefix, $file) ); $have = "undef" unless defined $have; push @reports, [$mod, $want, $have]; if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) { if ( $have !~ /\A$lax_version_re\z/ ) { push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)"; } elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) { push @dep_errors, "$mod version '$have' is not in required range '$want'"; } } } else { push @reports, [$mod, $want, "missing"]; if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) { push @dep_errors, "$mod is not installed ($req_string)"; } } } if ( @reports ) { push @full_reports, "=== $title ===\n\n"; my $ml = _max( map { length $_->[0] } @reports ); my $wl = _max( map { length $_->[1] } @reports ); my $hl = _max( map { length $_->[2] } @reports ); if ($type eq 'modules') { splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports; } else { splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl]; push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports; } push @full_reports, "\n"; } } } if ( @full_reports ) { diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } if ( $cpan_meta_error || @dep_errors ) { diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n"; } if ( $cpan_meta_error ) { my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n"; } if ( @dep_errors ) { diag join("\n", "\nThe following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); } pass; # vim: ts=4 sts=4 sw=4 et: IO-CaptureOutput-1.1105/t/wperl.t000644 000766 000024 00000002767 13554665671 017004 0ustar00davidstaff000000 000000 use strict; use IO::File; use File::Temp 0.16 (); use Test::More; if ( $^O ne 'MSWin32' ) { plan skip_all => "not MSWin32"; } else { require File::Spec; File::Spec->VERSION(3.27); } ( my $wperl = $^X ) =~ s/perl\.exe$/wperl.exe/i; if ( ! -x $wperl ) { plan skip_all => "no wperl.exe found"; } sub _is_vista { require Win32; my (undef, $major, $minor, $build, $id) = Win32::GetOSVersion(); return $id == 2 && $major > 5; # 2 for NT, 6 is 2k/XP/Server 2003 } #--------------------------------------------------------------------------# # test scripts #--------------------------------------------------------------------------# my @scripts = qw( wperl-capture.pl wperl-exec.pl ); plan tests => 2 * @scripts; #--------------------------------------------------------------------------# # loop over scripts and pass a filename for output #--------------------------------------------------------------------------# for my $pl ( @scripts ) { TODO: { local $TODO = "wperl.exe can't capture child process output on Vista or Win7" if _is_vista() && $pl eq 'wperl-exec.pl'; my $pl_path = File::Spec->catfile('t', 'scripts', $pl); my $outputname = File::Temp->new(); $outputname->close; # avoid Win32 locking it read-only system($wperl, $pl_path, $outputname); is( $?, 0, "'$pl' no error"); my $result = IO::File->new( $outputname ); is_deeply( [ <$result> ], ["STDOUT\n", "STDERR\n"], "'$pl' capture correct" ); } } IO-CaptureOutput-1.1105/t/00-report-prereqs.dd000644 000766 000024 00000005770 13554665671 021203 0ustar00davidstaff000000 000000 do { my $x = { 'configure' => { 'requires' => { 'ExtUtils::MakeMaker' => '6.17', 'perl' => '5.006' } }, 'develop' => { 'requires' => { 'Dist::Zilla' => '5', 'Dist::Zilla::Plugin::Deprecated' => '0', 'Dist::Zilla::Plugin::OSPrereqs' => '0', 'Dist::Zilla::Plugin::RemovePrereqs' => '0', 'Dist::Zilla::PluginBundle::DAGOLDEN' => '0.072', 'File::Spec' => '0', 'File::Temp' => '0', 'IO::Handle' => '0', 'IPC::Open3' => '0', 'Pod::Coverage::TrustPod' => '0', 'Pod::Wordlist' => '0', 'Software::License::Perl_5' => '0', 'Test::CPAN::Meta' => '0', 'Test::MinimumVersion' => '0', 'Test::More' => '0', 'Test::Perl::Critic' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Portability::Files' => '0', 'Test::Spelling' => '0.12', 'Test::Version' => '1', 'perl' => '5.006' } }, 'runtime' => { 'requires' => { 'Carp' => '0', 'Exporter' => '0', 'File::Basename' => '0', 'File::Temp' => '0.16', 'Symbol' => '0', 'perl' => '5.006', 'strict' => '0', 'vars' => '0', 'warnings' => '0' } }, 'test' => { 'recommends' => { 'CPAN::Meta' => '2.120900' }, 'requires' => { 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '3.27', 'IO::File' => '0', 'Test::More' => '0.62', 'perl' => '5.006' } } }; $x; }IO-CaptureOutput-1.1105/t/scripts/wperl-exec.pl000644 000766 000024 00000000414 13554665671 021550 0ustar00davidstaff000000 000000 use strict; use IO::File; use IO::CaptureOutput qw/qxx/; my $output_file = shift @ARGV; my ($stdout, $stderr) = qxx($^X, '-e', 'print "STDOUT\n"; print STDERR "STDERR\n"'); my $fh = IO::File->new($output_file, ">"); print {$fh} $stdout, $stderr; $fh->close; IO-CaptureOutput-1.1105/t/scripts/wperl-capture.pl000644 000766 000024 00000000474 13554665671 022275 0ustar00davidstaff000000 000000 use strict; use IO::File; use IO::CaptureOutput qw/capture/; my $output_file = shift @ARGV; my ($stdout, $stderr) = (q{}, q{}); capture sub { print STDOUT "STDOUT\n"; print STDERR "STDERR\n"; } => \$stdout, \$stderr; my $fh = IO::File->new($output_file, ">"); print {$fh} $stdout, $stderr; $fh->close;