2 # BEGIN BPS TAGGED BLOCK {{{
6 # This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
7 # <sales@bestpractical.com>
9 # (Except where explicitly superseded by other copyright notices)
14 # This work is made available to you under the terms of Version 2 of
15 # the GNU General Public License. A copy of that license should have
16 # been provided with this software, but in any event can be snarfed
19 # This work is distributed in the hope that it will be useful, but
20 # WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 # General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 # 02110-1301 or visit their web page on the internet at
28 # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
31 # CONTRIBUTION SUBMISSION POLICY:
33 # (The following paragraph is not intended to limit the rights granted
34 # to you to modify and distribute this software under the terms of
35 # the GNU General Public License and is only of importance to you if
36 # you choose to contribute your changes and enhancements to the
37 # community by submitting them to Best Practical Solutions, LLC.)
39 # By intentionally submitting any modifications, corrections or
40 # derivatives to this work, or any other work intended for use with
41 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
42 # you are the copyright holder for those contributions and you grant
43 # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
44 # royalty-free, perpetual, license to use, copy, create derivative
45 # works based on those contributions, and sublicense and distribute
46 # those contributions and any derivatives thereof.
48 # END BPS TAGGED BLOCK }}}
50 # This is just a basic script that checks to make sure that all
51 # the modules needed by RT before you can install it.
56 no warnings qw(numeric redefine);
61 my @orig_argv = @ARGV;
62 # Save our path because installers or tests can change cwd
63 my $script_path = abs_path($0);
68 'with-MYSQL', 'with-PG', 'with-SQLITE', 'with-ORACLE',
69 'with-FASTCGI', 'with-MODPERL1', 'with-MODPERL2', 'with-STANDALONE',
88 Pod::Usage::pod2usage( { verbose => 2 } );
99 'with-DEVELOPER' => @RT_DEVELOPER@,
100 'with-GPG' => @RT_GPG_DEPS@,
101 'with-SMIME' => @RT_SMIME_DEPS@,
104 'with-GRAPHVIZ' => @RT_GRAPHVIZ@,
105 'with-GD' => @RT_GD@,
106 'with-DASHBOARDS' => 1,
107 'with-USERLOGO' => 1,
108 'with-HTML-DOC' => @RT_DEVELOPER@,
110 $args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default;
114 my %always_show_sections = (
122 print "$s:\n" unless $args{'list-deps'};
130 unless ( $args{'list-deps'} ) {
131 if ( $args{'v'} or not $test or $always_show_sections{$section} ) {
133 print $test ? "found" : "MISSING";
137 print "\t\t$extra\n" if defined $extra;
143 my %missing_by_type = @_;
145 unless ( $args{'list-deps'} ) {
146 unless ( keys %missing_by_type ) {
147 print "\nAll dependencies have been found.\n";
151 print "\nSOME DEPENDENCIES WERE MISSING.\n";
153 for my $type ( keys %missing_by_type ) {
154 my $missing = $missing_by_type{$type};
156 print "$type missing dependencies:\n";
157 for my $name ( keys %$missing ) {
158 my $module = $missing->{$name};
159 my $version = $module->{version};
160 my $error = $module->{error};
161 print_found( $name . ( $version && !$error ? " >= $version" : "" ),
162 0, $module->{error} );
166 print "\nPerl library path for @PERL@:\n";
167 print " $_\n" for @INC;
175 for my $line ( split /\n/, $_[0] ) {
176 my($key, $value) = $line =~ /(\S+)\s*(\S*)/;
178 $hash{$key} = $value;
184 my ($name, $module, $version) = @_;
185 my %list = @{$deps{$name}};
186 $list{$module} = ($version || '');
187 $deps{$name} = [ %list ];
190 $deps{'CORE'} = [ text_to_hash( << '.') ];
196 Class::Accessor::Fast
203 DateTime::Format::Natural 0.67
204 DateTime::Locale 0.40
206 DBIx::SearchBuilder 1.65
207 Devel::GlobalDestruction
208 Devel::StackTrace 1.19
213 Email::Address::List 0.02
221 HTML::FormatText::WithLinks 0.14
222 HTML::FormatText::WithLinks::AndTables
224 HTML::Mason::PSGIHandler 0.52
226 HTML::RewriteAttributes 0.05
233 Locale::Maketext 1.06
234 Locale::Maketext::Fuzzy 0.11
235 Locale::Maketext::Lexicon 0.32
241 Module::Versions::Report 1.05
244 Plack::Handler::Starlet
246 Regexp::Common::net::CIDR
251 Symbol::Global::Name 0.04
253 Text::Password::Pronounceable
256 Text::WikiFormat 0.76
264 set_dep( CORE => 'Symbol::Global::Name' => 0.05 ) if $] >= 5.019003;
265 set_dep( CORE => CGI => 4.00 ) if $] > 5.019003;
267 $deps{'MAILGATE'} = [ text_to_hash( << '.') ];
276 $deps{'CLI'} = [ text_to_hash( << '.') ];
278 HTTP::Request::Common
285 $deps{'DEVELOPER'} = [ text_to_hash( << '.') ];
292 Plack::Middleware::Test::StashWarnings 0.08
294 String::ShellQuote 0 # needed for gnupg-incoming.t
295 Test::Builder 0.90 # needed for is_passing
296 Test::Deep 0 # needed for shredder tests
304 Test::WWW::Mechanize 1.30
305 Test::WWW::Mechanize::PSGI
310 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
315 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
320 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
324 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
328 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
332 $deps{'PG'} = [ text_to_hash( << '.') ];
333 DBIx::SearchBuilder 1.66
337 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
341 $deps{'GPG'} = [ text_to_hash( << '.') ];
347 $deps{'SMIME'} = [ text_to_hash( << '.') ];
353 $deps{'ICAL'} = [ text_to_hash( << '.') ];
357 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
363 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ];
368 $deps{'GD'} = [ text_to_hash( << '.') ];
374 $deps{'USERLOGO'} = [ text_to_hash( << '.') ];
378 $deps{'HTML-DOC'} = [ text_to_hash( <<'.') ];
384 'DBD::Oracle' => [qw(1.23)],
385 'Devel::StackTrace' => [qw(1.28 1.29)],
388 if ($args{'download'}) {
393 check_perl_version();
397 my %Missing_By_Type = ();
398 foreach my $type (sort grep $args{$_}, keys %args) {
399 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
402 section("$type dependencies");
405 my @deps = @{ $deps{$type} };
407 my %missing = test_deps(@deps);
409 if ( $args{'install'} ) {
410 for my $module (keys %missing) {
411 resolve_dep($module, $missing{$module}{version});
412 my $m = $module . '.pm';
414 if ( delete $INC{$m} ) {
415 my $symtab = $module . '::';
417 for my $symbol ( keys %{$symtab} ) {
418 next if substr( $symbol, -2, 2 ) eq '::';
419 delete $symtab->{$symbol};
422 delete $missing{$module}
423 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
427 $Missing_By_Type{$type} = \%missing if keys %missing;
430 if ( $args{'install'} && keys %Missing_By_Type ) {
431 exec($script_path, @orig_argv, '--no-install');
434 conclude(%Missing_By_Type);
442 my $module = shift @deps;
443 my $version = shift @deps;
444 my($test, $error) = test_dep($module, $version, $AVOID{$module});
445 my $msg = $module . ($version && !$error ? " >= $version" : '');
446 print_found($msg, $test, $error);
448 $missing{$module} = { version => $version, error => $error } unless $test;
459 if ( $args{'list-deps'} ) {
460 print $module, ': ', $version || 0, "\n";
463 no warnings 'deprecated';
464 eval "{ local \$ENV{__WARN__}; use $module $version () }";
465 if ( my $error = $@ ) {
466 return 0 unless wantarray;
468 $error =~ s/\n(.*)$//s;
469 $error =~ s/at \(eval \d+\) line \d+\.$//;
470 undef $error if $error =~ /this is only/;
474 undef $error if defined $error and $error =~ /^Can't locate $path\.pm in \@INC/;
476 return ( 0, $error );
480 my $version = $module->VERSION;
481 if ( grep $version eq $_, @$avoid ) {
482 return 0 unless wantarray;
483 return (0, "It's known that there are problems with RT and version '$version' of '$module' module. If it's the latest available version of the module then you have to downgrade manually.");
495 unless (defined $args{siteinstall}) {
498 my @order = grep {($_ eq $Config::Config{sitelibexp}
499 or $_ eq $Config::Config{privlibexp})
500 and not $uniq{$_}++} @INC;
501 if ($] < 5.011 and @order == 2
502 and $order[0] eq $Config::Config{sitelibexp}
503 and $order[1] eq $Config::Config{privlibexp}) {
506 print "Patched perl, with site_perl before core in \@INC, detected.\n";
507 print "Installing dual-life modules into site_perl so they are not\n";
508 print "later overridden by the distribution's package.\n";
510 $args{siteinstall} = 1;
512 $args{siteinstall} = 0;
516 print "\nInstall module $module\n";
518 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
523 if ( $ENV{'HOME'} ) {
524 unshift @INC, "$ENV{'HOME'}/.cpan";
526 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
528 unless ( $configured ) {
530 You haven't configured the CPAN shell yet.
531 Please run `@PERL@ -MCPAN -e shell` to configure it.
536 my $installdirs = $CPAN::Config->{makepl_arg} ||= "";
537 $installdirs =~ s/(\bINSTALLDIRS=\S+|$)/ INSTALLDIRS=site/
538 if $args{siteinstall};
539 local $CPAN::Config->{makepl_arg} = $installdirs;
541 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
542 return $rv unless $@;
545 Failed to load module CPAN.
547 -------- Error ---------
549 ------------------------
551 When we tried to start installing RT's perl dependencies,
552 we were unable to load the CPAN client. This module is usually distributed
553 with Perl. This usually indicates that your vendor has shipped an unconfigured
554 or incorrectly configured CPAN client.
555 The error above may (or may not) give you a hint about what went wrong
557 You have several choices about how to install dependencies in
560 1) use a different tool to install dependencies by running setting the following
561 shell environment variable and rerunning this tool:
562 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
563 2) Attempt to configure CPAN by running:
564 `@PERL@ -MCPAN -e shell` program from shell.
565 If this fails, you may have to manually upgrade CPAN (see below)
566 3) Try to update the CPAN client. Download it from:
567 http://search.cpan.org/dist/CPAN and try again
568 4) Install each dependency manually by downloading them one by one from
569 http://search.cpan.org
576 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
580 print "\t\tcommand: '$ext'\n";
581 return scalar `$ext 1>&2`;
584 sub check_perl_version {
586 eval {require 5.010_001};
588 print_found("5.10.1", 0, sprintf("RT requires Perl v5.10.1 or newer. Your current Perl is v%vd", $^V));
591 print_found( sprintf(">=5.10.1(%vd)", $^V), 1 );
597 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
598 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
599 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
600 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
601 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
602 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
611 rt-test-dependencies - test rt's dependencies
616 rt-test-dependencies --install
617 rt-test-dependencies --with-mysql --with-fastcgi
621 by default, C<rt-test-dependencies> determines whether you have installed all
622 the perl modules RT needs to run.
624 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
625 the standard CPAN shell by --install to install any required modules. it will
626 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
627 replace the "%s" with the module name before calling the program.
635 install missing modules
639 list the status of all dependencies, rather than just the missing ones.
641 -v is equal to --verbose
643 =item specify dependencies
649 database interface for mysql
653 database interface for postgresql
657 database interface for oracle
661 database interface and driver for sqlite (unsupported)
665 libraries needed to support the fastcgi handler
667 =item --with-modperl1
669 libraries needed to support the modperl 1 handler
671 =item --with-modperl2
673 libraries needed to support the modperl 2 handler
675 =item --with-developer
677 tools needed for RT development