Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[kivitendo-erp.git] / scripts / installation_check.pl
index 6eca871..1cebcb2 100755 (executable)
 #!/usr/bin/perl -w
 
+use strict;
+use Getopt::Long;
+use Pod::Usage;
+use Term::ANSIColor;
+our $master_templates;
 BEGIN {
   unshift @INC, "modules/override"; # Use our own versions of various modules (e.g. YAML).
   push    @INC, "modules/fallback"; # Only use our own versions of modules if there's no system version.
+
+  # this is a default dir. may be wrong in your installation, change it then
+  $master_templates = './templates/print/';
 }
 
 use SL::InstallationCheck;
 
+my %check;
+Getopt::Long::Configure ("bundling");
+GetOptions(
+  "v|verbose"   => \ my $v,
+  "a|all"       => \ $check{a},
+  "o|optional!" => \ $check{o},
+  "d|devel!"    => \ $check{d},
+  "l|latex!"    => \ $check{l},
+  "r|required!" => \ $check{r},
+  "h|help"      => sub { pod2usage(-verbose => 2) },
+  "c|color!"    => \ ( my $c = 1 ),
+);
+
+# if nothing is requested check "required"
+$check{r} = 1 unless defined $check{a} ||
+                     defined $check{l} ||
+                     defined $check{o} ||
+                     defined $check{d};
+my $default_run ='1' if $check{r};  # no parameter, therefore print a note after default run
+if ($check{a}) {
+  foreach my $check (keys %check) {
+    $check{$check} = 1 unless defined $check{$check};
+  }
+}
+
+
 $| = 1;
 
