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