Automatisches Löschen von Flashanzeige unterdrückbar(2)
[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   push   (@INC, $FindBin::Bin . '/../modules/fallback'); # Only use our own versions of modules if there's no system version.
10
11   # this is a default dir. may be wrong in your installation, change it then
12   $master_templates = $FindBin::Bin . '/../templates/print/';
13 }
14
15 use strict;
16 use Getopt::Long;
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-get 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 }
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 { use String::ShellQuote; 1 } or warn "can't load String::ShellQuote" && return;
182      $dw         = shell_quote $dw;
183   my $e_package  = shell_quote $package;
184   my $e_type     = 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_aqbanking {
206   my $aqbin = $::lx_office_conf{applications}->{aqbanking};
207   if ( !$aqbin ) {
208     print_line('Looking for aqbanking executable', 'not configured','red');
209   }
210   else {
211     my $line = "Looking for aqbanking executable '".$aqbin."'";
212     my $shell_out = `$aqbin versions 2>&1 | grep AqBanking-CLI 2> /dev/null`;
213     my ($label,$version)  = split /:/,$shell_out;
214     if ( $label && $label eq ' AqBanking-CLI' ) {
215       chop $version;
216       print_line($line, $version, 'green');
217     } else {
218       print_line($line, 'not installed','red');
219       my %modinfo = ( name => 'aqbanking' );
220       push @missing_modules, \%modinfo;
221     }
222   }
223 }
224
225 sub check_module {
226   my ($module, %role) = @_;
227
228   my $line = "Looking for $module->{fullname}";
229   $line   .= " (from $module->{dist_name})" if $module->{dist_name};
230   my ($res, $ver) = SL::InstallationCheck::module_available($module->{"name"}, $module->{version});
231   if ($res) {
232     my $ver_string = ref $ver && $ver->can('numify') ? $ver->numify : $ver ? $ver : 'no version';
233     print_line($line, $ver_string, 'green');
234   } else {
235     print_result($line, $res);
236   }
237
238
239   return if $res;
240
241   push @missing_modules, $module;
242
243   my $needed_text =
244       $role{optional} ? 'It is OPTIONAL for kivitendo but RECOMMENDED for improved functionality.'
245     : $role{required} ? 'It is NEEDED by kivitendo and must be installed.'
246     : $role{devel}    ? 'It is OPTIONAL for kivitendo and only useful for developers.'
247     :                   'It is not listed as a dependancy yet. Please tell this the developers.';
248
249   my @source_texts = module_source_texts($module);
250   local $" = $/;
251   print STDERR <<EOL if $v && !$check{s};
252 +------------------------------------------------------------------------------+
253   $module->{fullname} could not be loaded.
254
255   This module is either too old or not available on your system.
256   $needed_text
257
258   Here are some ideas how to get it:
259
260 @source_texts
261 +------------------------------------------------------------------------------+
262 EOL
263 }
264
265 sub module_source_texts {
266   my ($module) = @_;
267   my @texts;
268   for my $key (keys %install_methods) {
269     my $method = $install_methods{$key};
270     push @texts, <<"EOL" if $module->{$method->{key}};
271   - Using $method->{system} you can install it with $key:
272       $method->{install} $module->{$method->{key}}
273 EOL
274   }
275   push @texts, <<EOL if $module->{url};
276   - You can download it from this URL and install it manually:
277       $module->{url}
278 EOL
279
280   return @texts;
281 }
282
283 sub mycolor {
284   return $_[0] unless $c;
285   return colored(@_);
286 }
287
288 sub print_result {
289   my ($test, $exit) = @_;
290   if ($exit) {
291     print_line($test, 'ok', 'green');
292   } else {
293     print_line($test, 'NOT ok', 'red');
294   }
295 }
296
297 sub print_line {
298   my ($text, $res, $color) = @_;
299   return if $check{s};
300   print $text, " ", ('.' x (78 - length($text) - length($res))), " ", mycolor($res, $color), $/;
301 }
302
303 sub print_header {
304   return if $check{s};
305   print $/;
306   print "$_[0]:", $/;
307 }
308
309 1;
310
311 __END__
312
313 =encoding UTF-8
314
315 =head1 NAME
316
317 scripts/installation_check.pl - check kivitendo dependancies
318
319 =head1 SYNOPSIS
320
321   scripts/installation_check.pl [OPTION]
322
323 =head1 DESCRIPTION
324
325 Check dependencys. List all perl modules needed by kivitendo, probes for them,
326 and warns if one is not available.  List all LaTeX document classes and
327 packages needed by kivitendo master templates, probes for them, and warns if
328 one is not available.
329
330
331 =head1 OPTIONS
332
333 =over 4
334
335 =item C<-a, --all>
336
337 Probe for all perl modules and all LaTeX master templates.
338
339 =item C<-c, --color>
340
341 Color output. Default on.
342
343 =item C<--no-color>
344
345 No color output. Helpful to avoid terminal escape problems.
346
347 =item C<-d, --devel>
348
349 Probe for perl developer dependancies. (Used for console  and tags file)
350
351 =item C<--no-devel>
352
353 Don't probe for perl developer dependancies. (Useful in combination with --all)
354
355 =item C<-h, --help>
356
357 Display this help.
358
359 =item C<-o, --optional>
360
361 Probe for optional modules.
362
363 =item C<--no-optional>
364
365 Don't probe for optional perl modules. (Useful in combination with --all)
366
367 =item C<-r, --required>
368
369 Probe for required perl modules (default).
370
371 =item C<--no-required>
372
373 Don't probe for required perl modules. (Useful in combination with --all)
374
375 =item C<-l. --latex>
376
377 Probe for LaTeX documentclasses and packages in master templates.
378
379 =item C<--no-latex>
380
381 Don't probe for LaTeX document classes and packages in master templates. (Useful in combination with --all)
382
383 =item C<-v. --verbose>
384
385 Print additional info for missing dependancies
386
387 =item C<-i, --install-command>
388
389 Tries to generate installation commands for the most common package managers.
390 Note that these lists can be slightly off, but it should still save you a lot
391 of typing.
392
393 =back
394
395 =head1 BUGS, CAVEATS and TODO
396
397 =over 4
398
399 =item *
400
401 Fedora packages not listed yet.
402
403 =item *
404
405 Not possible yet to generate a combined cpan/apt-get string to install all needed.
406
407 =item *
408
409 Not able to handle devel cpan modules yet.
410
411 =item *
412
413 Version requirements not fully tested yet.
414
415 =back
416
417 =head1 AUTHOR
418
419   Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
420   Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
421   Wulf Coulmann E<lt>wulf@coulmann.deE<gt>
422
423 =cut