2 # BEGIN BPS TAGGED BLOCK {{{
6 # This software is Copyright (c) 1996-2013 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);
60 my @orig_argv = @ARGV;
63 'install!', 'with-MYSQL',
64 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE',
65 'with-ORACLE', 'with-FASTCGI',
66 'with-MODPERL1', 'with-MODPERL2',
89 Pod::Usage::pod2usage( { verbose => 2 } );
100 'with-DEV' => @RT_DEVEL_MODE@,
101 'with-GPG' => @RT_GPG@,
104 'with-GRAPHVIZ' => @RT_GRAPHVIZ@,
105 'with-GD' => @RT_GD@,
106 'with-DASHBOARDS' => 1,
107 'with-USERLOGO' => 1,
108 'with-SSL-MAILGATE' => @RT_SSL_MAILGATE@,
109 'with-HTML-DOC' => @RT_DEVEL_MODE@,
111 $args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default;
115 my %always_show_sections = (
123 print "$s:\n" unless $args{'list-deps'};
131 unless ( $args{'list-deps'} ) {
132 if ( $args{'v'} or not $test or $always_show_sections{$section} ) {
134 print $test ? "found" : "MISSING";
138 print "\t\t$extra\n" if defined $extra;
144 my %missing_by_type = @_;
146 unless ( $args{'list-deps'} ) {
147 unless ( keys %missing_by_type ) {
148 print "\nAll dependencies have been found.\n";
152 print "\nSOME DEPENDENCIES WERE MISSING.\n";
154 for my $type ( keys %missing_by_type ) {
155 my $missing = $missing_by_type{$type};
157 print "$type missing dependencies:\n";
158 for my $name ( keys %$missing ) {
159 my $module = $missing->{$name};
160 my $version = $module->{version};
161 my $error = $module->{error};
162 print_found( $name . ( $version && !$error ? " >= $version" : "" ),
163 0, $module->{error} );
172 for my $line ( split /\n/, $_[0] ) {
173 my($key, $value) = $line =~ /(\S+)\s*(\S*)/;
175 $hash{$key} = $value;
181 $deps{'CORE'} = [ text_to_hash( << '.') ];
184 DateTime::Locale 0.40
189 Class::ReturnValue 0.40
190 DBIx::SearchBuilder 1.59
200 Locale::Maketext 1.06
201 Locale::Maketext::Lexicon 0.32
202 Locale::Maketext::Fuzzy
215 Module::Versions::Report 1.05
216 Cache::Simple::TimedExpiry
220 Devel::StackTrace 1.19
221 Text::Password::Pronounceable
222 Devel::GlobalDestruction
225 Regexp::Common::net::CIDR
229 $deps{'MASON'} = [ text_to_hash( << '.') ];
237 Text::WikiFormat 0.76
239 Devel::StackTrace 1.19
244 $deps{'PSGI'} = [ text_to_hash( << '.') ];
247 HTML::Mason::PSGIHandler 0.52
249 Plack::Handler::Starlet
253 $deps{'MAILGATE'} = [ text_to_hash( << '.') ];
259 $deps{'SSL-MAILGATE'} = [ text_to_hash( << '.') ];
267 $deps{'CLI'} = [ text_to_hash( << '.') ];
270 HTTP::Request::Common
276 $deps{'DEV'} = [ text_to_hash( << '.') ];
282 Test::WWW::Mechanize 1.30
287 Test::Deep 0 # needed for shredder tests
288 String::ShellQuote 0 # needed for gnupg-incoming.t
291 Test::Builder 0.90 # needed for is_passing
294 Test::WWW::Mechanize::PSGI
295 Plack::Middleware::Test::StashWarnings 0.06
300 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
305 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
310 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
315 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
319 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
323 $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ];
327 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
331 $deps{'GPG'} = [ text_to_hash( << '.') ];
336 $deps{'ICAL'} = [ text_to_hash( << '.') ];
340 $deps{'SMTP'} = [ text_to_hash( << '.') ];
344 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
345 HTML::RewriteAttributes 0.05
350 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ];
355 $deps{'GD'} = [ text_to_hash( << '.') ];
361 $deps{'USERLOGO'} = [ text_to_hash( << '.') ];
365 $deps{'HTML-DOC'} = [ text_to_hash( <<'.') ];
371 'DBD::Oracle' => [qw(1.23)],
372 'Email::Address' => [qw(1.893 1.894)],
373 'Devel::StackTrace' => [qw(1.28 1.29)],
376 if ($args{'download'}) {
381 check_perl_version();
385 my %Missing_By_Type = ();
386 foreach my $type (sort grep $args{$_}, keys %args) {
387 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
390 section("$type dependencies");
393 my @deps = @{ $deps{$type} };
395 my %missing = test_deps(@deps);
397 if ( $args{'install'} ) {
398 for my $module (keys %missing) {
399 resolve_dep($module, $missing{$module}{version});
400 my $m = $module . '.pm';
402 if ( delete $INC{$m} ) {
403 my $symtab = $module . '::';
405 for my $symbol ( keys %{$symtab} ) {
406 next if substr( $symbol, -2, 2 ) eq '::';
407 delete $symtab->{$symbol};
410 delete $missing{$module}
411 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
415 $Missing_By_Type{$type} = \%missing if keys %missing;
418 if ( $args{'install'} && keys %Missing_By_Type ) {
419 exec($0, @orig_argv, '--no-install');
422 conclude(%Missing_By_Type);
430 my $module = shift @deps;
431 my $version = shift @deps;
432 my($test, $error) = test_dep($module, $version, $AVOID{$module});
433 my $msg = $module . ($version && !$error ? " >= $version" : '');
434 print_found($msg, $test, $error);
436 $missing{$module} = { version => $version, error => $error } unless $test;
447 if ( $args{'list-deps'} ) {
448 print $module, ': ', $version || 0, "\n";
451 eval "use $module $version ()";
452 if ( my $error = $@ ) {
453 return 0 unless wantarray;
455 $error =~ s/\n(.*)$//s;
456 $error =~ s/at \(eval \d+\) line \d+\.$//;
457 undef $error if $error =~ /this is only/;
459 return ( 0, $error );
463 my $version = $module->VERSION;
464 if ( grep $version eq $_, @$avoid ) {
465 return 0 unless wantarray;
466 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.");
478 print "\nInstall module $module\n";
480 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
485 if ( $ENV{'HOME'} ) {
486 unshift @INC, "$ENV{'HOME'}/.cpan";
488 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
490 unless ( $configured ) {
492 You haven't configured the CPAN shell yet.
493 Please run `@PERL@ -MCPAN -e shell` to configure it.
497 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
498 return $rv unless $@;
501 Failed to load module CPAN.
503 -------- Error ---------
505 ------------------------
507 When we tried to start installing RT's perl dependencies,
508 we were unable to load the CPAN client. This module is usually distributed
509 with Perl. This usually indicates that your vendor has shipped an unconfigured
510 or incorrectly configured CPAN client.
511 The error above may (or may not) give you a hint about what went wrong
513 You have several choices about how to install dependencies in
516 1) use a different tool to install dependencies by running setting the following
517 shell environment variable and rerunning this tool:
518 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
519 2) Attempt to configure CPAN by running:
520 `@PERL@ -MCPAN -e shell` program from shell.
521 If this fails, you may have to manually upgrade CPAN (see below)
522 3) Try to update the CPAN client. Download it from:
523 http://search.cpan.org/dist/CPAN and try again
524 4) Install each dependency manually by downloading them one by one from
525 http://search.cpan.org
532 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
536 print "\t\tcommand: '$ext'\n";
537 return scalar `$ext 1>&2`;
544 foreach my $key (keys %deps) {
545 my @deps = (@{$deps{$key}});
547 my $mod = shift @deps;
548 my $ver = shift @deps;
549 next if ($mod =~ /^(DBD-|Apache-Request)/);
550 $modules{$mod} = $ver;
553 my @mods = keys %modules;
555 my $moddir = $args{'download'};
556 foreach my $mod (@mods) {
557 $CPAN::Config->{'build_dir'} = $moddir;
561 opendir(DIR, $moddir);
562 while ( my $dir = readdir(DIR)) {
563 print "Dir is $dir\n";
564 next if ( $dir =~ /^\.\.?$/);
566 # Skip things we've previously tagged
567 my $out = `svn ls $args{'repository'}/tags/$dir`;
570 if ($dir =~ /^(.*)-(.*?)$/) {
571 `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`;
572 `rm -rf $moddir/$dir`;
581 sub check_perl_version {
583 eval {require 5.008003};
585 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.");
588 print_found( sprintf(">=5.8.3(%vd)", $^V), 1 );
594 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
595 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
596 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
597 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
598 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
599 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
608 rt-test-dependencies - test rt's dependencies
613 rt-test-dependencies --install
614 rt-test-dependencies --with-mysql --with-fastcgi
618 by default, C<rt-test-dependencies> determines whether you have installed all
619 the perl modules RT needs to run.
621 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
622 the standard CPAN shell by --install to install any required modules. it will
623 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
624 replace the "%s" with the module name before calling the program.
632 install missing modules
636 list the status of all dependencies, rather than just the missing ones.
638 -v is equal to --verbose
640 =item specify dependencies
646 database interface for mysql
648 =item --with-postgresql
650 database interface for postgresql
654 database interface for oracle
658 database interface and driver for sqlite (unsupported)
662 libraries needed to support the fastcgi handler
666 libraries needed to support the modperl 1 handler
670 libraries needed to support the modperl 2 handler
674 tools needed for RT development