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