--- /dev/null
+## 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/
+
--- /dev/null
+Changes for File-chdir
+
+0.1011 2016-10-07 10:23:15-04:00 America/New_York
+
+ [Documentation]
+
+ - Fixed POD typos
+
+0.1010 2015-02-05 10:04:27-05:00 America/New_York
+
+ [Changed]
+
+ - Updated distribution metadata and repo layout
+
+ - Changed bugtracker to github
+
+0.1009 2014-09-23 12:24:11-04:00 America/New_York
+
+ [Changed]
+
+ - Updated distribution metadata
+
+0.1008 2012-12-02 22:32:37 America/New_York
+
+ - Fixed broken use of abs_path on Cygwin [Joel Berger]
+
+0.1007 2012-09-17 20:29:43 America/New_York
+
+ - Fixed broken Pod link; reordered CAVEATS section
+
+0.1006 2011-11-02 18:11:13 America/New_York
+
+ - Handle directories with newlines [rt.cpan.org #72114]
+
+0.1005 2011-11-02 14:21:27 America/New_York
+
+ - Fixed rt.cpan.org #53064 [Michael Schwern]
+
+ - Removes bundled Test::More
+
+ - Converted distribution builder to Dist::Zilla
+
+0.1004 Wed Jun 9 14:14:54 EDT 2010
+
+ - Build.Pl and Makefile.PL will bail out on Perl 5.13.1, which
+ accidentally broke File::chdir
+
+0.1003 Tue Apr 27 21:21:32 EDT 2010
+
+ - testfix: remove -T flag in tests
+
+0.1002 Mon Feb 11 19:47:46 EST 2008
+
+ - testfix: 0.1001 accidentally left many array tests commented out
+
+0.1001 Sat Feb 9 13:07:05 EST 2008
+
+ - testfix: work around odd Test::Builder errors on perl 5.6.2 dying in
+ the middle of a "push"
+
+0.10 Fri Feb 8 08:42:53 EST 2008
+ - File::Spec 3.2501 broke File::chdir on Win32; updated prerequisite to
+ latest File::Spec (3.27) and rewrote internals of File::chdir
+ - Split array deletion tests to separate file to skip on Perl < 5.006
+ - Added Build.PL and other files (e.g. INSTALL, LICENSE) to the tarball
+ - Minor documentation changes/additions
+
+0.0901
+ - removed unnecessary prototypes on internal functions (perl critic)
+ - cosmetic changes to distribution package (README, extra tests in xt)
+
+0.09 Mon Jul 30 09:50:28 EDT 2007
+ - Updated Makefile.PL to warn about API change in 0.08
+ - Added $! diagnostic to error messages
+
+0.08 Thu Jun 21 20:56:50 EDT 2007
+ * Croaks if the chdir fails when changing $CWD or @CWD
+ * Deleting from end of @CWD acts like a pop
+ - Revised and expanded @CWD tests
+ - Revised delete error message for deleting from middle of @CWD
+ - Added DIAGNOSTICS section to documentation
+
+0.07 Mon Jun 18 18:38:00 EDT 2007
+ - Fixed testfile bug that prepended "/" in tests on Cygwin
+
+0.06_01 Mon Apr 9 05:17:02 EDT 2007
+ - Development release by David Golden
+ * Fixed bug that prepended "/" to $CWD for Win32
+ * $CWD changed to use native path separators
+ * Tests fixed on Win32 by always using native separators as well
+ * Upped File::Spec and Cwd dependencies to require many recent bug-fixes
+ - Added note about comparing $CWD to File::Spec generated names
+ - Other minor documentation patches from Schwern
+
+0.06 Thu Aug 14 17:02:32 PDT 2003
+ * Now working under taint mode (thanks Mark Guckeyson)
+ - Small nit in the SYNOPSIS
+ * Removed dependency on File::Spec 0.8 and File::Spec::Functions
+ - Added a LICENSE
+ - Added NOTES about %CWD.
+
+0.05 Mon Nov 26 15:44:20 EST 2001
+ * Added @CWD
+ - $CWD's value now guaranteed to be correct even if some other code
+ calls chdir().
+
+0.04 Mon Nov 26 13:36:24 EST 2001 *UNRELEASED*
+ * The magic chdir() is *gone*
+ * Now works back to 5.004
+
+0.03 Mon Sep 3 20:10:15 EDT 2001
+ * chdir() is being deprecated and will be removed next version!
+ - Gave credit to Abigail and Bryan
+
+0.02 Mon Sep 3 19:51:02 EDT 2001
+ * Added $CWD
+ - chdir() with no args works
+
+0.01 Fri Aug 31 21:15:25 EDT 2001
+ * HA! It works!
+
--- /dev/null
+This software is copyright (c) 2016 by Michael G. Schwern 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) 2016 by Michael G. Schwern 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+--- The Artistic License 1.0 ---
+
+This software is Copyright (c) 2016 by Michael G. Schwern 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
+
--- /dev/null
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.008.
+CONTRIBUTING.mkdn
+Changes
+LICENSE
+MANIFEST
+META.json
+META.yml
+Makefile.PL
+README
+cpanfile
+dist.ini
+examples/chdir-example.pl
+lib/File/chdir.pm
+perlcritic.rc
+t/00-report-prereqs.dd
+t/00-report-prereqs.t
+t/array.t
+t/chdir.t
+t/delete-array.t
+t/lib/dummy.txt
+t/nested.t
+t/newline.t
+t/var.t
+xt/author/00-compile.t
+xt/author/critic.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
+xt/release/minimum-version.t
--- /dev/null
+{
+ "abstract" : "a more sensible way to change directories",
+ "author" : [
+ "David Golden <dagolden@cpan.org>",
+ "Michael G. Schwern <schwern@pobox.com>"
+ ],
+ "dynamic_config" : 0,
+ "generated_by" : "Dist::Zilla version 6.008, CPAN::Meta::Converter version 2.150010",
+ "license" : [
+ "perl_5"
+ ],
+ "meta-spec" : {
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "version" : 2
+ },
+ "name" : "File-chdir",
+ "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::PluginBundle::DAGOLDEN" : "0.072",
+ "English" : "0",
+ "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::More" : "0",
+ "Test::Pod" : "1.41",
+ "Test::Pod::Coverage" : "1.08",
+ "Test::Portability::Files" : "0",
+ "Test::Spelling" : "0.12",
+ "Test::Version" : "1",
+ "blib" : "1.01",
+ "perl" : "5.006",
+ "warnings" : "0"
+ }
+ },
+ "runtime" : {
+ "requires" : {
+ "Carp" : "0",
+ "Cwd" : "3.16",
+ "Exporter" : "0",
+ "File::Spec::Functions" : "3.27",
+ "perl" : "5.006",
+ "strict" : "0",
+ "vars" : "0"
+ }
+ },
+ "test" : {
+ "recommends" : {
+ "CPAN::Meta" : "2.120900"
+ },
+ "requires" : {
+ "ExtUtils::MakeMaker" : "0",
+ "File::Spec" : "0",
+ "Test::More" : "0",
+ "perl" : "5.006",
+ "warnings" : "0"
+ }
+ }
+ },
+ "provides" : {
+ "File::chdir" : {
+ "file" : "lib/File/chdir.pm",
+ "version" : "0.1011"
+ },
+ "File::chdir::ARRAY" : {
+ "file" : "lib/File/chdir.pm",
+ "version" : "0.1011"
+ },
+ "File::chdir::SCALAR" : {
+ "file" : "lib/File/chdir.pm",
+ "version" : "0.1011"
+ }
+ },
+ "release_status" : "stable",
+ "resources" : {
+ "bugtracker" : {
+ "web" : "https://github.com/dagolden/File-chdir/issues"
+ },
+ "homepage" : "https://github.com/dagolden/File-chdir",
+ "repository" : {
+ "type" : "git",
+ "url" : "https://github.com/dagolden/File-chdir.git",
+ "web" : "https://github.com/dagolden/File-chdir"
+ }
+ },
+ "version" : "0.1011",
+ "x_authority" : "cpan:DAGOLDEN",
+ "x_contributors" : [
+ "David Golden <xdg@xdg.me>",
+ "Joel Berger <joel.a.berger@gmail.com>",
+ "Philippe Bruhat (BooK) <book@cpan.org>"
+ ],
+ "x_serialization_backend" : "Cpanel::JSON::XS version 3.0213"
+}
+
--- /dev/null
+---
+abstract: 'a more sensible way to change directories'
+author:
+ - 'David Golden <dagolden@cpan.org>'
+ - 'Michael G. Schwern <schwern@pobox.com>'
+build_requires:
+ ExtUtils::MakeMaker: '0'
+ File::Spec: '0'
+ Test::More: '0'
+ perl: '5.006'
+ warnings: '0'
+configure_requires:
+ ExtUtils::MakeMaker: '6.17'
+ perl: '5.006'
+dynamic_config: 0
+generated_by: 'Dist::Zilla version 6.008, 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: File-chdir
+no_index:
+ directory:
+ - corpus
+ - examples
+ - t
+ - xt
+ package:
+ - DB
+provides:
+ File::chdir:
+ file: lib/File/chdir.pm
+ version: '0.1011'
+ File::chdir::ARRAY:
+ file: lib/File/chdir.pm
+ version: '0.1011'
+ File::chdir::SCALAR:
+ file: lib/File/chdir.pm
+ version: '0.1011'
+requires:
+ Carp: '0'
+ Cwd: '3.16'
+ Exporter: '0'
+ File::Spec::Functions: '3.27'
+ perl: '5.006'
+ strict: '0'
+ vars: '0'
+resources:
+ bugtracker: https://github.com/dagolden/File-chdir/issues
+ homepage: https://github.com/dagolden/File-chdir
+ repository: https://github.com/dagolden/File-chdir.git
+version: '0.1011'
+x_authority: cpan:DAGOLDEN
+x_contributors:
+ - 'David Golden <xdg@xdg.me>'
+ - 'Joel Berger <joel.a.berger@gmail.com>'
+ - 'Philippe Bruhat (BooK) <book@cpan.org>'
+x_serialization_backend: 'YAML::Tiny version 1.69'
--- /dev/null
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.008.
+use strict;
+use warnings;
+
+use 5.006;
+
+use ExtUtils::MakeMaker 6.17;
+
+my %WriteMakefileArgs = (
+ "ABSTRACT" => "a more sensible way to change directories",
+ "AUTHOR" => "David Golden <dagolden\@cpan.org>, Michael G. Schwern <schwern\@pobox.com>",
+ "CONFIGURE_REQUIRES" => {
+ "ExtUtils::MakeMaker" => "6.17"
+ },
+ "DISTNAME" => "File-chdir",
+ "LICENSE" => "perl",
+ "MIN_PERL_VERSION" => "5.006",
+ "NAME" => "File::chdir",
+ "PREREQ_PM" => {
+ "Carp" => 0,
+ "Cwd" => "3.16",
+ "Exporter" => 0,
+ "File::Spec::Functions" => "3.27",
+ "strict" => 0,
+ "vars" => 0
+ },
+ "TEST_REQUIRES" => {
+ "ExtUtils::MakeMaker" => 0,
+ "File::Spec" => 0,
+ "Test::More" => 0,
+ "warnings" => 0
+ },
+ "VERSION" => "0.1011",
+ "test" => {
+ "TESTS" => "t/*.t"
+ }
+);
+
+
+my %FallbackPrereqs = (
+ "Carp" => 0,
+ "Cwd" => "3.16",
+ "Exporter" => 0,
+ "ExtUtils::MakeMaker" => 0,
+ "File::Spec" => 0,
+ "File::Spec::Functions" => "3.27",
+ "Test::More" => 0,
+ "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) };
+
+WriteMakefile(%WriteMakefileArgs);
--- /dev/null
+NAME
+ File::chdir - a more sensible way to change directories
+
+VERSION
+ version 0.1011
+
+SYNOPSIS
+ use File::chdir;
+
+ $CWD = "/foo/bar"; # now in /foo/bar
+ {
+ local $CWD = "/moo/baz"; # now in /moo/baz
+ ...
+ }
+
+ # still in /foo/bar!
+
+DESCRIPTION
+ Perl's "chdir()" has the unfortunate problem of being very, very, very
+ global. If any part of your program calls "chdir()" or if any library
+ you use calls "chdir()", it changes the current working directory for
+ the *whole* program.
+
+ This sucks.
+
+ File::chdir gives you an alternative, $CWD and @CWD. These two variables
+ combine all the power of "chdir()", File::Spec and Cwd.
+
+$CWD
+ Use the $CWD variable instead of "chdir()" and Cwd.
+
+ use File::chdir;
+ $CWD = $dir; # just like chdir($dir)!
+ print $CWD; # prints the current working directory
+
+ It can be localized, and it does the right thing.
+
+ $CWD = "/foo"; # it's /foo out here.
+ {
+ local $CWD = "/bar"; # /bar in here
+ }
+ # still /foo out here!
+
+ $CWD always returns the absolute path in the native form for the
+ operating system.
+
+ $CWD and normal "chdir()" work together just fine.
+
+@CWD
+ @CWD represents the current working directory as an array, each
+ directory in the path is an element of the array. This can often make
+ the directory easier to manipulate, and you don't have to fumble with
+ "File::Spec->splitpath" and "File::Spec->catdir" to make portable code.
+
+ # Similar to chdir("/usr/local/src/perl")
+ @CWD = qw(usr local src perl);
+
+ pop, push, shift, unshift and splice all work. pop and push are probably
+ the most useful.
+
+ pop @CWD; # same as chdir(File::Spec->updir)
+ push @CWD, 'some_dir' # same as chdir('some_dir')
+
+ @CWD and $CWD both work fine together.
+
+ *NOTE* Due to a perl bug you can't localize @CWD. See "CAVEATS" for a
+ work around.
+
+EXAMPLES
+ (We omit the "use File::chdir" from these examples for terseness)
+
+ Here's $CWD instead of "chdir()":
+
+ $CWD = 'foo'; # chdir('foo')
+
+ and now instead of Cwd.
+
+ print $CWD; # use Cwd; print Cwd::abs_path
+
+ you can even do zsh style "cd foo bar"
+
+ $CWD = '/usr/local/foo';
+ $CWD =~ s/usr/var/;
+
+ if you want to localize that, make sure you get the parens right
+
+ {
+ (local $CWD) =~ s/usr/var/;
+ ...
+ }
+
+ It's most useful for writing polite subroutines which don't leave the
+ program in some strange directory:
+
+ sub foo {
+ local $CWD = 'some/other/dir';
+ ...do your work...
+ }
+
+ which is much simpler than the equivalent:
+
+ sub foo {
+ use Cwd;
+ my $orig_dir = Cwd::getcwd;
+ chdir('some/other/dir');
+
+ ...do your work...
+
+ chdir($orig_dir);
+ }
+
+ @CWD comes in handy when you want to start moving up and down the
+ directory hierarchy in a cross-platform manner without having to use
+ File::Spec.
+
+ pop @CWD; # chdir(File::Spec->updir);
+ push @CWD, 'some', 'dir' # chdir(File::Spec->catdir(qw(some dir)));
+
+ You can easily change your parent directory:
+
+ # chdir from /some/dir/bar/moo to /some/dir/foo/moo
+ $CWD[-2] = 'foo';
+
+CAVEATS
+ "local @CWD" does not work.
+ "local @CWD" will not localize @CWD. This is a bug in Perl, you can't
+ localize tied arrays. As a work around localizing $CWD will effectively
+ localize @CWD.
+
+ {
+ local $CWD;
+ pop @CWD;
+ ...
+ }
+
+ Assigning to @CWD calls "chdir()" for each element
+ @CWD = qw/a b c d/;
+
+ Internally, Perl clears @CWD and assigns each element in turn. Thus,
+ this code above will do this:
+
+ chdir 'a';
+ chdir 'a/b';
+ chdir 'a/b/c';
+ chdir 'a/b/c/d';
+
+ Generally, avoid assigning to @CWD and just use push and pop instead.
+
+ Volumes not handled
+ There is currently no way to change the current volume via File::chdir.
+
+NOTES
+ $CWD returns the current directory using native path separators, i.e.
+ "\" on Win32. This ensures that $CWD will compare correctly with
+ directories created using File::Spec. For example:
+
+ my $working_dir = File::Spec->catdir( $CWD, "foo" );
+ $CWD = $working_dir;
+ doing_stuff_might_chdir();
+ is( $CWD, $working_dir, "back to original working_dir?" );
+
+ Deleting the last item of @CWD will act like a pop. Deleting from the
+ middle will throw an exception.
+
+ delete @CWD[-1]; # OK
+ delete @CWD[-2]; # Dies
+
+ What should %CWD do? Something with volumes?
+
+ # chdir to C:\Program Files\Sierra\Half Life ?
+ $CWD{C} = '\\Program Files\\Sierra\\Half Life';
+
+DIAGNOSTICS
+ If an error is encountered when changing $CWD or @CWD, one of the
+ following exceptions will be thrown:
+
+ * ~Can't delete except at the end of @CWD~ * ~Failed to change directory
+ to '$dir'~
+
+HISTORY
+ Michael wanted "local chdir" to work. p5p didn't. But it wasn't over!
+ Was it over when the Germans bombed Pearl Harbor? Hell, no!
+
+ Abigail and/or Bryan Warnock suggested the $CWD thing (Michael forgets
+ which). They were right.
+
+ The "chdir()" override was eliminated in 0.04.
+
+ David became co-maintainer with 0.06_01 to fix some chronic Win32 path
+ bugs.
+
+ As of 0.08, if changing $CWD or @CWD fails to change the directory, an
+ error will be thrown.
+
+SEE ALSO
+ File::pushd, File::Spec, Cwd, "chdir" in perlfunc, "Animal House"
+ <http://www.imdb.com/title/tt0077975/quotes>
+
+SUPPORT
+ Bugs / Feature Requests
+ Please report any bugs or feature requests through the issue tracker at
+ <https://github.com/dagolden/File-chdir/issues>. 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.
+
+ <https://github.com/dagolden/File-chdir>
+
+ git clone https://github.com/dagolden/File-chdir.git
+
+AUTHORS
+ * David Golden <dagolden@cpan.org>
+
+ * Michael G. Schwern <schwern@pobox.com>
+
+CONTRIBUTORS
+ * David Golden <xdg@xdg.me>
+
+ * Joel Berger <joel.a.berger@gmail.com>
+
+ * Philippe Bruhat (BooK) <book@cpan.org>
+
+COPYRIGHT AND LICENSE
+ This software is copyright (c) 2016 by Michael G. Schwern 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.
+
--- /dev/null
+requires "Carp" => "0";
+requires "Cwd" => "3.16";
+requires "Exporter" => "0";
+requires "File::Spec::Functions" => "3.27";
+requires "perl" => "5.006";
+requires "strict" => "0";
+requires "vars" => "0";
+
+on 'test' => sub {
+ requires "ExtUtils::MakeMaker" => "0";
+ requires "File::Spec" => "0";
+ requires "Test::More" => "0";
+ requires "perl" => "5.006";
+ requires "warnings" => "0";
+};
+
+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::PluginBundle::DAGOLDEN" => "0.072";
+ requires "English" => "0";
+ 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::More" => "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 "blib" => "1.01";
+ requires "perl" => "5.006";
+ requires "warnings" => "0";
+};
--- /dev/null
+name = File-chdir
+author = David Golden <dagolden@cpan.org>
+author = Michael G. Schwern <schwern@pobox.com>
+license = Perl_5
+copyright_holder = Michael G. Schwern and David Golden
+
+[@DAGOLDEN]
+:version = 0.072
+stopwords = Warnock
--- /dev/null
+use strict;
+use warnings;
+use File::chdir;
+
+mkdir "foo";
+
+$CWD = "foo"; # now in foo/
+
+mkdir "bar";
+
+{
+ local $CWD = "bar"; # now in foo/bar/
+}
+
+# back to foo
+rmdir "bar";
+
+pop @CWD; # now in original directory
+
+rmdir "foo";
+
--- /dev/null
+package File::chdir;
+use 5.004;
+use strict;
+use vars qw($VERSION @ISA @EXPORT $CWD @CWD);
+# ABSTRACT: a more sensible way to change directories
+
+our $VERSION = '0.1011';
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(*CWD);
+
+use Carp;
+use Cwd 3.16;
+use File::Spec::Functions 3.27 qw/canonpath splitpath catpath splitdir catdir/;
+
+tie $CWD, 'File::chdir::SCALAR' or die "Can't tie \$CWD";
+tie @CWD, 'File::chdir::ARRAY' or die "Can't tie \@CWD";
+
+sub _abs_path {
+ # Otherwise we'll never work under taint mode.
+ my($cwd) = Cwd::getcwd =~ /(.*)/s;
+ # Run through File::Spec, since everything else uses it
+ return canonpath($cwd);
+}
+
+# splitpath but also split directory
+sub _split_cwd {
+ my ($vol, $dir) = splitpath(_abs_path, 1);
+ my @dirs = splitdir( $dir );
+ shift @dirs; # get rid of leading empty "root" directory
+ return ($vol, @dirs);
+}
+
+# catpath, but take list of directories
+# restore the empty root dir and provide an empty file to avoid warnings
+sub _catpath {
+ my ($vol, @dirs) = @_;
+ return catpath($vol, catdir(q{}, @dirs), q{});
+}
+
+sub _chdir {
+ # Untaint target directory
+ my ($new_dir) = $_[0] =~ /(.*)/s;
+
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
+ if ( ! CORE::chdir($new_dir) ) {
+ croak "Failed to change directory to '$new_dir': $!";
+ };
+ return 1;
+}
+
+{
+ package File::chdir::SCALAR;
+ use Carp;
+
+ BEGIN {
+ *_abs_path = \&File::chdir::_abs_path;
+ *_chdir = \&File::chdir::_chdir;
+ *_split_cwd = \&File::chdir::_split_cwd;
+ *_catpath = \&File::chdir::_catpath;
+ }
+
+ sub TIESCALAR {
+ bless [], $_[0];
+ }
+
+ # To be safe, in case someone chdir'd out from under us, we always
+ # check the Cwd explicitly.
+ sub FETCH {
+ return _abs_path;
+ }
+
+ sub STORE {
+ return unless defined $_[1];
+ _chdir($_[1]);
+ }
+}
+
+
+{
+ package File::chdir::ARRAY;
+ use Carp;
+
+ BEGIN {
+ *_abs_path = \&File::chdir::_abs_path;
+ *_chdir = \&File::chdir::_chdir;
+ *_split_cwd = \&File::chdir::_split_cwd;
+ *_catpath = \&File::chdir::_catpath;
+ }
+
+ sub TIEARRAY {
+ bless {}, $_[0];
+ }
+
+ sub FETCH {
+ my($self, $idx) = @_;
+ my ($vol, @cwd) = _split_cwd;
+ return $cwd[$idx];
+ }
+
+ sub STORE {
+ my($self, $idx, $val) = @_;
+
+ my ($vol, @cwd) = _split_cwd;
+ if( $self->{Cleared} ) {
+ @cwd = ();
+ $self->{Cleared} = 0;
+ }
+
+ $cwd[$idx] = $val;
+ my $dir = _catpath($vol,@cwd);
+
+ _chdir($dir);
+ return $cwd[$idx];
+ }
+
+ sub FETCHSIZE {
+ my ($vol, @cwd) = _split_cwd;
+ return scalar @cwd;
+ }
+ sub STORESIZE {}
+
+ sub PUSH {
+ my($self) = shift;
+
+ my $dir = _catpath(_split_cwd, @_);
+ _chdir($dir);
+ return $self->FETCHSIZE;
+ }
+
+ sub POP {
+ my($self) = shift;
+
+ my ($vol, @cwd) = _split_cwd;
+ my $popped = pop @cwd;
+ my $dir = _catpath($vol,@cwd);
+ _chdir($dir);
+ return $popped;
+ }
+
+ sub SHIFT {
+ my($self) = shift;
+
+ my ($vol, @cwd) = _split_cwd;
+ my $shifted = shift @cwd;
+ my $dir = _catpath($vol,@cwd);
+ _chdir($dir);
+ return $shifted;
+ }
+
+ sub UNSHIFT {
+ my($self) = shift;
+
+ my ($vol, @cwd) = _split_cwd;
+ my $dir = _catpath($vol, @_, @cwd);
+ _chdir($dir);
+ return $self->FETCHSIZE;
+ }
+
+ sub CLEAR {
+ my($self) = shift;
+ $self->{Cleared} = 1;
+ }
+
+ sub SPLICE {
+ my $self = shift;
+ my $offset = shift || 0;
+ my $len = shift || $self->FETCHSIZE - $offset;
+ my @new_dirs = @_;
+
+ my ($vol, @cwd) = _split_cwd;
+ my @orig_dirs = splice @cwd, $offset, $len, @new_dirs;
+ my $dir = _catpath($vol, @cwd);
+ _chdir($dir);
+ return @orig_dirs;
+ }
+
+ sub EXTEND { }
+ sub EXISTS {
+ my($self, $idx) = @_;
+ return $self->FETCHSIZE >= $idx ? 1 : 0;
+ }
+
+ sub DELETE {
+ my($self, $idx) = @_;
+ croak "Can't delete except at the end of \@CWD"
+ if $idx < $self->FETCHSIZE - 1;
+ local $Carp::CarpLevel = $Carp::CarpLevel + 1;
+ $self->POP;
+ }
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+File::chdir - a more sensible way to change directories
+
+=head1 VERSION
+
+version 0.1011
+
+=head1 SYNOPSIS
+
+ use File::chdir;
+
+ $CWD = "/foo/bar"; # now in /foo/bar
+ {
+ local $CWD = "/moo/baz"; # now in /moo/baz
+ ...
+ }
+
+ # still in /foo/bar!
+
+=head1 DESCRIPTION
+
+Perl's C<chdir()> has the unfortunate problem of being very, very, very
+global. If any part of your program calls C<chdir()> or if any library
+you use calls C<chdir()>, it changes the current working directory for
+the *whole* program.
+
+This sucks.
+
+File::chdir gives you an alternative, C<$CWD> and C<@CWD>. These two
+variables combine all the power of C<chdir()>, L<File::Spec> and L<Cwd>.
+
+=head1 $CWD
+
+Use the C<$CWD> variable instead of C<chdir()> and Cwd.
+
+ use File::chdir;
+ $CWD = $dir; # just like chdir($dir)!
+ print $CWD; # prints the current working directory
+
+It can be localized, and it does the right thing.
+
+ $CWD = "/foo"; # it's /foo out here.
+ {
+ local $CWD = "/bar"; # /bar in here
+ }
+ # still /foo out here!
+
+C<$CWD> always returns the absolute path in the native form for the
+operating system.
+
+C<$CWD> and normal C<chdir()> work together just fine.
+
+=head1 @CWD
+
+C<@CWD> represents the current working directory as an array, each
+directory in the path is an element of the array. This can often make
+the directory easier to manipulate, and you don't have to fumble with
+C<< File::Spec->splitpath >> and C<< File::Spec->catdir >> to make portable code.
+
+ # Similar to chdir("/usr/local/src/perl")
+ @CWD = qw(usr local src perl);
+
+pop, push, shift, unshift and splice all work. pop and push are
+probably the most useful.
+
+ pop @CWD; # same as chdir(File::Spec->updir)
+ push @CWD, 'some_dir' # same as chdir('some_dir')
+
+C<@CWD> and C<$CWD> both work fine together.
+
+*NOTE* Due to a perl bug you can't localize C<@CWD>. See L</CAVEATS> for a work around.
+
+=head1 EXAMPLES
+
+(We omit the C<use File::chdir> from these examples for terseness)
+
+Here's C<$CWD> instead of C<chdir()>:
+
+ $CWD = 'foo'; # chdir('foo')
+
+and now instead of Cwd.
+
+ print $CWD; # use Cwd; print Cwd::abs_path
+
+you can even do zsh style C<cd foo bar>
+
+ $CWD = '/usr/local/foo';
+ $CWD =~ s/usr/var/;
+
+if you want to localize that, make sure you get the parens right
+
+ {
+ (local $CWD) =~ s/usr/var/;
+ ...
+ }
+
+It's most useful for writing polite subroutines which don't leave the
+program in some strange directory:
+
+ sub foo {
+ local $CWD = 'some/other/dir';
+ ...do your work...
+ }
+
+which is much simpler than the equivalent:
+
+ sub foo {
+ use Cwd;
+ my $orig_dir = Cwd::getcwd;
+ chdir('some/other/dir');
+
+ ...do your work...
+
+ chdir($orig_dir);
+ }
+
+C<@CWD> comes in handy when you want to start moving up and down the
+directory hierarchy in a cross-platform manner without having to use
+File::Spec.
+
+ pop @CWD; # chdir(File::Spec->updir);
+ push @CWD, 'some', 'dir' # chdir(File::Spec->catdir(qw(some dir)));
+
+You can easily change your parent directory:
+
+ # chdir from /some/dir/bar/moo to /some/dir/foo/moo
+ $CWD[-2] = 'foo';
+
+=head1 CAVEATS
+
+=head2 C<local @CWD> does not work.
+
+C<local @CWD> will not localize C<@CWD>. This is a bug in Perl, you
+can't localize tied arrays. As a work around localizing $CWD will
+effectively localize @CWD.
+
+ {
+ local $CWD;
+ pop @CWD;
+ ...
+ }
+
+=head2 Assigning to C<@CWD> calls C<chdir()> for each element
+
+ @CWD = qw/a b c d/;
+
+Internally, Perl clears C<@CWD> and assigns each element in turn. Thus, this
+code above will do this:
+
+ chdir 'a';
+ chdir 'a/b';
+ chdir 'a/b/c';
+ chdir 'a/b/c/d';
+
+Generally, avoid assigning to C<@CWD> and just use push and pop instead.
+
+=head2 Volumes not handled
+
+There is currently no way to change the current volume via File::chdir.
+
+=head1 NOTES
+
+C<$CWD> returns the current directory using native path separators, i.e. C<\>
+on Win32. This ensures that C<$CWD> will compare correctly with directories
+created using File::Spec. For example:
+
+ my $working_dir = File::Spec->catdir( $CWD, "foo" );
+ $CWD = $working_dir;
+ doing_stuff_might_chdir();
+ is( $CWD, $working_dir, "back to original working_dir?" );
+
+Deleting the last item of C<@CWD> will act like a pop. Deleting from the
+middle will throw an exception.
+
+ delete @CWD[-1]; # OK
+ delete @CWD[-2]; # Dies
+
+What should %CWD do? Something with volumes?
+
+ # chdir to C:\Program Files\Sierra\Half Life ?
+ $CWD{C} = '\\Program Files\\Sierra\\Half Life';
+
+=head1 DIAGNOSTICS
+
+If an error is encountered when changing C<$CWD> or C<@CWD>, one of
+the following exceptions will be thrown:
+
+* ~Can't delete except at the end of @CWD~
+* ~Failed to change directory to '$dir'~
+
+=head1 HISTORY
+
+Michael wanted C<local chdir> to work. p5p didn't. But it wasn't over!
+Was it over when the Germans bombed Pearl Harbor? Hell, no!
+
+Abigail and/or Bryan Warnock suggested the C<$CWD> thing (Michael forgets
+which). They were right.
+
+The C<chdir()> override was eliminated in 0.04.
+
+David became co-maintainer with 0.06_01 to fix some chronic
+Win32 path bugs.
+
+As of 0.08, if changing C<$CWD> or C<@CWD> fails to change the directory, an
+error will be thrown.
+
+=head1 SEE ALSO
+
+L<File::pushd>, L<File::Spec>, L<Cwd>, L<perlfunc/chdir>,
+"Animal House" L<http://www.imdb.com/title/tt0077975/quotes>
+
+=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<https://github.com/dagolden/File-chdir/issues>.
+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<https://github.com/dagolden/File-chdir>
+
+ git clone https://github.com/dagolden/File-chdir.git
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+David Golden <dagolden@cpan.org>
+
+=item *
+
+Michael G. Schwern <schwern@pobox.com>
+
+=back
+
+=head1 CONTRIBUTORS
+
+=for stopwords David Golden Joel Berger Philippe Bruhat (BooK)
+
+=over 4
+
+=item *
+
+David Golden <xdg@xdg.me>
+
+=item *
+
+Joel Berger <joel.a.berger@gmail.com>
+
+=item *
+
+Philippe Bruhat (BooK) <book@cpan.org>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2016 by Michael G. Schwern 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
--- /dev/null
+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]
+
--- /dev/null
+do { my $x = {
+ 'configure' => {
+ 'requires' => {
+ 'ExtUtils::MakeMaker' => '6.17',
+ 'perl' => '5.006'
+ }
+ },
+ 'develop' => {
+ 'requires' => {
+ 'Dist::Zilla' => '5',
+ 'Dist::Zilla::PluginBundle::DAGOLDEN' => '0.072',
+ 'English' => '0',
+ '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::More' => '0',
+ 'Test::Pod' => '1.41',
+ 'Test::Pod::Coverage' => '1.08',
+ 'Test::Portability::Files' => '0',
+ 'Test::Spelling' => '0.12',
+ 'Test::Version' => '1',
+ 'blib' => '1.01',
+ 'perl' => '5.006',
+ 'warnings' => '0'
+ }
+ },
+ 'runtime' => {
+ 'requires' => {
+ 'Carp' => '0',
+ 'Cwd' => '3.16',
+ 'Exporter' => '0',
+ 'File::Spec::Functions' => '3.27',
+ 'perl' => '5.006',
+ 'strict' => '0',
+ 'vars' => '0'
+ }
+ },
+ 'test' => {
+ 'recommends' => {
+ 'CPAN::Meta' => '2.120900'
+ },
+ 'requires' => {
+ 'ExtUtils::MakeMaker' => '0',
+ 'File::Spec' => '0',
+ 'Test::More' => '0',
+ 'perl' => '5.006',
+ 'warnings' => '0'
+ }
+ }
+ };
+ $x;
+ }
\ No newline at end of file
--- /dev/null
+#!perl
+
+use strict;
+use warnings;
+
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.025
+
+use Test::More tests => 1;
+
+use ExtUtils::MakeMaker;
+use File::Spec;
+
+# from $version::LAX
+my $lax_version_re =
+ qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
+ |
+ (?:\.[0-9]+) (?:_[0-9]+)?
+ ) | (?:
+ v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
+ |
+ (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
+ )
+ )/x;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_pre = "CPAN::Meta::Prereqs";
+my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _max {
+ my $max = shift;
+ $max = ( $_ > $max ) ? $_ : $max for @_;
+ return $max;
+}
+
+sub _merge_prereqs {
+ my ($collector, $prereqs) = @_;
+
+ # CPAN::Meta::Prereqs object
+ if (ref $collector eq $cpan_meta_pre) {
+ return $collector->with_merged_prereqs(
+ CPAN::Meta::Prereqs->new( $prereqs )
+ );
+ }
+
+ # Raw hashrefs
+ for my $phase ( keys %$prereqs ) {
+ for my $type ( keys %{ $prereqs->{$phase} } ) {
+ for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
+ $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
+ }
+ }
+ }
+
+ return $collector;
+}
+
+my @include = qw(
+
+);
+
+my @exclude = qw(
+
+);
+
+# Add static prereqs to the included modules list
+my $static_prereqs = do 't/00-report-prereqs.dd';
+
+# Merge all prereqs (either with ::Prereqs or a hashref)
+my $full_prereqs = _merge_prereqs(
+ ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
+ $static_prereqs
+);
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META
+ && (my $meta = eval { CPAN::Meta->load_file($source) } )
+) {
+ $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
+}
+else {
+ $source = 'static metadata';
+}
+
+my @full_reports;
+my @dep_errors;
+my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
+
+# Add static includes into a fake section
+for my $mod (@include) {
+ $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
+ next unless $req_hash->{$phase};
+ next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
+
+ for my $type ( qw(requires recommends suggests conflicts modules) ) {
+ next unless $req_hash->{$phase}{$type};
+
+ my $title = ucfirst($phase).' '.ucfirst($type);
+ my @reports = [qw/Module Want Have/];
+
+ for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
+ next if $mod eq 'perl';
+ next if grep { $_ eq $mod } @exclude;
+
+ my $file = $mod;
+ $file =~ s{::}{/}g;
+ $file .= ".pm";
+ my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
+
+ my $want = $req_hash->{$phase}{$type}{$mod};
+ $want = "undef" unless defined $want;
+ $want = "any" if !$want && $want == 0;
+
+ my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
+
+ if ($prefix) {
+ my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
+ $have = "undef" unless defined $have;
+ push @reports, [$mod, $want, $have];
+
+ if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
+ if ( $have !~ /\A$lax_version_re\z/ ) {
+ push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
+ }
+ elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
+ push @dep_errors, "$mod version '$have' is not in required range '$want'";
+ }
+ }
+ }
+ else {
+ push @reports, [$mod, $want, "missing"];
+
+ if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
+ push @dep_errors, "$mod is not installed ($req_string)";
+ }
+ }
+ }
+
+ if ( @reports ) {
+ push @full_reports, "=== $title ===\n\n";
+
+ my $ml = _max( map { length $_->[0] } @reports );
+ my $wl = _max( map { length $_->[1] } @reports );
+ my $hl = _max( map { length $_->[2] } @reports );
+
+ if ($type eq 'modules') {
+ splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
+ push @full_reports, map { sprintf(" %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
+ }
+ else {
+ splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
+ push @full_reports, map { sprintf(" %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+ }
+
+ push @full_reports, "\n";
+ }
+ }
+}
+
+if ( @full_reports ) {
+ diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
+}
+
+if ( @dep_errors ) {
+ diag join("\n",
+ "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n",
+ "The following REQUIRED prerequisites were not satisfied:\n",
+ @dep_errors,
+ "\n"
+ );
+}
+
+pass;
+
+# vim: ts=4 sts=4 sw=4 et:
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+use Test::More tests => 55;
+use File::Spec::Functions qw/canonpath splitdir catdir splitpath catpath/;
+use Cwd qw/getcwd/;
+
+BEGIN { use_ok('File::chdir') }
+
+#--------------------------------------------------------------------------#
+# Fixtures and utility subs
+#--------------------------------------------------------------------------#-
+
+# _catdir has OS-specific path separators so do the same for getcwd
+sub _getcwd { canonpath( getcwd ) }
+
+# reassemble
+sub _catpath {
+ my ($vol, @dirs) = @_;
+ return catpath( $vol, catdir(q{}, @dirs), q{} );
+}
+
+# get $vol here and use it later
+my ($vol,$cwd) = splitpath(canonpath(getcwd),1);
+
+# get directory list the way a user would use it -- without empty leading dir
+# as returned by splitdir;
+my @cwd = grep { length } splitdir($cwd);
+
+# Utility sub for checking cases
+sub _check_cwd {
+ # report failures at the calling line
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $label = pop @_;
+ my @expect = @_;
+ is( _getcwd, _catpath($vol,@expect), "$label works" );
+ ok( eq_array(\@CWD, [@expect]), '... and value of @CWD is correct' );
+ is( $CWD, _catpath($vol,@expect), '... and value of $CWD is correct' );
+}
+
+#--------------------------------------------------------------------------#-
+# Tying test
+#--------------------------------------------------------------------------#-
+
+ok( tied @CWD, '@CWD is fit to be tied' );
+
+#--------------------------------------------------------------------------#
+# Assignment tests
+#--------------------------------------------------------------------------#
+
+# Non-local
+@CWD = (@cwd, 't');
+_check_cwd( @cwd, 't', 'Ordinary assignment');
+
+# Reset
+@CWD = @cwd;
+
+# Localized
+{
+ # localizing tied arrays doesn't work, perl bug. :(
+ # this is a work around.
+ local $CWD;
+
+ @CWD = (@cwd, 't');
+ _check_cwd( @cwd, 't', 'Localized assignment' );
+}
+
+# Check that localizing $CWD/@CWD reverts properly
+_check_cwd( @cwd, 'Reset of localized assignment' );
+
+#--------------------------------------------------------------------------#
+# Push tests
+#--------------------------------------------------------------------------#
+
+# Non-local
+push @CWD, 't';
+_check_cwd( @cwd, 't', 'Ordinary push');
+
+# Reset
+@CWD = @cwd;
+
+# Localized
+{
+ # localizing tied arrays doesn't work, perl bug. :(
+ # this is a work around.
+ local $CWD;
+
+ push @CWD, 't';
+ _check_cwd( @cwd, 't', 'Localized push' );
+}
+
+# Check that localizing $CWD/@CWD reverts properly
+_check_cwd( @cwd, 'Reset of localized push' );
+
+#--------------------------------------------------------------------------#
+# Pop tests
+#--------------------------------------------------------------------------#
+
+# Non-local
+my $popped_dir = pop @CWD;
+_check_cwd( @cwd[0 .. $#cwd-1], 'Ordinary pop');
+is( $popped_dir, $cwd[-1], '... and pop returned popped dir' );
+
+# Reset
+@CWD = @cwd;
+
+# Localized
+{
+ # localizing tied arrays doesn't work, perl bug. :(
+ # this is a work around.
+ local $CWD;
+
+ my $popped_dir = pop @CWD;
+ _check_cwd( @cwd[0 .. $#cwd-1], 'Localized pop');
+}
+
+# Check that localizing $CWD/@CWD reverts properly
+_check_cwd( @cwd, 'Reset of localized pop' );
+
+
+#--------------------------------------------------------------------------#
+# Splice tests
+#--------------------------------------------------------------------------#
+
+# Non-local
+my @spliced_dirs;
+
+# splice multiple dirs from end
+push @CWD, 't', 'lib';
+@spliced_dirs = splice @CWD, -2;
+_check_cwd( @cwd, 'Ordinary splice (from end)');
+is( @spliced_dirs, 2, '... and returns right number of dirs' );
+ok( eq_array(\@spliced_dirs, [qw/t lib/]), "... and they're correct" );
+
+# splice a single dir from the middle
+push @CWD, 't', 'lib';
+@spliced_dirs = splice @CWD, -2, 1;
+_check_cwd( @cwd, 'lib', 'Ordinary splice (from middle)');
+is( @spliced_dirs, 1, '... and returns right number of dirs' );
+ok( eq_array(\@spliced_dirs, ['t']), "... and it's correct" );
+
+# Reset
+@CWD = @cwd;
+
+# Localized
+{
+ # localizing tied arrays doesn't work, perl bug. :(
+ # this is a work around.
+ local $CWD;
+
+ # splice multiple dirs from end
+ push @CWD, 't', 'lib';
+ @spliced_dirs = splice @CWD, -2;
+ _check_cwd( @cwd, 'Localized splice (from end)');
+ is( @spliced_dirs, 2, '... and returns right number of dirs' );
+ ok( eq_array(\@spliced_dirs, [qw/t lib/]), "... and they're correct" );
+
+ # splice a single dir from the middle
+ push @CWD, 't', 'lib';
+ @spliced_dirs = splice @CWD, -2, 1;
+ _check_cwd( @cwd, 'lib', 'Localized splice (from middle)');
+ is( @spliced_dirs, 1, '... and returns right number of dirs' );
+ ok( eq_array(\@spliced_dirs, ['t']), "... and it's correct" );
+}
+
+# Check that localizing $CWD/@CWD reverts properly
+_check_cwd( @cwd, 'Reset of localized splice' );
+
+#--------------------------------------------------------------------------#
+# Exceptions
+#--------------------------------------------------------------------------#
+
+
+# Change to invalid directory
+my $target = "doesnt_exist";
+eval { $CWD[@CWD] = $target };
+my $err = $@;
+ok( $err, 'Failure to chdir throws an error' );
+#_check_cwd( @cwd, 'Still in original directory' );
+
+my $missing_dir = quotemeta(File::Spec->catfile($CWD,$target));
+like( $err, "/Failed to change directory to '$missing_dir'/",
+ '... and the error message is correct');
+
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+use Test::More tests => 6;
+use File::Spec::Functions qw/canonpath catdir/;
+use Cwd qw/getcwd/;
+
+BEGIN { use_ok('File::chdir') }
+
+# _catdir has OS-specific path separators so do the same for getcwd
+sub _getcwd { canonpath( getcwd ) }
+
+my($cwd) = _getcwd =~ /(.*)/; # detaint otherwise nothing's gonna work
+
+# First, let's try normal chdir()
+{
+ chdir('t');
+ ::is( _getcwd, catdir($cwd,'t'), 'void chdir still works' );
+
+ chdir($cwd); # reset
+
+ if( chdir('t') ) {
+ 1;
+ }
+ else {
+ ::fail('chdir() failed completely in boolean context!');
+ }
+ ::is( _getcwd, catdir($cwd,'t'), ' even in boolean context' );
+}
+
+::is( _getcwd, catdir($cwd,'t'), ' unneffected by blocks' );
+
+
+# Ok, reset ourself for the real test.
+chdir($cwd) or die $!;
+
+{
+ local $ENV{HOME} = 't';
+ chdir;
+ ::is( _getcwd, catdir($cwd, 't'), 'chdir() with no args' );
+ ::is( $CWD, catdir($cwd, 't'), ' $CWD follows' );
+}
+
+# Final chdir() back to the original or we confuse the debugger.
+chdir($cwd);
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+
+use Test::More;
+
+BEGIN {
+ if ( $] < 5.006 ) {
+ plan skip_all => 'delete(@array) not available before Perl 5.6';
+ }
+ else {
+ plan tests => 15;
+ }
+}
+
+use File::Spec::Functions qw/canonpath splitdir catdir splitpath catpath/;
+use Cwd qw/getcwd/;
+
+BEGIN { use_ok('File::chdir') }
+
+#--------------------------------------------------------------------------#
+# Fixtures and utility subs
+#--------------------------------------------------------------------------#-
+
+# _catdir has OS-specific path separators so do the same for getcwd
+sub _getcwd { canonpath( getcwd ) }
+
+# reassemble
+sub _catpath {
+ my ($vol, @dirs) = @_;
+ return catpath( $vol, catdir(q{}, @dirs), q{} );
+}
+
+# get $vol here and use it later
+my ($vol,$cwd) = splitpath(canonpath(getcwd),1);
+
+# get directory list the way a user would use it -- without empty leading dir
+# as returned by splitdir;
+my @cwd = grep { length } splitdir($cwd);
+
+# Utility sub for checking cases
+sub _check_cwd {
+ # report failures at the calling line
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ my $label = pop @_;
+ my @expect = @_;
+ is( _getcwd, _catpath($vol,@expect), "$label works" );
+ ok( eq_array(\@CWD, [@expect]), '... and value of @CWD is correct' );
+ is( $CWD, _catpath($vol,@expect), '... and value of $CWD is correct' );
+}
+
+#--------------------------------------------------------------------------#-
+# Tying test
+#--------------------------------------------------------------------------#-
+
+ok( tied @CWD, '@CWD is fit to be tied' );
+
+#--------------------------------------------------------------------------#
+# Delete tests - only from the end of the array (like popping)
+#--------------------------------------------------------------------------#
+
+SKIP: {
+ if ( $] < 5.006 ) {
+ skip 'delete(@array) not available before Perl 5.6', 13;
+ }
+
+ # Non-local
+ eval { delete $CWD[$#CWD] };
+ is( $@, '', "Ordinary delete from end of \@CWD lives" );
+ _check_cwd( @cwd[0 .. $#cwd-1], 'Ordinary delete from end of @CWD');
+
+ # Reset
+ @CWD = @cwd;
+
+ # Localized
+ {
+ # localizing tied arrays doesn't work, perl bug. :(
+ # this is a work around.
+ local $CWD;
+
+ eval { delete $CWD[$#CWD] };
+ is( $@, '', "Ordinary delete from end of \@CWD lives" );
+ _check_cwd( @cwd[0 .. $#cwd-1], 'Ordinary delete from end of @CWD');
+
+ }
+
+ # Exception: DELETE (middle of array)
+ {
+ local $CWD;
+ push @CWD, 't', 'lib';
+ eval { delete $CWD[-2] };
+ my $err = $@;
+ ok( $err, 'Deleting $CWD[-2] throws an error' );
+ like( $err, "/Can't delete except at the end of \@CWD/",
+ '... and the error message is correct');
+ }
+
+
+}
+
+# Check that localizing $CWD/@CWD reverts properly
+_check_cwd( @cwd, 'Reset of localized pop' );
+
+
--- /dev/null
+Ensures git tracks 't/lib' as tests use that directory.
--- /dev/null
+#!/usr/bin/env perl -w
+
+# Test that File::chdir works when multiple packages have nested, localized $CWD.
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use File::chdir;
+
+my $original_cwd = $CWD.'';
+
+{
+ package Inner;
+ use File::chdir;
+
+ sub foo {
+ local $CWD = File::Spec->catdir($original_cwd, "lib");
+ }
+}
+
+
+{
+ package Outer;
+ use File::chdir;
+
+ sub bar {
+ local $CWD = File::Spec->catdir($original_cwd, "t");
+ Inner::foo();
+ }
+}
+
+
+Outer::bar();
+is $CWD, $original_cwd;
+
+
+done_testing;
--- /dev/null
+#!/usr/bin/env perl -w
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use File::chdir;
+use Cwd qw(getcwd);
+
+my $Orig_Cwd = $CWD;
+
+my $Test_Dir = "t/testdir$$\ntest";
+my $Can_mkdir_With_Newline = mkdir $Test_Dir;
+
+plan skip_all => "Can't make a directory with a newline in it" unless $Can_mkdir_With_Newline;
+
+{
+ local $CWD = $Test_Dir;
+ is $CWD, getcwd;
+}
+
+is $CWD, $Orig_Cwd;
+is getcwd, $Orig_Cwd;
+
+END {
+ chdir $Orig_Cwd; # just in case
+ rmdir $Test_Dir;
+}
+
+done_testing;
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+use Test::More tests => 13;
+use File::Spec::Functions qw/canonpath catdir/;
+use Cwd qw/getcwd/;
+
+BEGIN { use_ok('File::chdir') }
+
+# _catdir has OS-specific path separators so do the same for getcwd
+sub _getcwd { canonpath( getcwd ) }
+
+my $cwd = _getcwd;
+
+ok( tied $CWD, '$CWD is fit to be tied' );
+
+# First, let's try unlocalized $CWD.
+{
+ $CWD = 't';
+ ::is( _getcwd, catdir($cwd,'t'), 'unlocalized $CWD works' );
+ ::is( $CWD, catdir($cwd,'t'), ' $CWD set' );
+}
+
+::is( _getcwd, catdir($cwd,'t'), 'unlocalized $CWD unneffected by blocks' );
+::is( $CWD, catdir($cwd,'t'), ' and still set' );
+
+
+# Ok, reset ourself for the real test.
+$CWD = $cwd;
+
+{
+ my $old_dir = $CWD;
+ local $CWD = "t";
+ ::is( $old_dir, $cwd, '$CWD fetch works' );
+ ::is( _getcwd, catdir($cwd,'t'), 'localized $CWD works' );
+}
+
+::is( _getcwd, $cwd, ' and resets automatically!' );
+::is( $CWD, $cwd, ' $CWD reset, too' );
+
+
+chdir('t');
+is( $CWD, catdir($cwd,'t'), 'chdir() and $CWD work together' );
+
+#--------------------------------------------------------------------------#
+# Exceptions
+#--------------------------------------------------------------------------#
+my $target = "doesnt_exist";
+eval { $CWD = $target };
+my $err = $@;
+ok( $err, 'failure to chdir throws an error' );
+like( $err, "/Failed to change directory to '\Q$target\E'/",
+ '... and the error message is correct');
+
+
+
--- /dev/null
+use 5.006;
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.054
+
+use Test::More;
+
+plan tests => 2;
+
+my @module_files = (
+ 'File/chdir.pm'
+);
+
+
+
+# fake home for cpan-testers
+use File::Temp;
+local $ENV{HOME} = File::Temp::tempdir( CLEANUP => 1 );
+
+
+my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib';
+
+use File::Spec;
+use IPC::Open3;
+use IO::Handle;
+
+open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
+
+my @warnings;
+for my $lib (@module_files)
+{
+ # see L<perlfaq8/How can I capture STDERR from an external command?>
+ my $stderr = IO::Handle->new;
+
+ my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]");
+ binmode $stderr, ':crlf' if $^O eq 'MSWin32';
+ my @_warnings = <$stderr>;
+ waitpid($pid, 0);
+ is($?, 0, "$lib loaded ok");
+
+ 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) );
+
+
--- /dev/null
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More;
+use English qw(-no_match_vars);
+
+eval "use Test::Perl::Critic";
+plan skip_all => 'Test::Perl::Critic required to criticise code' if $@;
+Test::Perl::Critic->import( -profile => "perlcritic.rc" ) if -e "perlcritic.rc";
+all_critic_ok();
--- /dev/null
+#!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' });
--- /dev/null
+use strict;
+use warnings;
+use Test::More;
+
+# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007003
+use Test::Spelling 0.12;
+use Pod::Wordlist;
+
+
+add_stopwords(<DATA>);
+all_pod_files_spelling_ok( qw( bin lib ) );
+__DATA__
+Berger
+BooK
+Bruhat
+David
+File
+Golden
+Joel
+Michael
+Philippe
+Schwern
+Warnock
+and
+book
+chdir
+dagolden
+joel
+lib
+schwern
+xdg
--- /dev/null
+#!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();
--- /dev/null
+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();
--- /dev/null
+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;
--- /dev/null
+#!perl
+# This file was automatically generated by Dist::Zilla::Plugin::MetaTests.
+
+use Test::CPAN::Meta;
+
+meta_yaml_ok();
--- /dev/null
+#!perl
+
+use Test::More;
+
+eval "use Test::MinimumVersion";
+plan skip_all => "Test::MinimumVersion required for testing minimum versions"
+ if $@;
+all_minimum_version_ok( qq{5.010} );