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