File Coverage

blib/lib/CPANPLUS/Dist/Debora/Package/Tar.pm
Criterion Covered Total %
statement 112 137 81.7
branch 19 40 47.5
condition 3 3 100.0
subroutine 23 26 88.4
pod 4 4 100.0
total 161 210 76.6


line stmt bran cond sub pod time code
1             package CPANPLUS::Dist::Debora::Package::Tar;
2              
3             # SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later
4              
5 3     3   3150 use 5.016;
  3         17  
6 3     3   16 use warnings;
  3         6  
  3         97  
7 3     3   16 use utf8;
  3         6  
  3         28  
8              
9             our $VERSION = '0.011';
10              
11 3     3   574 use parent qw(CPANPLUS::Dist::Debora::Package);
  3         320  
  3         20  
12              
13 3     3   2543 use Archive::Tar qw(COMPRESS_GZIP);
  3         261425  
  3         224  
14 3     3   34 use Archive::Tar::Constant qw(DIR);
  3         14  
  3         192  
15 3     3   19 use Carp qw(croak);
  3         16  
  3         121  
16 3     3   25 use Config;
  3         11  
  3         108  
17 3     3   18 use Cwd qw(cwd);
  3         9  
  3         137  
18 3     3   18 use English qw(-no_match_vars);
  3         9  
  3         72  
19 3     3   1315 use File::Spec::Functions qw(catdir catfile);
  3         8  
  3         234  
20              
21 3     3   23 use CPANPLUS::Dist::Debora::Util qw(can_run run unix_path is_testing);
  3         14  
  3         4661  
