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