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   8109 use 5.016;
  3         9  
6 3     3   16 use warnings;
  3         8  
  3         203  
7 3     3   13 use utf8;
  3         5  
  3         17  
8              
9             our $VERSION = '0.018';
10              
11 3     3   480 use parent qw(CPANPLUS::Dist::Debora::Package);
  3         275  
  3         17  
12              
13 3     3   2599 use Archive::Tar qw(COMPRESS_GZIP);
  3         259896  
  3         365  
14 3     3   35 use Archive::Tar::Constant qw(DIR);
  3         7  
  3         269  
15 3     3   21 use Carp qw(croak);
  3         37  
  3         171  
16 3     3   29 use Config;
  3         7  
  3         131  
17 3     3   19 use Cwd qw(cwd);
  3         7  
  3         162  
18 3     3   17 use English qw(-no_match_vars);
  3         7  
  3         29  
19 3     3   1309 use File::Spec::Functions qw(catdir catfile);
  3         6  
  3         282  
20              
21 3     3   20 use CPANPLUS::Dist::Debora::Util qw(can_run run unix_path is_testing);
  3         8  
  3         5209  
22              
23             sub format_priority {
24 2     2 1 6 my $class = shift;
25              
26 2         6 my @commands = qw(tar);
27              
28 2         4 my $priority = 0;
29 2 50       6 if (@commands == grep { can_run($_) } @commands) {
  2         6  
30 2         917 $priority = 1;
31             }
32              
33 2 50       13 if (is_testing) {
34 2         7 $priority = ~0;
35             }
36              
37 2         15 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 6969 my $self = shift;
79              
80             my $outputname = $self->_read(
81             'outputname',
82             sub {
83 1     1   8 catfile($self->outputdir,
84             $self->name . q{-}
85             . $self->version . q{-}
86             . $self->build_number
87             . q{.tar.gz});
88             }
89 1         24 );
90              
91 1         15 return $outputname;
92             }
93              
94             sub _docdir {
95 7     7   10 my $self = shift;
96              
97             my $docdir = $self->_read(
98             '_docdir',
99             sub {
100 1     1   15 catdir($Config{$self->installdirs . 'prefix'},
101             'share', 'doc', $self->name);
102             }
103 7         42 );
104              
105 7         35 return $docdir;
106             }
107              
108             sub _clamp_mtime {
109 13     13   21 my ($self, $tarfile) = @_;
110              
111 13         29 my $last_modification = $self->last_modification;
112 13 100       22 if ($tarfile->mtime > $last_modification) {
113 7         42 $tarfile->mtime($last_modification);
114             }
115              
116 13         73 return;
117             }
118              
119             sub _add_dir {
120 1     1   2 my ($self, $tar, $dir) = @_;
121              
122 1         8 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         16 my $tarfile = $tar->add_data(catdir(q{.}, $dir), q{}, \%properties);
133              
134 1         363 return $tarfile;
135             }
136              
137             sub _add_file {
138 7     7   10 my ($self, $tar, $path) = @_;
139              
140 7         27 my ($tarfile) = $tar->add_files(catfile(q{.}, $path));
141 7 50       1542 if (defined $tarfile) {
142 7         15 $tarfile->chown('root', 'root');
143 7         126 $self->_clamp_mtime($tarfile);
144             }
145              
146 7         15 return $tarfile;
147             }
148              
149             sub _add_doc {
150 6     6   10 my ($self, $tar, $path) = @_;
151              
152 6         11 my $docdir = $self->_docdir;
153 6         13 my $file = substr $path, length $self->builddir;
154 6         34 my $new_name = unix_path(catfile(q{.}, $docdir, $file));
155              
156 6         19 my ($tarfile) = $tar->add_files($path);
157 6 50       2126 if (defined $tarfile) {
158 6         21 $tarfile->chown('root', 'root');
159 6         122 $tarfile->rename($new_name);
160 6         259 $self->_clamp_mtime($tarfile);
161             }
162              
163 6         12 return $tarfile;
164             }
165              
166             sub _add_docdir {
167 1     1   3 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         20 while (defined(my $entry = readdir $dh)) {
172 3 100 100     16 next ENTRY if $entry eq q{.} || $entry eq q{..};
173              
174 1         7 my $path = catfile($dir, $entry);
175              
176             # Skip symbolic links.
177 1 50       13 next ENTRY if -l $path;
178              
179 1         3 $self->_add_doc($tar, $path);
180              
181 1 50       27 if (-d $path) {
182 0         0 $self->_add_docdir($tar, $path);
183             }
184             }
185 1         8 closedir $dh;
186              
187 1         6 return;
188             }
189              
190             sub _tar_create {
191 1     1   7 my $self = shift;
192              
193 1         11 my $builddir = $self->builddir;
194 1         4 my $stagingdir = $self->stagingdir;
195              
196 1         3 my $tar;
197              
198 1         9196 my $origdir = cwd;
199 1 50       31 if (chdir $stagingdir) {
200 1         31 $tar = Archive::Tar->new;
201              
202 1         32 my %is_doc = map { $_ => 1 } qw(changelog doc license);
  3         25  
203              
204 1         3 my $is_first = 1;
205 1         5 for my $file (@{$self->files}) {
  1         27  
206 12         17 my $name = $file->{name};
207 12         18 my $type = $file->{type};
208              
209 12 100       21 if ($is_doc{$type}) {
210 5 100       9 if ($is_first) {
211 1         18 $self->_add_dir($tar, $self->_docdir);
212 1         2 $is_first = 0;
213             }
214              
215 5         16 my $path = catfile($builddir, $name);
216 5         15 my $tarfile = $self->_add_doc($tar, $path);
217              
218 5 100       65 if (-d $path) {
219 1         15 $self->_add_docdir($tar, $path);
220             }
221             }
222             else {
223 7         20 $self->_add_file($tar, $name);
224             }
225             }
226              
227 1 50       14 if (!chdir $origdir) {
228 0         0 undef $tar;
229             }
230             }
231              
232 1         8 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__