Stow
view release on metacpan or search on metacpan
lib/Stow/Util.pm.in view on Meta::CPAN
# : '//' => '/', and 'a/b/../c' => 'a/c'. We need this function
# : with this behaviour, even though b could be a symlink to
# : elsewhere, as noted in the perldoc for File::Spec->canonpath().
# : This behaviour is deliberately different to
# : Stow::Util::canon_path(), because the way join_paths() is used
# : relies on this. Firstly, there is no guarantee that the paths
# : exist, so a filesystem check is inappropriate.
# :
# : For example, it's used to determine the path from the target
# : directory to a symlink destination. So if a symlink
# : path/to/target/a/b/c points to ../../../stow/pkg/a/b/c,
# : then joining path/to/target/a/b with ../../../stow/pkg/a/b/c
# : yields path/to/stow/pkg/a/b/c, and it's crucial that the
# : path/to/stow prefix matches a recognisable stow directory.
#============================================================================
sub join_paths {
my @paths = @_;
debug(5, 5, "| Joining: @paths");
my $result = '';
for my $part (@paths) {
next if ! length $part; # probably shouldn't happen?
$part = File::Spec->canonpath($part);
if (substr($part, 0, 1) eq '/') {
$result = $part; # absolute path, so ignore all previous parts
}
else {
$result .= '/' if length $result && $result ne '/';
$result .= $part;
}
debug(7, 6, "| Join now: $result");
}
debug(6, 5, "| Joined: $result");
# Need this to remove any initial ./
$result = File::Spec->canonpath($result);
# remove foo/..
1 while $result =~ s,(^|/)(?!\.\.)[^/]+/\.\.(/|$),$1,;
debug(6, 5, "| After .. removal: $result");
$result = File::Spec->canonpath($result);
debug(5, 5, "| Final join: $result");
return $result;
}
#===== METHOD ===============================================================
# Name : parent
# Purpose : find the parent of the given path
# Parameters: @path => components of the path
# Returns : returns a path string
# Throws : n/a
# Comments : allows you to send multiple chunks of the path
# : (this feature is currently not used)
#============================================================================
sub parent {
my @path = @_;
my $path = join '/', @_;
my @elts = split m{/+}, $path;
pop @elts;
return join '/', @elts;
}
#===== METHOD ===============================================================
# Name : canon_path
# Purpose : find absolute canonical path of given path
# Parameters: $path
# Returns : absolute canonical path
# Throws : n/a
# Comments : is this significantly different from File::Spec->rel2abs?
#============================================================================
sub canon_path {
my ($path) = @_;
my $cwd = getcwd();
chdir($path) or error("canon_path: cannot chdir to $path from $cwd");
my $canon_path = getcwd();
restore_cwd($cwd);
return $canon_path;
}
sub restore_cwd {
my ($prev) = @_;
chdir($prev) or error("Your current directory $prev seems to have vanished");
}
sub adjust_dotfile {
my ($pkg_node) = @_;
(my $adjusted = $pkg_node) =~ s/^dot-([^.])/.$1/;
return $adjusted;
}
# Needed when unstowing with --compat and --dotfiles
sub unadjust_dotfile {
my ($target_node) = @_;
return $target_node if $target_node =~ /^\.\.?$/;
(my $adjusted = $target_node) =~ s/^\./dot-/;
return $adjusted;
}
=head1 BUGS
=head1 SEE ALSO
=cut
1;
# Local variables:
# mode: perl
# end:
# vim: ft=perl
( run in 1.264 second using v1.01-cache-2.11-cpan-71847e10f99 )