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