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