@@ -1,5 +1,50 @@
Revision history for Path-Tiny
+0.052 2014-01-14 15:58:03-05:00 America/New_York
+
+ [FIXED]
+
+ - Backslash-to-slash conversion now only happens on Windows
+ (since backslash is legal on Unix, we must allow it)
+
+0.051 2013-12-20 07:34:14 America/New_York
+
+ [FIXED]
+
+ - Fixed file order bug in the new test file
+
+0.050 2013-12-20 07:27:20 America/New_York
+
+ [FIXED]
+
+ - Recursive iteration won't throw an exception if a directory is
+ removed or unreadable during iteration.
+
+0.049 2013-12-12 00:48:01 America/New_York
+
+ [FIXED]
+
+ - Generates filename for atomic writes independent of thread-ID.
+ Fixes crashing bug on Win32 when fork() is called.
+
+0.048 2013-12-11 21:56:23 America/New_York
+
+ [ADDED]
+
+ - Added 'subsumes' method
+
+ [CHANGED]
+
+ - The 'chomp' option for 'lines' will remove any end-of-line sequences
+ fully instead of just chomping the last character
+
+ - The 'flock' package will no longer indexed by PAUSE
+
+ [FIXED]
+
+ - Hides warnings and fixes possible fatal errors from pure-perl Cwd,
+ particularly on MSWin32
+
0.047 2013-11-26 15:11:13 America/New_York
[FIXED]
@@ -1,3 +1,4 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.011.
CONTRIBUTING
Changes
LICENSE
@@ -23,11 +24,13 @@ t/input_output_no_UU.t
t/lib/TestUtils.pm
t/locking.t
t/mkpath.t
+t/mutable_tree_while_iterating.t
t/normalize.t
t/overloading.t
t/parent.t
t/recurse.t
t/rel-abs.t
+t/subsumes.t
t/temp.t
t/zzz-spec.t
tidyall.ini
@@ -4,7 +4,7 @@
"David Golden <dagolden@cpan.org>"
],
"dynamic_config" : 0,
- "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830",
+ "generated_by" : "Dist::Zilla version 5.011, CPAN::Meta::Converter version 2.133380",
"license" : [
"apache_2_0"
],
@@ -21,7 +21,8 @@
"corpus"
],
"package" : [
- "DB"
+ "DB",
+ "flock"
]
},
"prereqs" : {
@@ -32,7 +33,7 @@
},
"develop" : {
"requires" : {
- "Dist::Zilla" : "5.006",
+ "Dist::Zilla" : "5.011",
"Dist::Zilla::Plugin::MakeMaker" : "0",
"Dist::Zilla::Plugin::OnlyCorePrereqs" : "0",
"Dist::Zilla::Plugin::Prereqs" : "0",
@@ -95,15 +96,11 @@
"provides" : {
"Path::Tiny" : {
"file" : "lib/Path/Tiny.pm",
- "version" : "0.047"
+ "version" : "0.052"
},
"Path::Tiny::Error" : {
"file" : "lib/Path/Tiny.pm",
- "version" : "0.047"
- },
- "flock" : {
- "file" : "lib/Path/Tiny.pm",
- "version" : "0.047"
+ "version" : "0.052"
}
},
"release_status" : "stable",
@@ -118,7 +115,7 @@
"web" : "https://github.com/dagolden/Path-Tiny"
}
},
- "version" : "0.047",
+ "version" : "0.052",
"x_authority" : "cpan:DAGOLDEN",
"x_contributors" : [
"Chris Williams <bingos@cpan.org>",
@@ -129,7 +126,6 @@
"Geraud Continsouzas <geraud@scsi.nc>",
"Goro Fuji <gfuji@cpan.org>",
"Karen Etheridge <ether@cpan.org>",
- "Keedi Kim <keedi@cpan.org>",
"Martin Kjeldsen <mk@bluepipe.dk>",
"Michael G. Schwern <mschwern@cpan.org>",
"Toby Inkster <tobyink@cpan.org>",
@@ -15,7 +15,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 6.17
dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830'
+generated_by: 'Dist::Zilla version 5.011, CPAN::Meta::Converter version 2.133380'
license: apache
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -29,16 +29,14 @@ no_index:
- corpus
package:
- DB
+ - flock
provides:
Path::Tiny:
file: lib/Path/Tiny.pm
- version: 0.047
+ version: 0.052
Path::Tiny::Error:
file: lib/Path/Tiny.pm
- version: 0.047
- flock:
- file: lib/Path/Tiny.pm
- version: 0.047
+ version: 0.052
recommends:
Unicode::UTF8: 0.58
requires:
@@ -63,7 +61,7 @@ resources:
bugtracker: https://github.com/dagolden/Path-Tiny/issues
homepage: https://github.com/dagolden/Path-Tiny
repository: https://github.com/dagolden/Path-Tiny.git
-version: 0.047
+version: 0.052
x_authority: cpan:DAGOLDEN
x_contributors:
- 'Chris Williams <bingos@cpan.org>'
@@ -74,7 +72,6 @@ x_contributors:
- 'Geraud Continsouzas <geraud@scsi.nc>'
- 'Goro Fuji <gfuji@cpan.org>'
- 'Karen Etheridge <ether@cpan.org>'
- - 'Keedi Kim <keedi@cpan.org>'
- 'Martin Kjeldsen <mk@bluepipe.dk>'
- 'Michael G. Schwern <mschwern@cpan.org>'
- 'Toby Inkster <tobyink@cpan.org>'
@@ -1,4 +1,5 @@
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.011.
use strict;
use warnings;
@@ -48,7 +49,7 @@ my %WriteMakefileArgs = (
"lib" => 0,
"open" => 0
},
- "VERSION" => "0.047",
+ "VERSION" => "0.052",
"test" => {
"TESTS" => "t/*.t"
}
@@ -2,7 +2,7 @@ NAME
Path::Tiny - File path utility
VERSION
- version 0.047
+ version 0.052
SYNOPSIS
use Path::Tiny;
@@ -298,7 +298,8 @@ METHODS
If the "recurse" option is true, the iterator will walk the directory
recursively, breadth-first. If the "follow_symlinks" option is also
true, directory links will be followed recursively. There is no
- protection against loops when following links.
+ protection against loops when following links. If a directory is not
+ readable, it will not be followed.
The default is the same as:
@@ -322,7 +323,8 @@ METHODS
of options. Valid options are "binmode", "count" and "chomp". If
"binmode" is provided, it will be set on the handle prior to reading. If
"count" is provided, up to that many lines will be returned. If "chomp"
- is set, lines will be chomped before being returned.
+ is set, any end-of-line character sequences ("CR", "CRLF", or "LF") will
+ be removed from the lines returned.
Because the return is a list, "lines" in scalar context will return the
number of lines (and throw away the data).
@@ -490,6 +492,24 @@ METHODS
method returns the path standardized with Unix-style "/" directory
separators.
+ subsumes
+ path("foo/bar")->subsumes("foo/bar/baz"); # true
+ path("/foo/bar")->subsumes("/foo/baz"); # false
+
+ Returns true if the first path is a prefix of the second path at a
+ directory boundary.
+
+ This does not resolve parent directory entries ("..") or symlinks:
+
+ path("foo/bar")->subsumes("foo/bar/../baz"); # true
+
+ If such things are important to you, ensure that both paths are resolved
+ to the filesystem with "realpath":
+
+ my $p1 = path("foo/bar")->realpath;
+ my $p2 = path("foo/bar/../baz")->realpath;
+ if ( $p1->subsumes($p2) ) { ... }
+
touch
path("foo.txt")->touch;
path("foo.txt")->touch($epoch_secs);
@@ -614,6 +634,9 @@ SEE ALSO
There are probably comparable, non-Tiny tools. Let me know if you want
me to add a module to the list.
+ This module was featured in the 2013 Perl Advent Calendar
+ <http://www.perladvent.org/2013/2013-12-18.html>.
+
SUPPORT
Bugs / Feature Requests
Please report any bugs or feature requests through the issue tracker at
@@ -648,8 +671,6 @@ CONTRIBUTORS
* Karen Etheridge <ether@cpan.org>
- * Keedi Kim <keedi@cpan.org>
-
* Martin Kjeldsen <mk@bluepipe.dk>
* Michael G. Schwern <mschwern@cpan.org>
@@ -40,7 +40,7 @@ on 'configure' => sub {
};
on 'develop' => sub {
- requires "Dist::Zilla" => "5.006";
+ requires "Dist::Zilla" => "5.011";
requires "Dist::Zilla::Plugin::MakeMaker" => "0";
requires "Dist::Zilla::Plugin::OnlyCorePrereqs" => "0";
requires "Dist::Zilla::Plugin::Prereqs" => "0";
@@ -30,6 +30,7 @@ stopwords = touchpath
stopwords = UNC
stopwords = unlinked
stopwords = utf
+MetaNoIndex.package = flock
[MakeMaker]
eumm_version = 6.17
@@ -4,7 +4,7 @@ use warnings;
package Path::Tiny;
# ABSTRACT: File path utility
-our $VERSION = '0.047'; # VERSION
+our $VERSION = '0.052'; # VERSION
# Dependencies
use Config;
@@ -32,13 +32,7 @@ use overload (
fallback => 1,
);
-# if cloning, threads should already be loaded, but Win32 pseudoforks
-# don't do that so we have to be sure it's loaded anyway
-my $TID = 0; # for thread safe atomic writes
-
-sub CLONE { require threads; $TID = threads->tid }
-
-my $HAS_UU; # has Unicode::UTF8; lazily populated
+my $HAS_UU; # has Unicode::UTF8; lazily populated
sub _check_UU {
eval { require Unicode::UTF8; Unicode::UTF8->VERSION(0.58); 1 };
@@ -56,10 +50,10 @@ my $WIN32_ROOT = qr{(?: $UNC_VOL $SLASH | $DRV_VOL $SLASH | $SLASH )}x;
sub _win32_vol {
my ( $path, $drv ) = @_;
require Cwd;
- my $dcwd = Cwd::getdcwd($drv); # C: -> C:\some\cwd
+ my $dcwd = eval { Cwd::getdcwd($drv) }; # C: -> C:\some\cwd
# getdcwd on non-existent drive returns empty string
# so just use the original drive Z: -> Z:
- $dcwd = "$drv" unless length $dcwd;
+ $dcwd = "$drv" unless defined $dcwd && length $dcwd;
# normalize dwcd to end with a slash: might be C:\some\cwd or D:\ or Z:
$dcwd =~ s{$SLASH?$}{/};
# make the path absolute with dcwd
@@ -147,7 +141,7 @@ sub path {
# canonicalize paths
my $cpath = $path = File::Spec->canonpath($path); # ugh, but probably worth it
- $path =~ tr[\\][/]; # unix convention enforced
+ $path =~ tr[\\][/] if IS_WIN32(); # unix convention enforced
$path .= "/" if IS_WIN32() && $path =~ m{^$UNC_VOL$}; # canonpath strips it
# hack to make splitpath give us a basename; root paths must always have
@@ -244,7 +238,9 @@ sub absolute {
# add missing volume
if ( $self->is_absolute ) {
require Cwd;
- my ($drv) = Cwd::getdcwd() =~ /^($DRV_VOL | $UNC_VOL)/x;
+ # use Win32::GetCwd not Cwd::getdcwd because we're sure
+ # to have the former but not necessarily the latter
+ my ($drv) = Win32::GetCwd() =~ /^($DRV_VOL | $UNC_VOL)/x;
return path( $drv . $self->[PATH] );
}
}
@@ -441,6 +437,15 @@ sub iterator {
my $next;
while (@dirs) {
if ( ref $dirs[0] eq 'Path::Tiny' ) {
+ if ( !-r $dirs[0] ) {
+ # Directory is missing or not readable, so skip it. There
+ # is still a race condition possible between the check and
+ # the opendir, but we can't easily differentiate between
+ # error cases that are OK to skip and those that we want
+ # to be exceptions, so we live with the race and let opendir
+ # be fatal.
+ shift @dirs and next;
+ }
$current = $dirs[0];
my $dh;
opendir( $dh, $current->[PATH] )
@@ -479,14 +484,14 @@ sub lines {
if ( $args->{count} ) {
my ( @result, $counter );
while ( my $line = <$fh> ) {
- chomp $line if $chomp;
+ $line =~ s/(?:\x{0d}?\x{0a}|\x{0d})$// if $chomp;
push @result, $line;
last if ++$counter == $args->{count};
}
return @result;
}
elsif ($chomp) {
- return map { chomp; $_ } <$fh>;
+ return map { s/(?:\x{0d}?\x{0a}|\x{0d})$//; $_ } <$fh>; ## no critic
}
else {
return wantarray ? <$fh> : ( my $count =()= <$fh> );
@@ -497,7 +502,7 @@ sub lines_raw {
my $self = shift;
my $args = _get_args( shift, qw/binmode chomp count/ );
if ( $args->{chomp} && !$args->{count} ) {
- return split /\n/, slurp_raw($self); ## no critic
+ return split /\n/, slurp_raw($self); ## no critic
}
else {
$args->{binmode} = ":raw";
@@ -512,7 +517,7 @@ sub lines_utf8 {
&& $args->{chomp}
&& !$args->{count} )
{
- return split /\n/, slurp_utf8($self); ## no critic
+ return split /(?:\x{0d}?\x{0a}|\x{0d})/, slurp_utf8($self); ## no critic
}
else {
$args->{binmode} = ":raw:encoding(UTF-8)";
@@ -620,7 +625,10 @@ sub _non_empty {
sub realpath {
my $self = shift;
require Cwd;
- my $realpath = eval { Cwd::realpath( $self->[PATH] ) };
+ my $realpath = eval {
+ local $SIG{__WARN__} = sub { }; # (sigh) pure-perl CWD can carp
+ Cwd::realpath( $self->[PATH] );
+ };
$self->_throw("resolving realpath") unless defined $realpath and length $realpath;
return path($realpath);
}
@@ -697,7 +705,7 @@ sub spew {
my $binmode = $args->{binmode};
# get default binmode from caller's lexical scope (see "perldoc open")
$binmode = ( ( caller(0) )[10] || {} )->{'open>'} unless defined $binmode;
- my $temp = path( $self->[PATH] . $TID . $$ );
+ my $temp = path( $self->[PATH] . $$ . int( rand( 2**31 ) ) );
my $fh = $temp->filehandle( { locked => 1 }, ">", $binmode );
print {$fh} map { ref eq 'ARRAY' ? @$_ : $_ } @data;
close $fh or $self->_throw( 'close', $temp->[PATH] );
@@ -740,6 +748,43 @@ sub lstat {
sub stringify { $_[0]->[PATH] }
+sub subsumes {
+ my $self = shift;
+ Carp::croak("subsumes() requires a defined, positive-length argument")
+ unless defined $_[0];
+ my $other = path(shift);
+
+ # normalize absolute vs relative
+ if ( $self->is_absolute && !$other->is_absolute ) {
+ $other = $other->absolute;
+ }
+ elsif ( $other->is_absolute && !$self->is_absolute ) {
+ $self = $self->absolute;
+ }
+
+ # normalize volume vs non-volume; do this after absolute path
+ # adjustments above since that might add volumes already
+ if ( length $self->volume && !length $other->volume ) {
+ $other = $other->absolute;
+ }
+ elsif ( length $other->volume && !length $self->volume ) {
+ $self = $self->absolute;
+ }
+
+ if ( $self->[PATH] eq '.' ) {
+ return !!1; # cwd subsumes everything relative
+ }
+ elsif ( $self->is_rootdir ) {
+ # a root directory ("/", "c:/") already ends with a separator
+ return $other->[PATH] =~ m{^\Q$self->[PATH]\E};
+ }
+ else {
+ # exact match or prefix breaking at a separator
+ return $other->[PATH] =~ m{^\Q$self->[PATH]\E(?:/|$)};
+ }
+}
+
+
sub touch {
my ( $self, $epoch ) = @_;
if ( !-e $self->[PATH] ) {
@@ -797,7 +842,7 @@ Path::Tiny - File path utility
=head1 VERSION
-version 0.047
+version 0.052
=head1 SYNOPSIS
@@ -1113,7 +1158,8 @@ be included.
If the C<recurse> option is true, the iterator will walk the directory
recursively, breadth-first. If the C<follow_symlinks> option is also true,
directory links will be followed recursively. There is no protection against
-loops when following links.
+loops when following links. If a directory is not readable, it will not be
+followed.
The default is the same as:
@@ -1137,8 +1183,9 @@ L<Path::Iterator::Rule>.
Returns a list of lines from a file. Optionally takes a hash-reference of
options. Valid options are C<binmode>, C<count> and C<chomp>. If C<binmode>
is provided, it will be set on the handle prior to reading. If C<count> is
-provided, up to that many lines will be returned. If C<chomp> is set, lines
-will be chomped before being returned.
+provided, up to that many lines will be returned. If C<chomp> is set, any
+end-of-line character sequences (C<CR>, C<CRLF>, or C<LF>) will be removed
+from the lines returned.
Because the return is a list, C<lines> in scalar context will return the number
of lines (and throw away the data).
@@ -1317,6 +1364,25 @@ Like calling C<stat> or C<lstat> from L<File::stat>.
Returns a string representation of the path. Unlike C<canonpath>, this method
returns the path standardized with Unix-style C</> directory separators.
+=head2 subsumes
+
+ path("foo/bar")->subsumes("foo/bar/baz"); # true
+ path("/foo/bar")->subsumes("/foo/baz"); # false
+
+Returns true if the first path is a prefix of the second path at a directory
+boundary.
+
+This B<does not> resolve parent directory entries (C<..>) or symlinks:
+
+ path("foo/bar")->subsumes("foo/bar/../baz"); # true
+
+If such things are important to you, ensure that both paths are resolved to
+the filesystem with C<realpath>:
+
+ my $p1 = path("foo/bar")->realpath;
+ my $p2 = path("foo/bar/../baz")->realpath;
+ if ( $p1->subsumes($p2) ) { ... }
+
=head2 touch
path("foo.txt")->touch;
@@ -1484,6 +1550,8 @@ L<File::Next>
There are probably comparable, non-Tiny tools. Let me know if you want me to
add a module to the list.
+This module was featured in the L<2013 Perl Advent Calendar|http://www.perladvent.org/2013/2013-12-18.html>.
+
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
=head1 SUPPORT
@@ -1545,10 +1613,6 @@ Karen Etheridge <ether@cpan.org>
=item *
-Keedi Kim <keedi@cpan.org>
-
-=item *
-
Martin Kjeldsen <mk@bluepipe.dk>
=item *
@@ -3,7 +3,7 @@
use strict;
use warnings;
-# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.010
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.012
use Test::More tests => 1;
@@ -70,7 +70,7 @@ if ( -f $source && eval "require $cpan_meta" ) { ## no critic
$prereqs = $meta->effective_prereqs; # get the object, not the hash
if (eval "require $cpan_meta_req; 1") { ## no critic
$all_requires = $cpan_meta_req->new;
- for my $phase ( qw/configure build test runtime/ ) {
+ for my $phase ( qw/configure build test runtime develop/ ) {
$all_requires->add_requirements(
$prereqs->requirements_for($phase, 'requires')
);
@@ -11,7 +11,7 @@ use Path::Tiny;
my $tmp = Path::Tiny->tempdir;
sub _lines {
- return ( "Line1\n", "Line2\n" );
+ return ( "Line1\r\n", "Line2\n" );
}
sub _utf8_lines {
@@ -125,7 +125,7 @@ subtest "spew -> lines (count, more than)" => sub {
subtest "spew -> lines (count, chomp)" => sub {
my $file = Path::Tiny->tempfile;
ok( $file->spew(_lines), "spew" );
- my @exp = map { chomp; $_ } _lines;
+ my @exp = map { s/[\r\n]+//; $_ } _lines;
is( join( '', $file->lines( { chomp => 1, count => 2 } ) ),
join( '', @exp[ 0 .. 1 ] ), "lines" );
};
@@ -140,7 +140,7 @@ subtest "spew -> lines (count, UTF-8)" => sub {
subtest "spew -> lines (count, chomp, UTF-8)" => sub {
my $file = Path::Tiny->tempfile;
ok( $file->spew_utf8(_utf8_lines), "spew" );
- my @exp = map { chomp; $_ } _utf8_lines;
+ my @exp = map { s/[\r\n]+//; $_ } _utf8_lines;
is( join( '', $file->lines_utf8( { chomp => 1, count => 2 } ) ),
join( '', @exp[ 0 .. 1 ] ), "lines" );
};
@@ -148,7 +148,7 @@ subtest "spew -> lines (count, chomp, UTF-8)" => sub {
subtest "spew -> lines (chomp, UTF-8)" => sub {
my $file = Path::Tiny->tempfile;
ok( $file->spew_utf8(_utf8_lines), "spew" );
- my @exp = map { chomp; $_ } _utf8_lines;
+ my @exp = map { s/[\r\n]+//; $_ } _utf8_lines;
is( join( '', $file->lines_utf8( { chomp => 1 } ) ), join( '', @exp ), "lines" );
};
@@ -0,0 +1,36 @@
+use strict;
+use warnings;
+use Test::More 0.88;
+use Path::Tiny;
+
+use lib 't/lib';
+use TestUtils qw/exception tempd/;
+use Path::Tiny;
+
+my $wd = tempd;
+
+my @tree = qw(
+ base/Bethlehem/XDG/gift_list.txt
+ base/Vancouver/ETHER/.naughty
+ base/Vancouver/ETHER/gift_list.txt
+ base/New_York/XDG/gift_list.txt
+);
+path($_)->touchpath for @tree;
+
+my @files;
+my $iter = path('base')->iterator( { recurse => 1 } );
+my $exception = exception {
+ while ( my $path = $iter->() ) {
+ $path->remove_tree if $path->child('.naughty')->is_file;
+ push @files, $path if $path->is_file;
+ }
+};
+
+is( $exception, '', 'can remove directories while traversing' );
+is_deeply(
+ [ sort @files ],
+ [ 'base/Bethlehem/XDG/gift_list.txt', 'base/New_York/XDG/gift_list.txt' ],
+ 'remaining files',
+);
+
+done_testing;
@@ -0,0 +1,105 @@
+use 5.008001;
+use strict;
+use warnings;
+use Test::More 0.96;
+
+use lib 't/lib';
+use TestUtils qw/exception/;
+
+use Path::Tiny;
+use Cwd;
+
+my $IS_WIN32 = $^O eq 'MSWin32';
+
+my @cases = (
+ # path1 => path2 => path1->subsumes(path2)
+
+ "identity always subsumes" => [
+ [ '.' => '.' => 1 ],
+ [ '/' => '/' => 1 ],
+ [ '..' => '..' => 1 ],
+ [ '../..' => '../..' => 1 ],
+ [ '/foo/' => '/foo' => 1 ],
+ [ 'foo/' => 'foo' => 1 ],
+ [ './foo' => 'foo' => 1 ],
+ [ 'foo/.' => 'foo' => 1 ],
+ ],
+
+ "absolute v. absolute" => [
+ [ '/foo' => '/foo/bar' => 1 ],
+ [ '/foo' => '/foo/bar/baz' => 1 ],
+ [ '/foo' => '/foo/bar/baz/' => 1 ],
+ [ '/' => '/foo' => 1 ],
+ [ '/foo' => '/bar' => 0 ],
+ [ '/foo/bar' => '/foo/baz' => 0 ],
+ ],
+
+ "relative v. relative" => [
+ [ '.' => 'foo' => 1 ],
+ [ 'foo' => 'foo/baz' => 1 ],
+ [ './foo/bar' => 'foo/bar/baz' => 1 ],
+ [ './foo/bar' => './foo/bar' => 1 ],
+ [ './foo/bar' => 'foo/bar' => 1 ],
+ [ 'foo/bar' => './foo/bar' => 1 ],
+ [ 'foo/bar' => 'foo/baz' => 0 ],
+ ],
+
+ "relative v. absolute" => [
+ [ path(".")->absolute => 't' => 1 ],
+ [ "." => path('t')->absolute => 1 ],
+ [ "foo" => path('t')->absolute => 0 ],
+ [ path("..")->realpath => 't' => 1 ],
+ [ path("lib")->absolute => 't' => 0 ],
+ ],
+
+ "updirs in paths" => [
+ [ '/foo' => '/foo/bar/baz/..' => 1 ],
+ [ '/foo/bar' => '/foo/bar/../baz' => $IS_WIN32 ? 0 : 1 ],
+ [ '/foo/../bar' => '/bar' => $IS_WIN32 ? 1 : 0 ],
+ [ '..' => '../bar' => 1 ],
+ ],
+
+);
+
+if ($IS_WIN32) {
+ my $vol = path( Win32::GetCwd() )->volume . "/";
+ my $other = $vol ne 'Z:/' ? 'Z:/' : 'Y:/';
+ push @cases, 'Win32 cases',
+ [
+ [ "C:/foo" => "C:/foo" => 1 ],
+ [ "C:/foo" => "C:/bar" => 0 ],
+ [ "C:/" => "C:/foo" => 1 ],
+ [ "C:/" => "D:/" => 0 ],
+ [ "${vol}foo" => "/foo" => 1 ],
+ [ $vol => "/foo" => 1 ],
+ [ $vol => $other => 0 ],
+ [ "/" => $vol => 1 ],
+ [ "/" => $other => 0 ],
+ [ "/foo" => "${vol}foo" => 1 ],
+ ];
+}
+
+while (@cases) {
+ my ( $subtest, $tests ) = splice( @cases, 0, 2 );
+ subtest $subtest => sub {
+ for my $t (@$tests) {
+ my ( $path1, $path2, $subsumes ) = @$t;
+ my $label =
+ join( " ", $path1, ( $subsumes ? "subsumes" : "does not subsume" ), $path2 );
+ ok( !!path($path1)->subsumes($path2) eq !!$subsumes, $label )
+ or diag "PATH 1:\n", explain( path($path1) ), "\nPATH2:\n",
+ explain( path($path2) );
+ }
+ };
+}
+
+done_testing;
+#
+# This file is part of Path-Tiny
+#
+# This software is Copyright (c) 2013 by David Golden.
+#
+# This is free software, licensed under:
+#
+# The Apache License, Version 2.0, January 2004
+#
@@ -63,7 +63,7 @@ my @tests = (
[ "path('..')->absolute('/t1/t2/t3')", '/t1/t2/t3/..', '/t1/t2' ],
[ "path('../t4')->absolute('/t1/t2/t3')", '/t1/t2/t3/../t4', '/t1/t2/t4' ],
# need to wash through rootdir->absolute->child to pick up volume on Windows
- [ "path('/t1')->absolute('/t1/t2/t3')", Path::Tiny->rootdir->absolute->child("t1") ],
+ [ "path('/t1')->absolute('/t1/t2/t3')", Path::Tiny->rootdir->absolute->child("t1") ],
);
my @win32_tests;
@@ -119,7 +119,7 @@ if ($IS_WIN32) {
[ "path('/../')", '/' ],
[ "path('d1/../foo')", 'foo' ],
# if there's no C drive, getdcwd will probably return '', so fake it
- [ "path('C:')", path( Cwd::getdcwd("C:") || "C:/" ) ],
+ [ "path('C:')", path( eval { Cwd::getdcwd("C:") } || "C:/" ) ],
[ "path('\\\\server\\share\\')", '//server/share/' ],
[ "path('\\\\server\\share')", '//server/share/' ],
[ "path('//server/share/')", '//server/share/' ],
@@ -1,7 +1,8 @@
+use 5.006;
use strict;
use warnings;
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.037
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.039
use Test::More tests => 1 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
@@ -24,11 +25,12 @@ 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?>
- open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
my $stderr = IO::Handle->new;
my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]");
@@ -2,7 +2,7 @@ use strict;
use warnings;
use Test::More;
-# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006001
+# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006002
use Test::Spelling 0.12;
use Pod::Wordlist;
@@ -59,9 +59,6 @@ gfuji
Karen
Etheridge
ether
-Keedi
-Kim
-keedi
Martin
Kjeldsen
mk
@@ -72,6 +69,9 @@ Toby
Inkster
tobyink
κΉλν
+Keedi
+Kim
+keedi
lib
Path
Tiny
@@ -1,4 +1,5 @@
#!perl
+# This file was automatically generated by Dist::Zilla::Plugin::MetaTests.
use Test::More;
@@ -1,4 +1,5 @@
#!perl
+# This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests.
use Test::More;
@@ -1,4 +1,5 @@
#!perl
+# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
use Test::More;
eval "use Test::Pod 1.41";