File Coverage

blib/lib/LedgerSMB/Installer/OS/linux/debian.pm
Criterion Covered Total %
statement 26 203 12.8
branch 0 40 0.0
condition 0 6 0.0
subroutine 9 33 27.2
pod 0 16 0.0
total 35 298 11.7


line stmt bran cond sub pod time code
1             package LedgerSMB::Installer::OS::linux::debian v0.999.11;
2              
3 1     1   2527 use v5.20;
  1         4  
4 1     1   5 use experimental qw(signatures);
  1         3  
  1         9  
5 1     1   219 use parent qw( LedgerSMB::Installer::OS::linux );
  1         2  
  1         10  
6              
7 1     1   94 use Carp qw( croak );
  1         2  
  1         60  
8 1     1   6 use English;
  1         2  
  1         11  
9 1     1   372 use HTTP::Tiny;
  1         2  
  1         14  
10 1     1   4 use JSON::PP;
  1         1  
  1         54  
11              
12 1     1   576 use Capture::Tiny qw( capture_stdout );
  1         4188  
  1         52  
13 1     1   5 use Log::Any qw($log);
  1         2  
  1         5  
14              
15 0     0 0   sub new($class, %args) {
  0            
  0            
  0            
16             return bless {
17             _distro => $args{distro},
18 0           }, $class;
19             }
20              
21 0     0 0   sub name($self) {
  0            
  0            
22 0           return $self->{_distro}->{ID};
23             }
24              
25 0     0 0   sub dependency_packages_identifier($self) {
  0            
  0            
26             my ($arch, ) = capture_stdout {
27 0     0     system( qw( dpkg --print-architecture ) );
28 0           };
29 0           chomp($arch);
30 0           return "$self->{_distro}->{ID}-$self->{_distro}->{VERSION_CODENAME}-$arch";
31             }
32              
33 0     0 0   sub pkgs_from_modules($self, $mods) {
  0            
  0            
  0            
34 0 0         if (not state $init = 0) {
35 0           $log->info( "Updating 'apt-file' packages index" );
36 0 0         system($self->{cmd}->{'apt-file'}, 'update') == 0
37             or croak $log->fatal( "Unable to update apt-file's index: $!" );
38 0           $init = 1;
39             }
40              
41 0           my $args = join(' ', $mods->@*);
42 0 0         open(my $fh, '-|',
43             "$self->{cmd}->{'dh-make-perl'} --no-verbose locate $args 2>/dev/null")
44             or return ({}, []);
45              
46 0           my (%pkgs, @unmapped);
47 0           my %found;
48 0           while (my $pkg_line = <$fh>) {
49 0 0         if ($pkg_line =~ m/^(\S+) is not found in any/) {
    0          
    0          
50 0           $found{$1} = 1;
51 0           push @unmapped, $1;
52 0           $log->trace( "Module '$1' not found" );
53             }
54             elsif ($pkg_line =~ m/^(\S+) is in (\S+)(?: \| \S+)* package/) {
55 0           $found{$1} = 1;
56 0   0       $pkgs{$2} //= [];
57 0           push $pkgs{$2}->@*, $1;
58 0           $log->trace( "Module '$1' found in package $2" );
59             }
60             elsif ($pkg_line =~ m/^(\S+) is in Perl core/) {
61 0           $found{$1} = 1;
62 0           $log->trace( "Module '$1' resolves to 'perl' package; skipping as explicit dependency" );
63             }
64             else {
65 0           $log->trace( "Unprocessed $self->{cmd}->{'dh_make_perl'} output line: " . $pkg_line );
66             }
67             }
68 0           my @skipped = grep { !$found{$_} } $mods->@*;
  0            
69 0 0         if (@skipped) {
70 0           $log->error( "Error: Modules skipped while mapping to packages: " . join(', ', @skipped ) );
71 0           push @unmapped, @skipped;
72             }
73 0           return (\%pkgs, \@unmapped);
74             }
75              
76 0     0 0   sub pkg_can_install($self) {
  0            
  0            
77 0           return ($EFFECTIVE_USER_ID == 0);
78             }
79              
80 0     0 0   sub pkg_install($self, $pkgs) {
  0            
  0            
  0            
81 0   0       $pkgs //= [];
82 0           my $apt_get = $self->have_cmd( 'apt-get' );
83 0           my @cmd;
84 0           @cmd = ($apt_get, qw( update -q -y ));
85 0           do {
86 0           local $ENV{DEBIAN_FRONTEND} = 'noninteractive';
87 0           $log->debug( "system(): " . join(' ', map { "'$_'" } @cmd ) );
  0            
88 0 0         system(@cmd) == 0
89             or croak $log->fatal( "Unable to update 'apt-get' package index: $!" );
90             };
91              
92 0           @cmd = ($apt_get, qw( install -q -y ), $pkgs->@*);
93 0           do {
94 0           local $ENV{DEBIAN_FRONTEND} = 'noninteractive';
95 0           $log->debug( "system(): " . join(' ', map { "'$_'" } @cmd ) );
  0            
96 0 0         system(@cmd) == 0
97             or croak $log->fatal( "Unable to install required packages through apt-get: $!" );
98             };
99             }
100              
101 0     0 0   sub pkg_uninstall($self, $pkgs) {
  0            
  0            
  0            
102 0   0       $pkgs //= [];
103 0           my $apt_get = $self->have_cmd( 'apt-get' );
104 0           my @cmd = ($apt_get, qw(autoremove --purge -q -y), $pkgs->@*);
105              
106 0           do {
107 0           local $ENV{DEBIAN_FRONTEND} = 'noninteractive';
108 0           $log->debug( "system(): " . join(' ', map { "'$_'" } @cmd ) );
  0            
109 0 0         system(@cmd) == 0
110             or croak $log->fatal( "Unable to uninstall packages through apt-get: $!" );
111             };
112             }
113              
114 0     0 0   sub cleanup_env($self, $config, %args) {
  0            
  0            
  0            
  0            
115 0           $self->pkg_uninstall( [ $config->pkgs_for_cleanup ] );
116             }
117              
118 0     0 0   sub prepare_builder_env($self, $config) {
  0            
  0            
  0            
119             my ($have_build_essential, ) = capture_stdout {
120 0     0     system( qw( dpkg-query -W build-essential ) );
121 0           };
122 0 0         unless (grep { m/build-essential/ } split( /\n/, $have_build_essential )) {
  0            
123 0           $config->mark_pkgs_for_cleanup( [ 'build-essential' ] );
124 0           $self->pkg_install( [ 'build-essential' ] );
125             }
126             }
127              
128 0     0 0   sub prepare_extraction_env($self, $config) {
  0            
  0            
  0            
129             my ($have_deps, ) = capture_stdout {
130 0     0     system( qw( dpkg-query -W tar gzip gpg ) );
131 0           };
132 0           my @pkgs;
133 0 0         unless (grep { m/tar/ } split(/\n/, $have_deps)) {
  0            
134 0           push @pkgs, 'tar';
135             }
136 0 0         unless (grep { m/gzip/ } split(/\n/, $have_deps)) {
  0            
137 0           push @pkgs, 'gzip';
138             }
139 0 0         if ($config->verify_sig) {
140 0 0         unless (grep { m/gpg/ } split(/\n/, $have_deps)) {
  0            
141 0           push @pkgs, 'gpg';
142             }
143             }
144 0 0         if (@pkgs) {
145 0           $config->mark_pkgs_for_cleanup( \@pkgs );
146 0           $self->pkg_install( \@pkgs );
147             }
148 0           $self->SUPER::prepare_extraction_env( $config );
149             }
150              
151 0     0 0   sub prepare_installer_env($self, $config) {
  0            
  0            
  0            
152             my ($have_make, ) = capture_stdout {
153 0     0     system( qw( dpkg-query -W make ) );
154 0           };
155 0 0         unless (grep { m/make/ } split(/\n/, $have_make)) {
  0            
156 0           $config->mark_pkgs_for_cleanup( [ 'make' ] );
157 0           $self->pkg_install( [ 'make' ] );
158             }
159 0           $self->SUPER::prepare_installer_env( $config );
160             }
161              
162 0     0 0   sub prepare_pkg_resolver_env($self, $config) {
  0            
  0            
  0            
163 0           my @new_pkgs;
164             my ($have_dh_make_perl, ) = capture_stdout {
165 0     0     system( qw( dpkg-query -W dh-make-perl ) );
166 0           };
167 0 0         unless (grep { m/dh-make-perl/ } split( /\n/, $have_dh_make_perl)) {
  0            
168 0           push @new_pkgs, 'dh-make-perl';
169             }
170             my ($have_apt_file, ) = capture_stdout {
171 0     0     system( qw( dpkg-query -W apt-file ) );
172 0           };
173 0 0         unless (grep { m/apt-file/ } split( /\n/, $have_apt_file)) {
  0            
174 0           push @new_pkgs, 'apt-file';
175             }
176 0 0         if ($config->effective_prepare_env) {
177 0           $config->mark_pkgs_for_cleanup( \@new_pkgs );
178 0           $self->pkg_install( \@new_pkgs );
179             }
180 0           $self->have_cmd( 'apt-file', $config->effective_compute_deps );
181 0           $self->have_cmd( 'dh-make-perl', $config->effective_compute_deps );
182             }
183              
184 0     0     sub _rm_installed($pkgs) {
  0            
  0            
185             my %pkgs = map {
186 0           $_ => 1
  0            
187             } $pkgs->@*;
188 0           my @cmd = (qw(dpkg-query -W), $pkgs->@*);
189             my ($installed, ) = capture_stdout {
190 0     0     system( @cmd );
191 0           };
192 0           delete $pkgs{$_} for (
193             map {
194 0           my ($pkg) = split( /\t/, $_ );
195 0           $pkg =~ s/:.*$//r;
196             } split( /\n/, $installed )
197             );
198              
199 0           return [ keys %pkgs ];
200             }
201              
202 0     0 0   sub pkg_deps_latex($self) {
  0            
  0            
203 0           return (_rm_installed([ qw(texlive-latex-recommended texlive-fonts-recommended
204             texlive-plain-generic texlive-xetex texlive-latex-extra) ]),
205             []);
206             }
207              
208 0     0 0   sub pkg_deps_xml($self) {
  0            
  0            
209 0           return (_rm_installed([ qw(libxml2) ]),
210             _rm_installed([ qw(libxml2-dev) ]));
211             }
212              
213 0     0 0   sub pkg_deps_expat($self) {
  0            
  0            
214 0           return (_rm_installed([ qw(libexpat1) ]),
215             _rm_installed([ qw(libexpat1-dev) ]));
216             }
217              
218 0     0 0   sub pkg_deps_dbd_pg($self) {
  0            
  0            
219 0           return (_rm_installed([ qw(libpq5) ]),
220             _rm_installed([ qw(libpq-dev) ]));
221             }
222              
223             1;