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 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( << '.') ];
279 $deps{'CLI'} = [ text_to_hash( << '.') ];
282 HTTP::Request::Common
288 $deps{'DEV'} = [ text_to_hash( << '.') ];
294 Test::WWW::Mechanize 1.30
299 Test::Deep 0 # needed for shredder tests
300 String::ShellQuote 0 # needed for gnupg-incoming.t
303 Test::Builder 0.90 # needed for is_passing
306 Test::WWW::Mechanize::PSGI
307 Plack::Middleware::Test::StashWarnings 0.08
313 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
318 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
323 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
328 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
332 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
336 $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ];
337 DBIx::SearchBuilder 1.66
341 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
345 $deps{'GPG'} = [ text_to_hash( << '.') ];
350 $deps{'ICAL'} = [ text_to_hash( << '.') ];
354 $deps{'SMTP'} = [ text_to_hash( << '.') ];
358 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
359 HTML::RewriteAttributes 0.05
364 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ];
369 $deps{'GD'} = [ text_to_hash( << '.') ];
375 $deps{'USERLOGO'} = [ text_to_hash( << '.') ];
379 $deps{'HTML-DOC'} = [ text_to_hash( <<'.') ];
385 'DBD::Oracle' => [qw(1.23)],
386 'Email::Address' => [qw(1.893 1.894)],
387 'Devel::StackTrace' => [qw(1.28 1.29)],
390 if ($args{'download'}) {
395 check_perl_version();
399 my %Missing_By_Type = ();
400 foreach my $type (sort grep $args{$_}, keys %args) {
401 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
404 section("$type dependencies");
407 my @deps = @{ $deps{$type} };
409 my %missing = test_deps(@deps);
411 if ( $args{'install'} ) {
412 for my $module (keys %missing) {
413 resolve_dep($module, $missing{$module}{version});
414 my $m = $module . '.pm';
416 if ( delete $INC{$m} ) {
417 my $symtab = $module . '::';
419 for my $symbol ( keys %{$symtab} ) {
420 next if substr( $symbol, -2, 2 ) eq '::';
421 delete $symtab->{$symbol};
424 delete $missing{$module}
425 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
429 $Missing_By_Type{$type} = \%missing if keys %missing;
432 if ( $args{'install'} && keys %Missing_By_Type ) {
433 exec($script_path, @orig_argv, '--no-install');
436 conclude(%Missing_By_Type);
444 my $module = shift @deps;
445 my $version = shift @deps;
446 my($test, $error) = test_dep($module, $version, $AVOID{$module});
447 my $msg = $module . ($version && !$error ? " >= $version" : '');
448 print_found($msg, $test, $error);
450 $missing{$module} = { version => $version, error => $error } unless $test;
461 if ( $args{'list-deps'} ) {
462 print $module, ': ', $version || 0, "\n";
465 no warnings 'deprecated';
466 eval "use $module $version ()";
467 if ( my $error = $@ ) {
468 return 0 unless wantarray;
470 $error =~ s/\n(.*)$//s;
471 $error =~ s/at \(eval \d+\) line \d+\.$//;
472 undef $error if $error =~ /this is only/;
474 return ( 0, $error );
478 my $version = $module->VERSION;
479 if ( grep $version eq $_, @$avoid ) {
480 return 0 unless wantarray;
481 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.");
493 print "\nInstall module $module\n";
495 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
500 if ( $ENV{'HOME'} ) {
501 unshift @INC, "$ENV{'HOME'}/.cpan";
503 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
505 unless ( $configured ) {
507 You haven't configured the CPAN shell yet.
508 Please run `@PERL@ -MCPAN -e shell` to configure it.
512 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
513 return $rv unless $@;
516 Failed to load module CPAN.
518 -------- Error ---------
520 ------------------------
522 When we tried to start installing RT's perl dependencies,
523 we were unable to load the CPAN client. This module is usually distributed
524 with Perl. This usually indicates that your vendor has shipped an unconfigured
525 or incorrectly configured CPAN client.
526 The error above may (or may not) give you a hint about what went wrong
528 You have several choices about how to install dependencies in
531 1) use a different tool to install dependencies by running setting the following
532 shell environment variable and rerunning this tool:
533 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
534 2) Attempt to configure CPAN by running:
535 `@PERL@ -MCPAN -e shell` program from shell.
536 If this fails, you may have to manually upgrade CPAN (see below)
537 3) Try to update the CPAN client. Download it from:
538 http://search.cpan.org/dist/CPAN and try again
539 4) Install each dependency manually by downloading them one by one from
540 http://search.cpan.org
547 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
551 print "\t\tcommand: '$ext'\n";
552 return scalar `$ext 1>&2`;
559 foreach my $key (keys %deps) {
560 my @deps = (@{$deps{$key}});
562 my $mod = shift @deps;
563 my $ver = shift @deps;
564 next if ($mod =~ /^(DBD-|Apache-Request)/);
565 $modules{$mod} = $ver;
568 my @mods = keys %modules;
570 my $moddir = $args{'download'};
571 foreach my $mod (@mods) {
572 $CPAN::Config->{'build_dir'} = $moddir;
576 opendir(DIR, $moddir);
577 while ( my $dir = readdir(DIR)) {
578 print "Dir is $dir\n";
579 next if ( $dir =~ /^\.\.?$/);
581 # Skip things we've previously tagged
582 my $out = `svn ls $args{'repository'}/tags/$dir`;
585 if ($dir =~ /^(.*)-(.*?)$/) {
586 `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`;
587 `rm -rf $moddir/$dir`;
596 sub check_perl_version {
598 eval {require 5.008003};
600 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.");
603 print_found( sprintf(">=5.8.3(%vd)", $^V), 1 );
609 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
610 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
611 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
612 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
613 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
614 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
623 rt-test-dependencies - test rt's dependencies
628 rt-test-dependencies --install
629 rt-test-dependencies --with-mysql --with-fastcgi
633 by default, C<rt-test-dependencies> determines whether you have installed all
634 the perl modules RT needs to run.
636 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
637 the standard CPAN shell by --install to install any required modules. it will
638 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
639 replace the "%s" with the module name before calling the program.
647 install missing modules
651 list the status of all dependencies, rather than just the missing ones.
653 -v is equal to --verbose
655 =item specify dependencies
661 database interface for mysql
663 =item --with-postgresql
665 database interface for postgresql
669 database interface for oracle
673 database interface and driver for sqlite (unsupported)
677 libraries needed to support the fastcgi handler
681 libraries needed to support the modperl 1 handler
685 libraries needed to support the modperl 2 handler
689 tools needed for RT development