Skip to content

Commit

Permalink
abs2rel and rel2abs done
Browse files Browse the repository at this point in the history
  • Loading branch information
FROGGS committed Sep 14, 2012
1 parent 72a5801 commit f9809ab
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 15 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ Methods (current state):
splitpath done
splitdir done
catpath done
abs2rel
rel2abs
abs2rel done
rel2abs done
4 changes: 2 additions & 2 deletions lib/File/Spec.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class File::Spec {
method splitpath( $path, $no_file = 0 ) { ::($module).splitpath( $path, $no_file ) }
method splitdir( $path ) { ::($module).splitdir( $path ) }
method catpath( $volume, $directoy, $file ) { ::($module).catpath( $volume, $directoy, $file ) }
method abs2rel { ::($module).abs2rel() }
method rel2abs { ::($module).rel2abs() }
method abs2rel( $path, $base = Str ) { ::($module).abs2rel( $path, $base ) }
method rel2abs( $path, $base = Str ) { ::($module).rel2abs( $path, $base ) }
}

1;
79 changes: 71 additions & 8 deletions lib/File/Spec/Unix.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class File::Spec::Unix {
return "$node$path";
}

method catdir( @parts ) { self.canonpath( (@parts, '').join('/') ) }
method catdir( *@parts ) { self.canonpath( (@parts, '').join('/') ) }

