2 # BEGIN BPS TAGGED BLOCK {{{
6 # This software is Copyright (c) 1996-2014 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);
67 'install!', 'with-MYSQL',
68 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE',
69 'with-ORACLE', 'with-FASTCGI',
70 'with-MODPERL1', 'with-MODPERL2',
93 Pod::Usage::pod2usage( { verbose => 2 } );
103 'with-MAILGATE' => 1,
104 'with-DEV' => @RT_DEVEL_MODE@,
105 'with-GPG' => @RT_GPG@,
108 'with-GRAPHVIZ' => @RT_GRAPHVIZ@,
109 'with-GD' => @RT_GD@,
110 'with-DASHBOARDS' => 1,
111 'with-USERLOGO' => 1,
112 'with-SSL-MAILGATE' => @RT_SSL_MAILGATE@,
113 'with-HTML-DOC' => @RT_DEVEL_MODE@,
115 $args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default;
119 my %always_show_sections = (
127 print "$s:\n" unless $args{'list-deps'};
135 unless ( $args{'list-deps'} ) {
136 if ( $args{'v'} or not $test or $always_show_sections{$section} ) {
138 print $test ? "found" : "MISSING";
142 print "\t\t$extra\n" if defined $extra;
148 my %missing_by_type = @_;
150 unless ( $args{'list-deps'} ) {
151 unless ( keys %missing_by_type ) {
152 print "\nAll dependencies have been found.\n";
156 print "\nSOME DEPENDENCIES WERE MISSING.\n";
158 for my $type ( keys %missing_by_type ) {
159 my $missing = $missing_by_type{$type};
161 print "$type missing dependencies:\n";
162 for my $name ( keys %$missing ) {
163 my $module = $missing->{$name};
164 my $version = $module->{version};
165 my $error = $module->{error};
166 print_found( $name . ( $version && !$error ? " >= $version" : "" ),
167 0, $module->{error} );
176 for my $line ( split /\n/, $_[0] ) {
177 my($key, $value) = $line =~ /(\S+)\s*(\S*)/;
179 $hash{$key} = $value;
185 $deps{'CORE'} = [ text_to_hash( << '.') ];
188 DateTime::Locale 0.40
193 Class::ReturnValue 0.40
194 DBIx::SearchBuilder 1.59
204 Locale::Maketext 1.06
205 Locale::Maketext::Lexicon 0.32
206 Locale::Maketext::Fuzzy
219 Module::Versions::Report 1.05
220 Cache::Simple::TimedExpiry
224 Devel::StackTrace 1.19
225 Text::Password::Pronounceable
226 Devel::GlobalDestruction
229 Regexp::Common::net::CIDR
233 $deps{'MASON'} = [ text_to_hash( << '.') ];
241 Text::WikiFormat 0.76
243 Devel::StackTrace 1.19
248 $deps{'PSGI'} = [ text_to_hash( << '.') ];
251 HTML::Mason::PSGIHandler 0.52
253 Plack::Handler::Starlet
257 $deps{'MAILGATE'} = [ text_to_hash( << '.') ];
263 $deps{'SSL-MAILGATE'} = [ text_to_hash( << '.') ];
271 $deps{'CLI'} = [ text_to_hash( << '.') ];
274 HTTP::Request::Common
280 $deps{'DEV'} = [ text_to_hash( << '.') ];
286 Test::WWW::Mechanize 1.30
291 Test::Deep 0 # needed for shredder tests
292 String::ShellQuote 0 # needed for gnupg-incoming.t
295 Test::Builder 0.90 # needed for is_passing
298 Test::WWW::Mechanize::PSGI
299 Plack::Middleware::Test::StashWarnings 0.06
305 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
310 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
315 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
320 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
324 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
328 $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ];
332 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
336 $deps{'GPG'} = [ text_to_hash( << '.') ];
341 $deps{'ICAL'} = [ text_to_hash( << '.') ];
345 $deps{'SMTP'} = [ text_to_hash( << '.') ];
349 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
350 HTML::RewriteAttributes 0.05
355 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ];
360 $deps{'GD'} = [ text_to_hash( << '.') ];
366 $deps{'USERLOGO'} = [ text_to_hash( << '.') ];
370 $deps{'HTML-DOC'} = [ text_to_hash( <<'.') ];
376 'DBD::Oracle' => [qw(1.23)],
377 'Email::Address' => [qw(1.893 1.894)],
378 'Devel::StackTrace' => [qw(1.28 1.29)],
381 if ($args{'download'}) {
386 check_perl_version();
390 my %Missing_By_Type = ();
391 foreach my $type (sort grep $args{$_}, keys %args) {
392 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
395 section("$type dependencies");
398 my @deps = @{ $deps{$type} };
400 my %missing = test_deps(@deps);
402 if ( $args{'install'} ) {
403 for my $module (keys %missing) {
404 resolve_dep($module, $missing{$module}{version});
405 my $m = $module . '.pm';
407 if ( delete $INC{$m} ) {
408 my $symtab = $module . '::';
410 for my $symbol ( keys %{$symtab} ) {
411 next if substr( $symbol, -2, 2 ) eq '::';
412 delete $symtab->{$symbol};
415 delete $missing{$module}
416 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
420 $Missing_By_Type{$type} = \%missing if keys %missing;
423 if ( $args{'install'} && keys %Missing_By_Type ) {
424 exec($script_path, @orig_argv, '--no-install');
427 conclude(%Missing_By_Type);
435 my $module = shift @deps;
436 my $version = shift @deps;
437 my($test, $error) = test_dep($module, $version, $AVOID{$module});
438 my $msg = $module . ($version && !$error ? " >= $version" : '');
439 print_found($msg, $test, $error);
441 $missing{$module} = { version => $version, error => $error } unless $test;
452 if ( $args{'list-deps'} ) {
453 print $module, ': ', $version || 0, "\n";
456 eval "use $module $version ()";
457 if ( my $error = $@ ) {
458 return 0 unless wantarray;
460 $error =~ s/\n(.*)$//s;
461 $error =~ s/at \(eval \d+\) line \d+\.$//;
462 undef $error if $error =~ /this is only/;
464 return ( 0, $error );
468 my $version = $module->VERSION;
469 if ( grep $version eq $_, @$avoid ) {
470 return 0 unless wantarray;
471 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.");
483 print "\nInstall module $module\n";
485 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
490 if ( $ENV{'HOME'} ) {
491 unshift @INC, "$ENV{'HOME'}/.cpan";
493 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
495 unless ( $configured ) {
497 You haven't configured the CPAN shell yet.
498 Please run `@PERL@ -MCPAN -e shell` to configure it.
502 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
503 return $rv unless $@;
506 Failed to load module CPAN.
508 -------- Error ---------
510 ------------------------
512 When we tried to start installing RT's perl dependencies,
513 we were unable to load the CPAN client. This module is usually distributed
514 with Perl. This usually indicates that your vendor has shipped an unconfigured
515 or incorrectly configured CPAN client.
516 The error above may (or may not) give you a hint about what went wrong
518 You have several choices about how to install dependencies in
521 1) use a different tool to install dependencies by running setting the following
522 shell environment variable and rerunning this tool:
523 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
524 2) Attempt to configure CPAN by running:
525 `@PERL@ -MCPAN -e shell` program from shell.
526 If this fails, you may have to manually upgrade CPAN (see below)
527 3) Try to update the CPAN client. Download it from:
528 http://search.cpan.org/dist/CPAN and try again
529 4) Install each dependency manually by downloading them one by one from
530 http://search.cpan.org
537 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
541 print "\t\tcommand: '$ext'\n";
542 return scalar `$ext 1>&2`;
549 foreach my $key (keys %deps) {
550 my @deps = (@{$deps{$key}});
552 my $mod = shift @deps;
553 my $ver = shift @deps;
554 next if ($mod =~ /^(DBD-|Apache-Request)/);
555 $modules{$mod} = $ver;
558 my @mods = keys %modules;
560 my $moddir = $args{'download'};
561 foreach my $mod (@mods) {
562 $CPAN::Config->{'build_dir'} = $moddir;
566 opendir(DIR, $moddir);
567 while ( my $dir = readdir(DIR)) {
568 print "Dir is $dir\n";
569 next if ( $dir =~ /^\.\.?$/);
571 # Skip things we've previously tagged
572 my $out = `svn ls $args{'repository'}/tags/$dir`;
575 if ($dir =~ /^(.*)-(.*?)$/) {
576 `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`;
577 `rm -rf $moddir/$dir`;
586 sub check_perl_version {
588 eval {require 5.008003};
590 print_found("5.8.3", 0,"RT is known to be non-functional on versions of perl older than 5.8.3. Please upgrade to 5.8.3 or newer.");
593 print_found( sprintf(">=5.8.3(%vd)", $^V), 1 );
599 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
600 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
601 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
602 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
603 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
604 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
613 rt-test-dependencies - test rt's dependencies
618 rt-test-dependencies --install
619 rt-test-dependencies --with-mysql --with-fastcgi
623 by default, C<rt-test-dependencies> determines whether you have installed all
624 the perl modules RT needs to run.
626 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
627 the standard CPAN shell by --install to install any required modules. it will
628 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
629 replace the "%s" with the module name before calling the program.
637 install missing modules
641 list the status of all dependencies, rather than just the missing ones.
643 -v is equal to --verbose
645 =item specify dependencies
651 database interface for mysql
653 =item --with-postgresql
655 database interface for postgresql
659 database interface for oracle
663 database interface and driver for sqlite (unsupported)
667 libraries needed to support the fastcgi handler
671 libraries needed to support the modperl 1 handler
675 libraries needed to support the modperl 2 handler
679 tools needed for RT development