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   2507 use 5.016;
  3         15  
6 3     3   14 use warnings;
  3         6  
  3         71  
7 3     3   12 use utf8;
  3         6  
  3         21  
8              
9             our $VERSION = '0.010';
10              
11 3     3   474 use parent qw(CPANPLUS::Dist::Debora::Package);
  3         298  
  3         16  
12              
13 3     3   2203 use Archive::Tar qw(COMPRESS_GZIP);
  3         219996  
  3         218  
14 3     3   26 use Archive::Tar::Constant qw(DIR);
  3         11  
  3         172  
15 3     3   28 use Carp qw(croak);
  3         9  
  3         110  
16 3     3   15 use Config;
  3         9  
  3         103  
17 3     3   18 use Cwd qw(cwd);
  3         7  
  3         112  
18 3     3   15 use English qw(-no_match_vars);
  3         6  
  3         35  
19 3     3   999 use File::Spec::Functions qw(catdir catfile);
  3         9  
  3         226  
20              
21 3     3   22 use CPANPLUS::Dist::Debora::Util qw(can_run run unix_path is_testing);
  3         5  
  3         4051  
22              
23             sub format_priority {
24 2     2 1 5 my $class = shift;
25              
26 2         6 my @commands = qw(tar);
27              
28 2         3 my $priority = 0;
29 2 50       4 if (@commands == grep { can_run($_) } @commands) {
  2         6  
30 2         538 $priority = 1;
31             }
32              
33 2 50       10 if (is_testing) {
34 2         5 $priority = ~0;
35             }
36              
37 2         11 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 6022 my $self = shift;
79              
80             my $outputname = $self->_read(
81             'outputname',
82             sub {
83 1     1   11 catfile($self->outputdir,
84             $self->name . q{-}
85             . $self->version . q{-}
86             . $self->build_number
87             . q{.tar.gz});
88             }
89 1         31 );
90              
91 1         20 return $outputname;
92             }
93              
94             sub _docdir {
95 7     7   16 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         39 return $docdir;
106             }
107              
108             sub _clamp_mtime {
109 13     13   28 my ($self, $tarfile) = @_;
110              
111 13         32 my $last_modification = $self->last_modification;
112 13 100       27 if ($tarfile->mtime > $last_modification) {
113 7         55 $tarfile->mtime($last_modification);
114             }
115              
116 13         98 return;
117             }
118              
119             sub _add_dir {
120 1     1   7 my ($self, $tar, $dir) = @_;
121              
122 1         108 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         20 my $tarfile = $tar->add_data(catdir(q{.}, $dir), q{}, \%properties);
133              
134 1         459 return $tarfile;
135             }
136              
137             sub _add_file {
138 7     7   18 my ($self, $tar, $path) = @_;
139              
140 7         31 my ($tarfile) = $tar->add_files(catfile(q{.}, $path));
141 7 50       1954 if (defined $tarfile) {
142 7         27 $tarfile->chown('root', 'root');
143 7         169 $self->_clamp_mtime($tarfile);
144             }
145              
146 7         16 return $tarfile;
147             }
148              
149             sub _add_doc {
150 6     6   18 my ($self, $tar, $path) = @_;
151              
152 6         16 my $docdir = $self->_docdir;
153 6         18 my $file = substr $path, length $self->builddir;
154 6         39 my $new_name = unix_path(catfile(q{.}, $docdir, $file));
155              
156 6         20 my ($tarfile) = $tar->add_files($path);
157 6 50       2505 if (defined $tarfile) {
158 6         24 $tarfile->chown('root', 'root');
159 6         152 $tarfile->rename($new_name);
160 6         372 $self->_clamp_mtime($tarfile);
161             }
162              
163 6         13 return $tarfile;
164             }
165              
166             sub _add_docdir {
167 1     1   5 my ($self, $tar, $dir) = @_;
168              
169 1 50       34 opendir my $dh, $dir or croak "Could not traverse '$dir': $OS_ERROR";
170             ENTRY:
171 1         26 while (defined(my $entry = readdir $dh)) {
172 3 100 100     30 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       16 next ENTRY if -l $path;
178              
179 1         5 $self->_add_doc($tar, $path);
180              
181 1 50       19 if (-d $path) {
182 0         0 $self->_add_docdir($tar, $path);
183             }
184             }
185 1         11 closedir $dh;
186              
187 1         7 return;
188             }
189              
190             sub _tar_create {
191 1     1   4 my $self = shift;
192              
193 1         13 my $builddir = $self->builddir;
194 1         4 my $stagingdir = $self->stagingdir;
195              
196 1         6 my $tar;
197              
198 1         5206 my $origdir = cwd;
199 1 50       61 if (chdir $stagingdir) {
200 1         51 $tar = Archive::Tar->new;
201              
202 1         86 my %is_doc = map { $_ => 1 } qw(changelog doc license);
  3         41  
203              
204 1         9 my $is_first = 1;
205 1         3 for my $file (@{$self->files}) {
  1         40  
206 12         27 my $name = $file->{name};
207 12         20 my $type = $file->{type};
208              
209 12 100       25 if ($is_doc{$type}) {
210 5 100       12 if ($is_first) {
211 1         27 $self->_add_dir($tar, $self->_docdir);
212 1         49 $is_first = 0;
213             }
214              
215 5         36 my $path = catfile($builddir, $name);
216 5         17 my $tarfile = $self->_add_doc($tar, $path);
217              
218 5 100       76 if (-d $path) {
219 1         14 $self->_add_docdir($tar, $path);
220             }
221             }
222             else {
223 7         35 $self->_add_file($tar, $name);
224             }
225             }
226              
227 1 50       18 if (!chdir $origdir) {
228 0         0 undef $tar;
229             }
230             }
231              
232 1         12 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__