method catfile( @parts is copy ) {
method catfile( *@parts is copy ) {
my $file = self.canonpath( @parts.pop );
return $file unless @parts.elems;
my $dir = self.catdir( @parts );
Expand Down Expand Up @@ -64,7 +64,7 @@ class File::Spec::Unix {

method updir { '..' }

method no_upwards( @paths ) {
method no_upwards( *@paths ) {
my @no_upwards = grep { $_ !~~ /^[\.|\.\.]$/ }, @paths;
return @no_upwards;
}
Expand All @@ -84,7 +84,7 @@ class File::Spec::Unix {
return @path
}

method join( @parts ) {
method join( *@parts ) {
self.catfile( @parts )
}

Expand Down Expand Up @@ -121,12 +121,75 @@ class File::Spec::Unix {
return $directory
}

method abs2rel {

method abs2rel( $path is copy, $base is copy = Str ) {
$base = $*CWD unless $base.defined && $base.chars;

$path = self.canonpath( $path );
$base = self.canonpath( $base );

if self.file_name_is_absolute($path) || self.file_name_is_absolute($base) {
$path = self.rel2abs( $path );
$base = self.rel2abs( $base );
}
else {
# save a couple of cwd()s if both paths are relative
$path = self.catdir( '/', $path );
$base = self.catdir( '/', $base );
}

my ($path_volume, $path_directories) = self.splitpath( $path, 1 );
my ($base_volume, $base_directories) = self.splitpath( $base, 1 );

# Can't relativize across volumes
return $path unless $path_volume eq $base_volume;

# For UNC paths, the user might give a volume like //foo/bar that
# strictly speaking has no directory portion. Treat it as if it
# had the root directory for that volume.
if !$base_directories.chars && self.file_name_is_absolute( $base ) {
$base_directories = self.rootdir;
}

# Now, remove all leading components that are the same
my @pathchunks = self.splitdir( $path_directories );
my @basechunks = self.splitdir( $base_directories );

if $base_directories eq self.rootdir {
@pathchunks.shift;
return self.canonpath( self.catpath('', self.catdir( @pathchunks ), '') );
}

while @pathchunks && @basechunks && @pathchunks[0] eq @basechunks[0] {
@pathchunks.shift;
@basechunks.shift;
}
return self.curdir unless @pathchunks || @basechunks;

# $base now contains the directories the resulting relative path
# must ascend out of before it can descend to $path_directory.
my $result_dirs = self.catdir( self.updir() xx @basechunks.elems, @pathchunks );
return self.canonpath( self.catpath('', $result_dirs, '') );
}

method rel2abs {

method rel2abs( $path is copy, $base is copy = Str ) {
# Clean up $path
if !self.file_name_is_absolute( $path ) {
# Figure out the effective $base and clean it up.
if !$base.defined || $base eq '' {
$base = $*CWD;
}
elsif !self.file_name_is_absolute( $base ) {
$base = self.rel2abs( $base )
}
else {
$base = self.canonpath( $base )
}

# Glom them together
$path = self.catdir( $base, $path )
}

return self.canonpath( $path )
}
}

Expand Down
26 changes: 23 additions & 3 deletions t/01_unix.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use lib 'lib';
use Test;
use File::Spec;

plan 62;
plan 81;

if $*OS ~~ any(<MacOS MSWin32 os2 VMS epoc NetWare symbian dos cygwin>) {
skip_rest 'this is not Unix\'ish'
Expand Down Expand Up @@ -106,8 +106,28 @@ else {
is File::Spec.catpath('d1','d2/d3/',''), 'd2/d3/', "catpath: ('d1','d2/d3/','') -> 'd2/d3/'";
is File::Spec.catpath('d1','d2','d3/'), 'd2/d3/', "catpath: ('d1','d2','d3/') -> 'd2/d3/'";

#abs2rel
#rel2ab
is File::Spec.abs2rel('/t1/t2/t3','/t1/t2/t3'), '.', "abs2rel: ('/t1/t2/t3','/t1/t2/t3') -> '.'";
is File::Spec.abs2rel('/t1/t2/t4','/t1/t2/t3'), '../t4', "abs2rel: ('/t1/t2/t4','/t1/t2/t3') -> '../t4'";
is File::Spec.abs2rel('/t1/t2','/t1/t2/t3'), '..', "abs2rel: ('/t1/t2','/t1/t2/t3') -> '..'";
is File::Spec.abs2rel('/t1/t2/t3/t4','/t1/t2/t3'), 't4', "abs2rel: ('/t1/t2/t3/t4','/t1/t2/t3') -> 't4'";
is File::Spec.abs2rel('/t4/t5/t6','/t1/t2/t3'), '../../../t4/t5/t6', "abs2rel: ('/t4/t5/t6','/t1/t2/t3') -> '../../../t4/t5/t6'";
#[ "Unix->abs2rel('../t4','/t1/t2/t3'), '../t4', "abs2rel: ('../t4','/t1/t2/t3') -> '../t4'";
is File::Spec.abs2rel('/','/t1/t2/t3'), '../../..', "abs2rel: ('/','/t1/t2/t3') -> '../../..'";
is File::Spec.abs2rel('///','/t1/t2/t3'), '../../..', "abs2rel: ('///','/t1/t2/t3') -> '../../..'";
is File::Spec.abs2rel('/.','/t1/t2/t3'), '../../..', "abs2rel: ('/.','/t1/t2/t3') -> '../../..'";
is File::Spec.abs2rel('/./','/t1/t2/t3'), '../../..', "abs2rel: ('/./','/t1/t2/t3') -> '../../..'";
#[ "Unix->abs2rel('../t4','/t1/t2/t3'), '../t4', "abs2rel: ('../t4','/t1/t2/t3') -> '../t4'";
is File::Spec.abs2rel('/t1/t2/t3', '/'), 't1/t2/t3', "abs2rel: ('/t1/t2/t3', '/') -> 't1/t2/t3'";
is File::Spec.abs2rel('/t1/t2/t3', '/t1'), 't2/t3', "abs2rel: ('/t1/t2/t3', '/t1') -> 't2/t3'";
is File::Spec.abs2rel('t1/t2/t3', 't1'), 't2/t3', "abs2rel: ('t1/t2/t3', 't1') -> 't2/t3'";
is File::Spec.abs2rel('t1/t2/t3', 't4'), '../t1/t2/t3', "abs2rel: ('t1/t2/t3', 't4') -> '../t1/t2/t3'";

is File::Spec.rel2abs('t4','/t1/t2/t3'), '/t1/t2/t3/t4', "rel2abs: ('t4','/t1/t2/t3') -> '/t1/t2/t3/t4'";
is File::Spec.rel2abs('t4/t5','/t1/t2/t3'), '/t1/t2/t3/t4/t5', "rel2abs: ('t4/t5','/t1/t2/t3') -> '/t1/t2/t3/t4/t5'";
is File::Spec.rel2abs('.','/t1/t2/t3'), '/t1/t2/t3', "rel2abs: ('.','/t1/t2/t3') -> '/t1/t2/t3'";
is File::Spec.rel2abs('..','/t1/t2/t3'), '/t1/t2/t3/..', "rel2abs: ('..','/t1/t2/t3') -> '/t1/t2/t3/..'";
is File::Spec.rel2abs('../t4','/t1/t2/t3'), '/t1/t2/t3/../t4', "rel2abs: ('../t4','/t1/t2/t3') -> '/t1/t2/t3/../t4'";
is File::Spec.rel2abs('/t1','/t1/t2/t3'), '/t1', "rel2abs: ('/t1','/t1/t2/t3') -> '/t1'";
}

done;

0 comments on commit f9809ab

Please sign in to comment.