-foreach my $module (@SL::InstallationCheck::required_modules) {
-  if ($module->{version}) {
-    print("Looking for $module->{name} $module->{version}...");
-  } else {
-    print("Looking for $module->{name}...");
+if ($check{r}) {
+  print_header('Checking Required Modules');
+  check_module($_, required => 1) for @SL::InstallationCheck::required_modules;
+  print_header('Standard check for required modules done. See additional parameters for more checks (-- help)') if $default_run;
+}
+if ($check{o}) {
+  print_header('Checking Optional Modules');
+  check_module($_, optional => 1) for @SL::InstallationCheck::optional_modules;
+}
+if ($check{d}) {
+  print_header('Checking Developer Modules');
+  check_module($_, devel => 1) for @SL::InstallationCheck::developer_modules;
+}
+if ($check{l}) {
+  check_latex();
+}
+
+sub check_latex {
+  my ($res) = check_kpsewhich();
+  print_result("Looking for LaTeX kpsewhich", $res ? ('ok', 'green') : ('NOT ok', 'red'));
+  if ($res) {
+    check_template_dir($_) for SL::InstallationCheck::template_dirs($master_templates);
+  }
+}
+
+sub check_template_dir {
+  my ($dir) = @_;
+  my $path  = $master_templates . $dir;
+
+  print_header("Checking LaTeX Dependencies for Master Templates '$dir'");
+  kpsewhich($path, 'cls', $_) for SL::InstallationCheck::classes_from_latex($path, '\documentclass');
+  kpsewhich($path, 'sty', $_) for SL::InstallationCheck::classes_from_latex($path, '\usepackage');
+}
+
+our $mastertemplate_path = './templates/print/';
+
+sub check_kpsewhich {
+  return 1 if SL::InstallationCheck::check_kpsewhich();
+
+  print STDERR <<EOL if $v;
++------------------------------------------------------------------------------+
+  Can't find kpsewhich, is there a proper installed LaTeX?
+  On Debian you may run "aptitude install texlive-base-bin"
++------------------------------------------------------------------------------+
+EOL
+  return 0;
+}
+
+sub kpsewhich {
+  my ($dw, $type, $package) = @_;
+  $package =~ s/[^-_0-9A-Za-z]//g;
+  my $type_desc = $type eq 'cls' ? 'document class' : 'package';
+
+  eval { use String::ShellQuote; 1 } or warn "can't load String::ShellQuote" && return;
+     $dw         = shell_quote $dw;
+  my $e_package  = shell_quote $package;
+  my $e_type     = shell_quote $type;
+
+  my $exit = system(qq|TEXINPUTS=".:$dw:" kpsewhich $e_package.$e_type > /dev/null|);
+  my $res  = $exit > 0 ? 0 : 1;
+
+  print_result("Looking for LaTeX $type_desc $package", $res);
+  if (!$res) {
+    print STDERR <<EOL if $v;
++------------------------------------------------------------------------------+
+  LaTeX $type_desc $package could not be loaded.
+
+  On Debian you may find the needed *.deb package with:
+    apt-file search $package.$type
+
+  Maybe you need to install apt-file first by:
+    aptitude install apt-file && apt-file update
++------------------------------------------------------------------------------+
+EOL
   }
-  if (!SL::InstallationCheck::module_available($module->{"name"})) {
-    print(" NOT found\n" .
-          "  The module '$module->{name}' is not available on your system.\n" .
-          "  Please install it with the CPAN shell, e.g.\n" .
-          "    perl -MCPAN -e \"install $module->{name}\"\n" .
-          "  or download it from this URL and install it manually:\n" .
-          "    $module->{url}\n\n");
+}
+
+sub check_module {
+  my ($module, %role) = @_;
+
+  my $line = "Looking for $module->{fullname}";
+  my ($res, $ver) = SL::InstallationCheck::module_available($module->{"name"}, $module->{version});
+  if ($res) {
+    print_line($line, $ver || 'no version', 'green');
   } else {
-    print(" ok\n");
+    print_result($line, $res);
   }
+
+
+  return if $res;
+
+  my $needed_text =
+      $role{optional} ? 'It is OPTIONAL for Lx-Office but RECOMMENDED for improved functionality.'
+    : $role{required} ? 'It is NEEDED by Lx-Office and must be installed.'
+    : $role{devel}    ? 'It is OPTIONAL for Lx-Office and only useful for developers.'
+    :                   'It is not listed as a dependancy yet. Please tell this the developers.';
+
+  my @source_texts = module_source_texts($module);
+  local $" = $/;
+  print STDERR <<EOL if $v;
++------------------------------------------------------------------------------+
+  $module->{fullname} could not be loaded.
+
+  This module is either too old or not available on your system.
+  $needed_text
+
+  Here are some ideas how to get it:
+
+@source_texts
++------------------------------------------------------------------------------+
+EOL
 }
 
-foreach my $module (@SL::InstallationCheck::optional_modules) {
-  print("Looking for $module->{name} (optional)...");
-  if (!SL::InstallationCheck::module_available($module->{"name"})) {
-    print(" NOT found\n" .
-          "  The module '$module->{name}' is not available on your system.\n" .
-          "  While it is not strictly needed it provides extra functionality\n" .
-          "  and should be installed.\n" .
-          "  You can install it with the CPAN shell, e.g.\n" .
-          "    perl -MCPAN -e \"install $module->{name}\"\n" .
-          "  or download it from this URL and install it manually:\n" .
-          "    $module->{url}\n\n");
+sub module_source_texts {
+  my ($module) = @_;
+  my @texts;
+  push @texts, <<EOL;
+  - You can get it from CPAN:
+      perl -MCPAN -e "install $module->{name}"
+EOL
+  push @texts, <<EOL if $module->{url};
+  - You can download it from this URL and install it manually:
+      $module->{url}
+EOL
+  push @texts, <<EOL if $module->{debian};
+  - On Debian, Ubuntu and other distros you can install it with apt-get:
+      sudo apt-get install $module->{debian}
+    Note: These may be out of date as well if your system is old.
+EOL
+ # TODO: SuSE and Fedora packaging. Windows packaging.
+
+  return @texts;
+}
+
+sub mycolor {
+  return $_[0] unless $c;
+  return colored(@_);
+}
+
+sub print_result {
+  my ($test, $exit) = @_;
+  if ($exit) {
+    print_line($test, 'ok', 'green');
   } else {
-    print(" ok\n");
+    print_line($test, 'NOT ok', 'red');
   }
 }
+
+sub print_line {
+  my ($text, $res, $color) = @_;
+  print $text, " ", ('.' x (78 - length($text) - length($res)));
+  print mycolor($res, $color);
+  print "\n";
+  return;
+}
+
+sub print_header {
+  print $/;
+  print "$_[0]:", $/;
+}
+
+1;
+
+__END__
+
+=encoding UTF-8
+
+=head1 NAME
+
+scripts/installation_check.pl - check Lx-Office dependancies
+
+=head1 SYNOPSIS
+
+  scripts/installation_check.pl [OPTION]
+
+=head1 DESCRIPTION
+
+Check dependencys. List all perl modules needed by Lx-Office, probes for them,
+and warns if one is not available.  List all LaTeX document classes and
+packages needed by Lx-Office master templates, probes for them, and warns if
+one is not available.
+
+
+=head1 OPTIONS
+
+=over 4
+
+=item C<-a, --all>
+
+Probe for all perl modules and all LaTeX master templates.
+
+=item C<-c, --color>
+
+Color output. Default on.
+
+=item C<--no-color>
+
+No color output. Helpful to avoid terminal escape problems.
+
+=item C<-d, --devel>
+
+Probe for perl developer dependancies. (Used for console  and tags file)
+
+=item C<--no-devel>
+
+Don't probe for perl developer dependancies. (Useful in combination with --all)
+
+=item C<-h, --help>
+
+Display this help.
+
+=item C<-o, --optional>
+
+Probe for optional modules.
+
+=item C<--no-optional>
+
+Don't probe for optional perl modules. (Useful in combination with --all)
+
+=item C<-r, --required>
+
+Probe for required perl modules (default).
+
+=item C<--no-required>
+
+Don't probe for required perl modules. (Useful in combination with --all)
+
+=item C<-l. --latex>
+
+Probe for LaTeX documentclasses and packages in master templates.
+
+=item C<--no-latex>
+
+Don't probe for LaTeX document classes and packages in master templates. (Useful in combination with --all)
+
+=item C<-v. --verbose>
+
+Print additional info for missing dependancies
+
+=back
+
+=head1 BUGS, CAVEATS and TODO
+
+=over 4
+
+=item *
+
+Fedora packages not listed yet.
+
+=item *
+
+Not possible yet to generate a combined cpan/apt-get string to install all needed.
+
+=item *
+
+Not able to handle devel cpan modules yet.
+
+=item *
+
+Version requirements not fully tested yet.
+
+=back
+
+=head1 AUTHOR
+
+  Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
+  Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
+  Wulf Coulmann E<lt>wulf@coulmann.deE<gt>
+
+=cut