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);
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 my ($name, $module, $version) = @_;
186 my %list = @{$deps{$name}};
187 $list{$module} = ($version || '');
188 $deps{$name} = [ %list ];
191 $deps{'CORE'} = [ text_to_hash( << '.') ];
194 DateTime::Locale 0.40
199 Class::ReturnValue 0.40
200 DBIx::SearchBuilder 1.59
210 Locale::Maketext 1.06
211 Locale::Maketext::Lexicon 0.32
212 Locale::Maketext::Fuzzy
225 Module::Versions::Report 1.05
226 Cache::Simple::TimedExpiry
230 Devel::StackTrace 1.19
231 Text::Password::Pronounceable
232 Devel::GlobalDestruction
235 Regexp::Common::net::CIDR
239 $deps{'MASON'} = [ text_to_hash( << '.') ];
247 Text::WikiFormat 0.76
249 Devel::StackTrace 1.19
254 $deps{'PSGI'} = [ text_to_hash( << '.') ];
257 HTML::Mason::PSGIHandler 0.52
259 Plack::Handler::Starlet
262 set_dep( PSGI => CGI => 4.00 ) if $] > 5.019003;
265 $deps{'MAILGATE'} = [ text_to_hash( << '.') ];
271 $deps{'SSL-MAILGATE'} = [ text_to_hash( << '.') ];
278 $deps{'CLI'} = [ text_to_hash( << '.') ];
281 HTTP::Request::Common
287 $deps{'DEV'} = [ text_to_hash( << '.') ];
293 Test::WWW::Mechanize 1.30
298 Test::Deep 0 # needed for shredder tests
299 String::ShellQuote 0 # needed for gnupg-incoming.t
302 Test::Builder 0.90 # needed for is_passing
305 Test::WWW::Mechanize::PSGI
306 Plack::Middleware::Test::StashWarnings 0.08
312 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
317 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
322 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
327 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
331 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
335 $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ];
336 DBIx::SearchBuilder 1.66
340 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
344 $deps{'GPG'} = [ text_to_hash( << '.') ];
349 $deps{'ICAL'} = [ text_to_hash( << '.') ];
353 $deps{'SMTP'} = [ text_to_hash( << '.') ];
357 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
358 HTML::RewriteAttributes 0.05
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 'Email::Address' => [qw(1.893 1.894)],
386 'Devel::StackTrace' => [qw(1.28 1.29)],
389 if ($args{'download'}) {
394 check_perl_version();
398 my %Missing_By_Type = ();
399 foreach my $type (sort grep $args{$_}, keys %args) {
400 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
403 section("$type dependencies");
406 my @deps = @{ $deps{$type} };
408 my %missing = test_deps(@deps);
410 if ( $args{'install'} ) {
411 for my $module (keys %missing) {
412 resolve_dep($module, $missing{$module}{version});
413 my $m = $module . '.pm';
415 if ( delete $INC{$m} ) {
416 my $symtab = $module . '::';
418 for my $symbol ( keys %{$symtab} ) {
419 next if substr( $symbol, -2, 2 ) eq '::';
420 delete $symtab->{$symbol};
423 delete $missing{$module}
424 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
428 $Missing_By_Type{$type} = \%missing if keys %missing;
431 if ( $args{'install'} && keys %Missing_By_Type ) {
432 exec($script_path, @orig_argv, '--no-install');
435 conclude(%Missing_By_Type);
443 my $module = shift @deps;
444 my $version = shift @deps;
445 my($test, $error) = test_dep($module, $version, $AVOID{$module});
446 my $msg = $module . ($version && !$error ? " >= $version" : '');
447 print_found($msg, $test, $error);
449 $missing{$module} = { version => $version, error => $error } unless $test;
460 if ( $args{'list-deps'} ) {
461 print $module, ': ', $version || 0, "\n";
464 no warnings 'deprecated';
465 eval "use $module $version ()";
466 if ( my $error = $@ ) {
467 return 0 unless wantarray;
469 $error =~ s/\n(.*)$//s;
470 $error =~ s/at \(eval \d+\) line \d+\.$//;
471 undef $error if $error =~ /this is only/;
473 return ( 0, $error );
477 my $version = $module->VERSION;
478 if ( grep $version eq $_, @$avoid ) {
479 return 0 unless wantarray;
480 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.");
492 print "\nInstall module $module\n";
494 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
499 if ( $ENV{'HOME'} ) {
500 unshift @INC, "$ENV{'HOME'}/.cpan";
502 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
504 unless ( $configured ) {
506 You haven't configured the CPAN shell yet.
507 Please run `@PERL@ -MCPAN -e shell` to configure it.
511 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
512 return $rv unless $@;
515 Failed to load module CPAN.
517 -------- Error ---------
519 ------------------------
521 When we tried to start installing RT's perl dependencies,
522 we were unable to load the CPAN client. This module is usually distributed
523 with Perl. This usually indicates that your vendor has shipped an unconfigured
524 or incorrectly configured CPAN client.
525 The error above may (or may not) give you a hint about what went wrong
527 You have several choices about how to install dependencies in
530 1) use a different tool to install dependencies by running setting the following
531 shell environment variable and rerunning this tool:
532 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
533 2) Attempt to configure CPAN by running:
534 `@PERL@ -MCPAN -e shell` program from shell.
535 If this fails, you may have to manually upgrade CPAN (see below)
536 3) Try to update the CPAN client. Download it from:
537 http://search.cpan.org/dist/CPAN and try again
538 4) Install each dependency manually by downloading them one by one from
539 http://search.cpan.org
546 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
550 print "\t\tcommand: '$ext'\n";
551 return scalar `$ext 1>&2`;
558 foreach my $key (keys %deps) {
559 my @deps = (@{$deps{$key}});
561 my $mod = shift @deps;
562 my $ver = shift @deps;
563 next if ($mod =~ /^(DBD-|Apache-Request)/);
564 $modules{$mod} = $ver;
567 my @mods = keys %modules;
569 my $moddir = $args{'download'};
570 foreach my $mod (@mods) {
571 $CPAN::Config->{'build_dir'} = $moddir;
575 opendir(DIR, $moddir);
576 while ( my $dir = readdir(DIR)) {
577 print "Dir is $dir\n";
578 next if ( $dir =~ /^\.\.?$/);
580 # Skip things we've previously tagged
581 my $out = `svn ls $args{'repository'}/tags/$dir`;
584 if ($dir =~ /^(.*)-(.*?)$/) {
585 `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`;
586 `rm -rf $moddir/$dir`;
595 sub check_perl_version {
597 eval {require 5.008003};
599 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.");
602 print_found( sprintf(">=5.8.3(%vd)", $^V), 1 );
608 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
609 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
610 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
611 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
612 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
613 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
622 rt-test-dependencies - test rt's dependencies
627 rt-test-dependencies --install
628 rt-test-dependencies --with-mysql --with-fastcgi
632 by default, C<rt-test-dependencies> determines whether you have installed all
633 the perl modules RT needs to run.
635 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
636 the standard CPAN shell by --install to install any required modules. it will
637 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
638 replace the "%s" with the module name before calling the program.
646 install missing modules
650 list the status of all dependencies, rather than just the missing ones.
652 -v is equal to --verbose
654 =item specify dependencies
660 database interface for mysql
662 =item --with-postgresql
664 database interface for postgresql
668 database interface for oracle
672 database interface and driver for sqlite (unsupported)
676 libraries needed to support the fastcgi handler
680 libraries needed to support the modperl 1 handler
684 libraries needed to support the modperl 2 handler
688 tools needed for RT development