]> wagnertech.de Git - mfinanz.git/blob - scripts/installation_check.pl
restart apache2 in postinst
[mfinanz.git] / scripts / installation_check.pl
1 #!/usr/bin/perl -w
2
3 our $master_templates;
4 BEGIN {
5   use FindBin;
6
7   unshift(@INC, $FindBin::Bin . '/../modules/override'); # Use our own versions of various modules (e.g. YAML).
8   push   (@INC, $FindBin::Bin . '/..');                  # '.' will be removed from @INC soon.
9
10   # this is a default dir. may be wrong in your installation, change it then
11   $master_templates = $FindBin::Bin . '/../templates/print/';
12 }
13
14 use strict;
15 use Getopt::Long;
16 use Pod::Usage;
17 use Term::ANSIColor;
18 use Text::Wrap;
19
20 my $exit_code = 0;
21 unless (eval { require Config::Std; 1 }){
22   print STDERR <<EOL ;
23 +------------------------------------------------------------------------------+
24   Perl Modul Config::Std could not be loaded.
25
26   Debian: you may install the needed *.deb package with:
27     apt-get install libconfig-std-perl
28
29   Red Hat/Fedora/CentOS: you may install the needed *.rpm package with:
30     yum install perl-Config-Std
31
32   SUSE: you may install the needed *.rpm package with:
33     zypper install perl-Config-Std
34
35 +------------------------------------------------------------------------------+
36 EOL
37
38   $exit_code = 72;
39 }
40
41
42 unless (eval { require List::MoreUtils; 1 }){
43   print STDERR <<EOL ;
44 +------------------------------------------------------------------------------+
45   Perl Modul List::MoreUtils could not be loaded.
46
47   Debian: you may install the needed *.deb package with:
48     apt install liblist-moreutils-perl
49
50   Red Hat/Fedora/CentOS: you may install the needed *.rpm package with:
51     dnf install perl-List-MoreUtils
52
53
54 +------------------------------------------------------------------------------+
55 EOL
56
57   $exit_code = 72;
58 }
59
60 exit $exit_code if $exit_code;
61
62 use SL::InstallationCheck;
63 use SL::LxOfficeConf;
64
65 my @missing_modules;
66 my %check;
67 Getopt::Long::Configure ("bundling");
68 GetOptions(
69   "v|verbose"   => \ my $v,
70   "a|all"       => \ $check{a},
71   "o|optional!" => \ $check{o},
72   "d|devel!"    => \ $check{d},
73   "l|latex!"    => \ $check{l},
74   "r|required!" => \ $check{r},
75   "h|help"      => sub { pod2usage(-verbose => 2) },
76   "c|color!"    => \ ( my $c = 1 ),
77   "i|install-command!"  => \ my $apt,
78   "s|silent"    => \ $check{s},
79 );
80
81 my %install_methods = (
82   apt    => { key => 'debian', install => 'sudo apt install', system => "Debian, Ubuntu" },
83   yum    => { key => 'fedora', install => 'sudo yum install',     system => "RHEL, Fedora, CentOS" },
84   zypper => { key => 'suse',   install => 'sudo zypper install',  system => "SLES, openSUSE" },
85   cpan   => { key => 'name',   install => "sudo cpan",            system => "CPAN" },
86 );
87
88 # if nothing is requested check "required"
89 my $default_run;
90 if (!defined $check{a}
91  && !defined $check{l}
92  && !defined $check{o}
93  && !defined $check{d}) {
94   $check{r} = 1;
95   $default_run ='1';  # no parameter, therefore print a note after default run
96 }
97
98 if ($check{a}) {
99   $check{$_} //= 1 for qw(o d l r);
100 }
101
102
103 $| = 1;
104
105 if (!SL::LxOfficeConf->read(undef, 'may fail')) {
106   print_header('Could not load the config file. If you have dependencies from any features enabled in the configuration these will still show up as optional because of this. Please rerun this script after installing the dependencies needed to load the configuration.')
107 } else {
108   SL::InstallationCheck::check_for_conditional_dependencies();
109 }
110
111 if ($check{r}) {
112   print_header('Checking Required Modules');
113   check_module($_, required => 1) for @SL::InstallationCheck::required_modules;
114   check_pdfinfo();
115 }
116 if ($check{o}) {
117   print_header('Checking Optional Modules');
118   check_module($_, optional => 1) for @SL::InstallationCheck::optional_modules;
119 }
120 if ($check{d}) {
121   print_header('Checking Developer Modules');
122   check_module($_, devel => 1) for @SL::InstallationCheck::developer_modules;
123 }
124 if ($check{l}) {
125   check_latex();
126 }
127
128 my $fail = @missing_modules;
129 print_header('Result');
130 print_line('All', $fail ? 'NOT ok' : 'OK', $fail ? 'red' : 'green');
131
132 if ($default_run && !$check{s}) {
133   if (@missing_modules) {
134     $apt = 1;
135   print <<"EOL";
136
137 HEY! It seems there are modules MISSING! Look for the red lines with "NOT ok"
138 above. You'll want to fix those, I've enabled --install-command for you...
139 EOL
140   } else {
141   print <<"EOL";
142
143 Standard check done, everything is OK and up to date. Have a look at the --help
144 section of this script to see some more advanced checks for developer and
145 optional dependencies, as well as LaTeX packages you might need.
146 EOL
147   }
148 }
149
150 if (@missing_modules && $apt && !$check{s}) {
151   print "\nHere are some sample installation lines, choose one appropriate for your system:\n\n";
152   local $Text::Wrap::separator = " \\\n";
153
154   for (keys %install_methods) {
155     my $method = $install_methods{$_};
156     if (my @install_candidates = grep $_, map { $_->{$method->{key}} } @missing_modules) {
157       print "$method->{system}:\n";
158       print wrap("  ", "    ",  $method->{install}, @install_candidates);
159       print $/;
160     }
161   }
162 }
163
164 exit !!@missing_modules;
165
166 sub check_latex {
167   my ($res) = check_kpsewhich();
168   print_result("Looking for LaTeX kpsewhich", $res);
169
170   # no pdfx -> no zugferd possible
171   my $ret = kpsewhich('template/print/', 'sty', 'pdfx');
172   die "Cannot use pdfx. Please install this package first (debian: apt install texlive-latex-extra)"  if $ret;
173   if ($res) {
174     check_template_dir($_) for SL::InstallationCheck::template_dirs($master_templates);
175   }
176 }
177
178 sub check_template_dir {
179   my ($dir) = @_;
180   my $path  = $master_templates . $dir;
181
182   print_header("Checking LaTeX Dependencies for Master Templates '$dir'");
183   kpsewhich($path, 'cls', $_) for SL::InstallationCheck::classes_from_latex($path, '\documentclass');
184
185   my @sty = sort { $a cmp $b } List::MoreUtils::uniq (
186     SL::InstallationCheck::classes_from_latex($path, '\usepackage'),
187     qw(textcomp ulem embedfile)
188   );
189   kpsewhich($path, 'sty', $_) for @sty;
190 }
191
192 our $mastertemplate_path = './templates/print/';
193
194 sub check_kpsewhich {
195   return 1 if SL::InstallationCheck::check_kpsewhich();
196
197   print STDERR <<EOL if $v && !$check{s};
198 +------------------------------------------------------------------------------+
199   Can't find kpsewhich, is there a proper installed LaTeX?
200   On Debian you may run "aptitude install texlive-base-bin"
201 +------------------------------------------------------------------------------+
202 EOL
203   return 0;
204 }
205
206 sub kpsewhich {
207   my ($dw, $type, $package) = @_;
208   $package =~ s/[^-_0-9A-Za-z]//g;
209   my $type_desc = $type eq 'cls' ? 'document class' : 'package';
210
211   eval { require String::ShellQuote; 1 } or warn "can't load String::ShellQuote" && return;
212      $dw         = String::ShellQuote::shell_quote $dw;
213   my $e_package  = String::ShellQuote::shell_quote $package;
214   my $e_type     = String::ShellQuote::shell_quote $type;
215
216   my $exit = system(qq|TEXINPUTS=".:$dw:" kpsewhich $e_package.$e_type > /dev/null|);
217   my $res  = $exit > 0 ? 0 : 1;
218
219   print_result("Looking for LaTeX $type_desc $package", $res);
220   if (!$res) {
221     print STDERR <<EOL if $v && !$check{s};
222 +------------------------------------------------------------------------------+
223   LaTeX $type_desc $package could not be loaded.
224
225   On Debian you may find the needed *.deb package with:
226     apt-file search $package.$type
227
228   Maybe you need to install apt-file first by:
229     aptitude install apt-file && apt-file update
230 +------------------------------------------------------------------------------+
231 EOL
232   }
233 }
234
235 sub check_pdfinfo {
236   my $line = "Looking for pdfinfo executable";
237   my $shell_out = `pdfinfo -v 2>&1 | grep version 2> /dev/null`;
238   my ($label,$vers,$ver_string)  = split / /,$shell_out;
239   if ( $label && $label eq 'pdfinfo' ) {
240     chop $ver_string;
241     print_line($line, $ver_string, 'green');
242   } else {
243     print_line($line, 'not installed','red');
244     my %modinfo = ( debian => 'poppler-utils' );
245     push @missing_modules, \%modinfo;
246
247   }
248 }
249
250 sub check_module {
251   my ($module, %role) = @_;
252
253   my $line = "Looking for $module->{fullname}";
254   $line   .= " (from $module->{dist_name})" if $module->{dist_name};
255   my ($res, $ver) = SL::InstallationCheck::module_available($module->{"name"}, $module->{version});
256   if ($res) {
257     my $ver_string = ref $ver && $ver->can('numify') ? $ver->numify : $ver ? $ver : 'no version';
258     print_line($line, $ver_string, 'green');
259   } else {
260     print_result($line, $res);
261   }
262
263
264   return if $res;
265
266   push @missing_modules, $module;
267
268   my $needed_text =
269       $role{optional} ? 'It is OPTIONAL for kivitendo but RECOMMENDED for improved functionality.'
270     : $role{required} ? 'It is NEEDED by kivitendo and must be installed.'
271     : $role{devel}    ? 'It is OPTIONAL for kivitendo and only useful for developers.'
272     :                   'It is not listed as a dependency yet. Please tell this the developers.';
273
274   my @source_texts = module_source_texts($module);
275   local $" = $/;
276   print STDERR <<EOL if $v && !$check{s};
277 +------------------------------------------------------------------------------+
278   $module->{fullname} could not be loaded.
279
280   This module is either too old or not available on your system.
281   $needed_text
282
283   Here are some ideas how to get it:
284
285 @source_texts
286 +------------------------------------------------------------------------------+
287 EOL
288 }
289
290 sub module_source_texts {
291   my ($module) = @_;
292   my @texts;
293   for my $key (keys %install_methods) {
294     my $method = $install_methods{$key};
295     push @texts, <<"EOL" if $module->{$method->{key}};
296   - Using $method->{system} you can install it with $key:
297       $method->{install} $module->{$method->{key}}
298 EOL
299   }
300   push @texts, <<EOL if $module->{url};
301   - You can download it from this URL and install it manually:
302       $module->{url}
303 EOL
304
305   return @texts;
306 }
307
308 sub mycolor {
309   return $_[0] unless $c;
310   return colored(@_);
311 }
312
313 sub print_result {
314   my ($test, $exit) = @_;
315   if ($exit) {
316     print_line($test, 'ok', 'green');
317   } else {
318     print_line($test, 'NOT ok', 'red');
319   }
320 }
321
322 sub print_line {
323   my ($text, $res, $color) = @_;
324   return if $check{s};
325   print $text, " ", ('.' x (78 - length($text) - length($res))), " ", mycolor($res, $color), $/;
326 }
327
328 sub print_header {
329   return if $check{s};
330   print $/;
331   print "$_[0]:", $/;
332 }
333
334 1;
335
336 __END__
337
338 =encoding UTF-8
339
340 =head1 NAME
341
342 scripts/installation_check.pl - check kivitendo dependencies
343
344 =head1 SYNOPSIS
345
346   scripts/installation_check.pl [OPTION]
347
348 =head1 DESCRIPTION
349
350 Check dependencys. List all perl modules needed by kivitendo, probes for them,
351 and warns if one is not available.  List all LaTeX document classes and
352 packages needed by kivitendo master templates, probes for them, and warns if
353 one is not available.
354
355
356 =head1 OPTIONS
357
358 =over 4
359
360 =item C<-a, --all>
361
362 Probe for all perl modules and all LaTeX master templates.
363
364 =item C<-c, --color>
365
366 Color output. Default on.
367
368 =item C<--no-color>
369
370 No color output. Helpful to avoid terminal escape problems.
371
372 =item C<-d, --devel>
373
374 Probe for perl developer dependencies. (Used for console  and tags file)
375
376 =item C<--no-devel>
377
378 Don't probe for perl developer dependencies. (Useful in combination with --all)
379
380 =item C<-h, --help>
381
382 Display this help.
383
384 =item C<-o, --optional>
385
386 Probe for optional modules.
387
388 =item C<--no-optional>
389
390 Don't probe for optional perl modules. (Useful in combination with --all)
391
392 =item C<-r, --required>
393
394 Probe for required perl modules (default).
395
396 =item C<--no-required>
397
398 Don't probe for required perl modules. (Useful in combination with --all)
399
400 =item C<-l. --latex>
401
402 Probe for LaTeX documentclasses and packages in master templates.
403
404 =item C<--no-latex>
405
406 Don't probe for LaTeX document classes and packages in master templates. (Useful in combination with --all)
407
408 =item C<-v. --verbose>
409
410 Print additional info for missing dependencies
411
412 =item C<-i, --install-command>
413
414 Tries to generate installation commands for the most common package managers.
415 Note that these lists can be slightly off, but it should still save you a lot
416 of typing.
417
418 =back
419
420 =head1 BUGS, CAVEATS and TODO
421
422 =over 4
423
424 =item *
425
426 Fedora packages not listed yet.
427
428 =item *
429
430 Not possible yet to generate a combined cpan/apt-get string to install all needed.
431
432 =item *
433
434 Not able to handle devel cpan modules yet.
435
436 =item *
437
438 Version requirements not fully tested yet.
439
440 =back
441
442 =head1 AUTHOR
443
444   Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
445   Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
446   Wulf Coulmann E<lt>wulf@coulmann.deE<gt>
447
448 =cut