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   3132 use 5.016;
  3         18  
6 3     3   17 use warnings;
  3         6  
  3         97  
7 3     3   15 use utf8;
  3         6  
  3         19  
8              
9             our $VERSION = '0.009';
10              
11 3     3   587 use parent qw(CPANPLUS::Dist::Debora::Package);
  3         326  
  3         17  
12              
13 3     3   2614 use Archive::Tar qw(COMPRESS_GZIP);
  3         261636  
  3         259  
14 3     3   34 use Archive::Tar::Constant qw(DIR);
  3         8  
  3         208  
15 3     3   24 use Carp qw(croak);
  3         9  
  3         128  
16 3     3   19 use Config;
  3         9  
  3         107  
17 3     3   19 use Cwd qw(cwd);
  3         9  
  3         130  
18 3     3   18 use English qw(-no_match_vars);
  3         6  
  3         28  
19 3     3   1294 use File::Spec::Functions qw(catdir catfile);
  3         9  
  3         224  
20              
21 3     3   37 use CPANPLUS::Dist::Debora::Util qw(can_run run unix_path is_testing);
  3         8  
  3         4615  
22              
23             sub format_priority {
24 2     2 1 7 my $class = shift;
25              
26 2         8 my @commands = qw(tar);
27              
28 2         4 my $priority = 0;
29 2 50       7 if (@commands == grep { can_run($_) } @commands) {
  2         8  
30 2         668 $priority = 1;
31             }
32              
33 2 50       18 if (is_testing) {
34 2         5 $priority = ~0;
35             }
36              
37 2         16 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 6299 my $self = shift;
79              
80             my $outputname = $self->_read(
81             'outputname',
82             sub {
83 1     1   10 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         14 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   23 catdir($Config{$self->installdirs . 'prefix'},
101             'share', 'doc', $self->name);
102             }
103 7         70 );
104              
105 7         54 return $docdir;
106             }
107              
108             sub _clamp_mtime {
109 13     13   34 my ($self, $tarfile) = @_;
110              
111 13         40 my $last_modification = $self->last_modification;
112 13 100       33 if ($tarfile->mtime > $last_modification) {
113 7         68 $tarfile->mtime($last_modification);
114             }
115              
116 13         119 return;
117             }
118              
119             sub _add_dir {
120 1     1   18 my ($self, $tar, $dir) = @_;
121              
122 1         97 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         22 my $tarfile = $tar->add_data(catdir(q{.}, $dir), q{}, \%properties);
133              
134 1         507 return $tarfile;
135             }
136              
137             sub _add_file {
138 7     7   27 my ($self, $tar, $path) = @_;
139              
140 7         39 my ($tarfile) = $tar->add_files(catfile(q{.}, $path));
141 7 50       2343 if (defined $tarfile) {
142 7         34 $tarfile->chown('root', 'root');
143 7         207 $self->_clamp_mtime($tarfile);
144             }
145              
146 7         18 return $tarfile;
147             }
148              
149             sub _add_doc {
150 6     6   21 my ($self, $tar, $path) = @_;
151              
152 6         113 my $docdir = $self->_docdir;
153 6         22 my $file = substr $path, length $self->builddir;
154 6         60 my $new_name = unix_path(catfile(q{.}, $docdir, $file));
155              
156 6         27 my ($tarfile) = $tar->add_files($path);
157 6 50       2992 if (defined $tarfile) {
158 6         23 $tarfile->chown('root', 'root');
159 6         194 $tarfile->rename($new_name);
160 6         460 $self->_clamp_mtime($tarfile);
161             }
162              
163 6         13 return $tarfile;
164             }
165              
166             sub _add_docdir {
167 1     1   4 my ($self, $tar, $dir) = @_;
168              
169 1 50       28 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     32 next ENTRY if $entry eq q{.} || $entry eq q{..};
173              
174 1         8 my $path = catfile($dir, $entry);
175              
176             # Skip symbolic links.
177 1 50       18 next ENTRY if -l $path;
178              
179 1         6 $self->_add_doc($tar, $path);
180              
181 1 50       24 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   5 my $self = shift;
192              
193 1         10 my $builddir = $self->builddir;
194 1         5 my $stagingdir = $self->stagingdir;
195              
196 1         3 my $tar;
197              
198 1         5280 my $origdir = cwd;
199 1 50       58 if (chdir $stagingdir) {
200 1         57 $tar = Archive::Tar->new;
201              
202 1         50 my %is_doc = map { $_ => 1 } qw(changelog doc license);
  3         38  
203              
204 1         11 my $is_first = 1;
205 1         9 for my $file (@{$self->files}) {
  1         43  
206 12         35 my $name = $file->{name};
207 12         20 my $type = $file->{type};
208              
209 12 100       30 if ($is_doc{$type}) {
210 5 100       11 if ($is_first) {
211 1         28 $self->_add_dir($tar, $self->_docdir);
212 1         58 $is_first = 0;
213             }
214              
215 5         34 my $path = catfile($builddir, $name);
216 5         32 my $tarfile = $self->_add_doc($tar, $path);
217              
218 5 100       95 if (-d $path) {
219 1         14 $self->_add_docdir($tar, $path);
220             }
221             }
222             else {
223 7         40 $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__