File Coverage

blib/lib/File/Symlink/Util.pm
Criterion Covered Total %
statement 38 56 67.8
branch 9 18 50.0
condition n/a
subroutine 9 9 100.0
pod 3 3 100.0
total 59 86 68.6


line stmt bran cond sub pod time code
1             package File::Symlink::Util;
2              
3 1     1   71553 use 5.010001;
  1         14  
4 1     1   5 use strict;
  1         2  
  1         18  
5 1     1   5 use warnings;
  1         2  
  1         23  
6 1     1   1774 use Log::ger;
  1         52  
  1         4  
7              
8 1     1   244 use Exporter 'import';
  1         2  
  1         26  
9 1     1   5 use File::Spec;
  1         2  
  1         487  
10              
11             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
12             our $DATE = '2021-12-02'; # DATE
13             our $DIST = 'File-Symlink-Util'; # DIST
14             our $VERSION = '0.001'; # VERSION
15              
16             our @EXPORT_OK = qw(
17             symlink_rel
18             symlink_abs
19             adjust_rel_symlink
20             );
21              
22              
23             sub symlink_rel {
24 2     2 1 3770 my ($dest_path, $link_path) = @_;
25 2         255 symlink(File::Spec->abs2rel($dest_path), $link_path);
26             }
27              
28             sub symlink_abs {
29 2     2 1 3634 my ($dest_path, $link_path) = @_;
30 2         120 symlink(File::Spec->rel2abs($dest_path), $link_path);
31             }
32              
33             sub adjust_rel_symlink {
34 1     1 1 2887 require File::Basename;
35 1         540 require Path::Naive;
36              
37 1         1148 my ($link_path1, $link_path2) = @_;
38              
39 1 50       16 unless (-l $link_path1) {
40 0         0 log_warn "First path '$link_path1' is not a symlink, skipping adjusting";
41 0         0 return;
42             }
43 1 50       12 unless (-l $link_path2) {
44 0         0 log_warn "Second path '$link_path2' is not a symlink, skipping adjusting";
45 0         0 return;
46             }
47              
48 1         16 my $dest_path1 = readlink $link_path1;
49 1 50       5 if (!defined $dest_path1) {
50 0         0 log_warn "Cannot read first symlink %s, skipping adjusting", $link_path1;
51 0         0 return;
52             }
53 1         24 my $dest_path2 = readlink $link_path2;
54 1 50       5 if (!defined $dest_path2) {
55 0         0 log_warn "Cannot read second symlink %s, skipping adjusting", $link_path2;
56 0         0 return;
57             }
58              
59 1 50       19 if (File::Spec->file_name_is_absolute($dest_path1)) {
60 0         0 log_trace "First symlink %s (target '%s') is not relative path, skipping adjusting", $link_path1, $dest_path1;
61 0         0 return;
62             }
63 1 50       7 if (File::Spec->file_name_is_absolute($dest_path2)) {
64 0         0 log_trace "Second symlink %s (target '%s') is not relative path, skipping adjusting", $link_path2, $dest_path2;
65 0         0 return;
66             }
67 1         197 my $new_dest_path2 = Path::Naive::normalize_path(
68             File::Spec->abs2rel(
69             (File::Spec->rel2abs($dest_path1, File::Basename::dirname($link_path1))),
70             File::Spec->rel2abs(File::Basename::dirname(File::Spec->rel2abs($link_path2)), "/"), # XXX "/" is unixism
71             )
72             );
73 1 50       60 if ($dest_path2 eq $new_dest_path2) {
74 0         0 log_trace "Skipping adjusting second symlink %s (no change: %s)", $link_path2, $new_dest_path2;
75 0         0 return;
76             }
77 1 50       62 unlink $link_path2 or do {
78 0         0 log_error "Cannot adjust second symlink %s (can't unlink: %s)", $link_path2, $!;
79 0         0 return;
80             };
81 1 50       34 symlink($new_dest_path2, $link_path2) or do {
82 0         0 log_error "Cannot adjust second symlink %s (can't symlink to '%s': %s)", $link_path2, $new_dest_path2, $!;
83 0         0 return;
84             };
85 1         8 log_trace "Adjusted symlink %s (from target '%s' to target '%s')", $link_path2, $dest_path2, $new_dest_path2;
86 1         6 1;
87             }
88              
89             1;
90             # ABSTRACT: Utilities related to symbolic links
91              
92             __END__