Dateimanagement: Massendruck
[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   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   kpsewhich($path, 'sty', $_) for SL::InstallationCheck::classes_from_latex($path, '\usepackage');
161 }
162
163 our $mastertemplate_path = './templates/print/';
164
165 sub check_kpsewhich {
166   return 1 if SL::InstallationCheck::check_kpsewhich();
167
168   print STDERR <<EOL if $v && !$check{s};
169 +------------------------------------------------------------------------------+
170   Can't find kpsewhich, is there a proper installed LaTeX?
171   On Debian you may run "aptitude install texlive-base-bin"
172 +------------------------------------------------------------------------------+
173 EOL
174   return 0;
175 }
176
177 sub kpsewhich {
178   my ($dw, $type, $package) = @_;
179   $package =~ s/[^-_0-9A-Za-z]//g;
180   my $type_desc = $type eq 'cls' ? 'document class' : 'package';
181
182   eval { use String::ShellQuote; 1 } or warn "can't load String::ShellQuote" && return;
183      $dw         = shell_quote $dw;
184   my $e_package  = shell_quote $package;
185   my $e_type     = shell_quote $type;
186
187   my $exit = system(qq|TEXINPUTS=".:$dw:" kpsewhich $e_package.$e_type > /dev/null|);
188   my $res  = $exit > 0 ? 0 : 1;
189
190   print_result("Looking for LaTeX $type_desc $package", $res);
191   if (!$res) {
192     print STDERR <<EOL if $v && !$check{s};
193 +------------------------------------------------------------------------------+
194   LaTeX $type_desc $package could not be loaded.
195
196   On Debian you may find the needed *.deb package with:
197     apt-file search $package.$type
198
199   Maybe you need to install apt-file first by:
200     aptitude install apt-file && apt-file update
201 +------------------------------------------------------------------------------+
202 EOL
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     print_line($line, $ver_string, 'green');
211   } else {
212     print_line($line, 'not installed','red');
213     my %modinfo = ( name => 'pdfinfo' );
214     push @missing_modules, \%modinfo;
215
216   }
217 }
218
219 sub check_pdfinfo {
220   my $line = "Looking for pdfinfo executable";
221   my $shell_out = `pdfinfo -v 2>&1 | grep version 2> /dev/null`;
222   my ($label,$vers,$ver_string)  = split / /,$shell_out;
223   if ( $label && $label eq 'pdfinfo' ) {
224     print_line($line, $ver_string, 'green');
225   } else {
226     print_line($line, 'not installed','red');
227     my %modinfo = ( name => 'pdfinfo' );
228     push @missing_modules, \%modinfo;
229
230   }
231 }
232
233 sub check_aqbanking {
234   my $aqbin = $::lx_office_conf{applications}->{aqbanking};
235   if ( !$aqbin ) {
236     print_line('Looking for aqbanking executable', 'not configured','red');
237   }
238   else {
239     my $line = "Looking for aqbanking executable '".$aqbin."'";
240     my $shell_out = `$aqbin versions 2>&1 | grep AqBanking-CLI 2> /dev/null`;
241     my ($label,$version)  = split /:/,$shell_out;
242     if ( $label && $label eq ' AqBanking-CLI' ) {
243       chop $version;
244       print_line($line, $version, 'green');
245     } else {
246       print_line($line, 'not installed','red');
247       my %modinfo = ( name => 'aqbanking' );
248       push @missing_modules, \%modinfo;
249     }
250   }
251 }
252
253 sub check_module {
254   my ($module, %role) = @_;
255
256   my $line = "Looking for $module->{fullname}";
257   $line   .= " (from $module->{dist_name})" if $module->{dist_name};
258   my ($res, $ver) = SL::InstallationCheck::module_available($module->{"name"}, $module->{version});
259   if ($res) {
260     my $ver_string = ref $ver && $ver->can('numify') ? $ver->numify : $ver ? $ver : 'no version';
261     print_line($line, $ver_string, 'green');
262   } else {
263     print_result($line, $res);
264   }
265
266
267   return if $res;
268
269   push @missing_modules, $module;
270
271   my $needed_text =
272       $role{optional} ? 'It is OPTIONAL for kivitendo but RECOMMENDED for improved functionality.'
273     : $role{required} ? 'It is NEEDED by kivitendo and must be installed.'
274     : $role{devel}    ? 'It is OPTIONAL for kivitendo and only useful for developers.'
275     :                   'It is not listed as a dependancy yet. Please tell this the developers.';
276
277   my @source_texts = module_source_texts($module);
278   local $" = $/;
279   print STDERR <<EOL if $v && !$check{s};
280 +------------------------------------------------------------------------------+
281   $module->{fullname} could not be loaded.
282
283   This module is either too old or not available on your system.
284   $needed_text
285
286   Here are some ideas how to get it:
287
288 @source_texts
289 +------------------------------------------------------------------------------+
290 EOL
291 }
292
293 sub module_source_texts {
294   my ($module) = @_;
295   my @texts;
296   for my $key (keys %install_methods) {
297     my $method = $install_methods{$key};
298     push @texts, <<"EOL" if $module->{$method->{key}};
299   - Using $method->{system} you can install it with $key:
300       $method->{install} $module->{$method->{key}}
301 EOL
302   }
303   push @texts, <<EOL if $module->{url};
304   - You can download it from this URL and install it manually:
305       $module->{url}
306 EOL
307
308   return @texts;
309 }
310
311 sub mycolor {
312   return $_[0] unless $c;
313   return colored(@_);
314 }
315
316 sub print_result {
317   my ($test, $exit) = @_;
318   if ($exit) {
319     print_line($test, 'ok', 'green');
320   } else {
321     print_line($test, 'NOT ok', 'red');
322   }
323 }
324
325 sub print_line {
326   my ($text, $res, $color) = @_;
327   return if $check{s};
328   print $text, " ", ('.' x (78 - length($text) - length($res))), " ", mycolor($res, $color), $/;
329 }
330
331 sub print_header {
332   return if $check{s};
333   print $/;
334   print "$_[0]:", $/;
335 }
336
337 1;
338
339 __END__
340
341 =encoding UTF-8
342
343 =head1 NAME
344
345 scripts/installation_check.pl - check kivitendo dependancies
346
347 =head1 SYNOPSIS
348
349   scripts/installation_check.pl [OPTION]
350
351 =head1 DESCRIPTION
352
353 Check dependencys. List all perl modules needed by kivitendo, probes for them,
354 and warns if one is not available.  List all LaTeX document classes and
355 packages needed by kivitendo master templates, probes for them, and warns if
356 one is not available.
357
358
359 =head1 OPTIONS
360
361 =over 4
362
363 =item C<-a, --all>
364
365 Probe for all perl modules and all LaTeX master templates.
366
367 =item C<-c, --color>
368
369 Color output. Default on.
370
371 =item C<--no-color>
372
373 No color output. Helpful to avoid terminal escape problems.
374
375 =item C<-d, --devel>
376
377 Probe for perl developer dependancies. (Used for console  and tags file)
378
379 =item C<--no-devel>
380
381 Don't probe for perl developer dependancies. (Useful in combination with --all)
382
383 =item C<-h, --help>
384
385 Display this help.
386
387 =item C<-o, --optional>
388
389 Probe for optional modules.
390
391 =item C<--no-optional>
392
393 Don't probe for optional perl modules. (Useful in combination with --all)
394
395 =item C<-r, --required>
396
397 Probe for required perl modules (default).
398
399 =item C<--no-required>
400
401 Don't probe for required perl modules. (Useful in combination with --all)
402
403 =item C<-l. --latex>
404
405 Probe for LaTeX documentclasses and packages in master templates.
406
407 =item C<--no-latex>
408
409 Don't probe for LaTeX document classes and packages in master templates. (Useful in combination with --all)
410
411 =item C<-v. --verbose>
412
413 Print additional info for missing dependancies
414
415 =item C<-i, --install-command>
416
417 Tries to generate installation commands for the most common package managers.
418 Note that these lists can be slightly off, but it should still save you a lot
419 of typing.
420
421 =back
422
423 =head1 BUGS, CAVEATS and TODO
424
425 =over 4
426
427 =item *
428
429 Fedora packages not listed yet.
430
431 =item *
432
433 Not possible yet to generate a combined cpan/apt-get string to install all needed.
434
435 =item *
436
437 Not able to handle devel cpan modules yet.
438
439 =item *
440
441 Version requirements not fully tested yet.
442
443 =back
444
445 =head1 AUTHOR
446
447   Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
448   Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
449   Wulf Coulmann E<lt>wulf@coulmann.deE<gt>
450
451 =cut