22              
23             sub format_priority {
24 2     2 1 7 my $class = shift;
25              
26 2         6 my @commands = qw(tar);
27              
28 2         6 my $priority = 0;
29 2 50       6 if (@commands == grep { can_run($_) } @commands) {
  2         9  
30 2         602 $priority = 1;
31             }
32              
33 2 50       14 if (is_testing) {
34 2         7 $priority = ~0;
35             }
36              
37 2         14 return $priority;
38             }
39              
40             sub create {
41 0     0 1 0 my ($self, %options) = @_;
42              
43 0         0 my $ok = 0;
44              
45 0         0 my $tar = $self->_tar_create;
46 0 0       0 if (defined $tar) {
47 0         0 $ok = $tar->write($self->outputname, COMPRESS_GZIP);
48             }
49              
50 0         0 return $ok;
51             }
52              
53             sub install {
54 0     0 1 0 my ($self, %options) = @_;
55              
56 0         0 my $sudo_cmd = $self->sudo_cmd;
57 0         0 my @install_cmd = ($sudo_cmd, qw(tar -C / -xvzf), $self->outputname);
58              
59 0         0 my $ok = 0;
60 0 0       0 if (is_testing) {
61 0         0 my $tar = Archive::Tar->new($self->outputname, COMPRESS_GZIP);
62 0 0       0 if (defined $tar) {
63 0         0 $ok = 1;
64 0         0 my @properties = qw(mode uname gname size mtime prefix name);
65 0         0 for my $file ($tar->list_files([@properties])) {
66 0 0       0 say $self->_format_file($file) or $ok = 0;
67             }
68             }
69             }
70             else {
71 0         0 $ok = run(command => \@install_cmd, verbose => $options{verbose});
72             }
73              
74 0         0 return $ok;
75             }
76              
77             sub outputname {
78 1     1 1 6702 my $self = shift;
79              
80             my $outputname = $self->_read(
81             'outputname',
82             sub {
83 1     1   17 catfile($self->outputdir,
84             $self->name . q{-}
85             . $self->version . q{-}
86             . $self->build_number
87             . q{.tar.gz});
88             }
89 1         34 );
90              
91 1         16 return $outputname;
92             }
93              
94             sub _docdir {
95 7     7   19 my $self = shift;
96              
97             my $docdir = $self->_read(
98             '_docdir',
99             sub {
100 1     1   18 catdir($Config{$self->installdirs . 'prefix'},
101             'share', 'doc', $self->name);
102             }
103 7         58 );
104              
105 7         47 return $docdir;
106             }
107              
108             sub _clamp_mtime {
109 13     13   29 my ($self, $tarfile) = @_;
110              
111 13         39 my $last_modification = $self->last_modification;
112 13 100       35 if ($tarfile->mtime > $last_modification) {
113 7         65 $tarfile->mtime($last_modification);
114             }
115              
116 13         118 return;
117             }
118              
119             sub _add_dir {
120 1     1   7 my ($self, $tar, $dir) = @_;
121              
122 1         96 my %properties = (
123             type => DIR,
124             mode => oct '0755',
125             uid => 0,
126             gid => 0,
127             uname => 'root',
128             gname => 'root',
129             mtime => $self->last_modification,
130             );
131              
132 1         23 my $tarfile = $tar->add_data(catdir(q{.}, $dir), q{}, \%properties);
133              
134 1         511 return $tarfile;
135             }
136              
137             sub _add_file {
138 7     7   26 my ($self, $tar, $path) = @_;
139              
140 7         40 my ($tarfile) = $tar->add_files(catfile(q{.}, $path));
141 7 50       2354 if (defined $tarfile) {
142 7         23 $tarfile->chown('root', 'root');
143 7         227 $self->_clamp_mtime($tarfile);
144             }
145              
146 7         19 return $tarfile;
147             }
148              
149             sub _add_doc {
150 6     6   15 my ($self, $tar, $path) = @_;
151              
152 6         13 my $docdir = $self->_docdir;
153 6         17 my $file = substr $path, length $self->builddir;
154 6         45 my $new_name = unix_path(catfile(q{.}, $docdir, $file));
155              
156 6         24 my ($tarfile) = $tar->add_files($path);
157 6 50       2981 if (defined $tarfile) {
158 6         22 $tarfile->chown('root', 'root');
159 6         248 $tarfile->rename($new_name);
160 6         493 $self->_clamp_mtime($tarfile);
161             }
162              
163 6         14 return $tarfile;
164             }
165              
166             sub _add_docdir {
167 1     1   4 my ($self, $tar, $dir) = @_;
168              
169 1 50       31 opendir my $dh, $dir or croak "Could not traverse '$dir': $OS_ERROR";
170             ENTRY:
171 1         24 while (defined(my $entry = readdir $dh)) {
172 3 100 100     30 next ENTRY if $entry eq q{.} || $entry eq q{..};
173              
174 1         14 my $path = catfile($dir, $entry);
175              
176             # Skip symbolic links.
177 1 50       20 next ENTRY if -l $path;
178              
179 1         12 $self->_add_doc($tar, $path);
180              
181 1 50       26 if (-d $path) {
182 0         0 $self->_add_docdir($tar, $path);
183             }
184             }
185 1         11 closedir $dh;
186              
187 1         8 return;
188             }
189              
190             sub _tar_create {
191 1     1   10 my $self = shift;
192              
193 1         9 my $builddir = $self->builddir;
194 1         8 my $stagingdir = $self->stagingdir;
195              
196 1         7 my $tar;
197              
198 1         4635 my $origdir = cwd;
199 1 50       52 if (chdir $stagingdir) {
200 1         73 $tar = Archive::Tar->new;
201              
202 1         70 my %is_doc = map { $_ => 1 } qw(changelog doc license);
  3         44  
203              
204 1         14 my $is_first = 1;
205 1         6 for my $file (@{$self->files}) {
  1         103  
206 12         29 my $name = $file->{name};
207 12         24 my $type = $file->{type};
208              
209 12 100       28 if ($is_doc{$type}) {
210 5 100       13 if ($is_first) {
211 1         25 $self->_add_dir($tar, $self->_docdir);
212 1         44 $is_first = 0;
213             }
214              
215 5         31 my $path = catfile($builddir, $name);
216 5         29 my $tarfile = $self->_add_doc($tar, $path);
217              
218 5 100       87 if (-d $path) {
219 1         17 $self->_add_docdir($tar, $path);
220             }
221             }
222             else {
223 7         39 $self->_add_file($tar, $name);
224             }
225             }
226              
227 1 50       19 if (!chdir $origdir) {
228 0         0 undef $tar;
229             }
230             }
231              
232 1         13 return $tar;
233             }
234              
235             sub _format_file {
236 0     0     my ($self, $file) = @_;
237              
238 0           my (undef, $min, $hour, $mday, $mon, $year) = localtime $file->{mtime};
239             my $string = sprintf '%s%s %s/%s %10d %d-%02d-%02d %02d:%02d %s/%s',
240             $file->{name} =~ m{/\z}xms ? q{d} : q{-},
241             $file->{mode} & oct '0111' ? 'rwxr-xr-x' : 'rw-r--r--',
242             $file->{uname}, $file->{gname}, $file->{size},
243             $year + 1900, $mon + 1, $mday, $hour, $min, $file->{prefix},
244 0 0         $file->{name};
    0          
245 0           return $string;
246             }
247              
248             1;
249             __END__