2 # BEGIN BPS TAGGED BLOCK {{{
6 # This software is Copyright (c) 1996-2012 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.
55 no warnings qw(numeric redefine);
59 my @orig_argv = @ARGV;
62 'install!', 'with-MYSQL',
63 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE',
64 'with-ORACLE', 'with-FASTCGI',
65 'with-MODPERL1', 'with-MODPERL2',
88 Pod::Usage::pod2usage( { verbose => 2 } );
99 'with-DEV' => @RT_DEVEL_MODE@,
100 'with-GPG' => @RT_GPG@,
103 'with-GRAPHVIZ' => @RT_GRAPHVIZ@,
104 'with-GD' => @RT_GD@,
105 'with-DASHBOARDS' => 1,
106 'with-USERLOGO' => 1,
107 'with-SSL-MAILGATE' => @RT_SSL_MAILGATE@,
108 'with-HTML-DOC' => @RT_DEVEL_MODE@,
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} );
171 for my $line ( split /\n/, $_[0] ) {
172 my($key, $value) = $line =~ /(\S+)\s*(\S*)/;
174 $hash{$key} = $value;
180 $deps{'CORE'} = [ text_to_hash( << '.') ];
183 DateTime::Locale 0.40
188 Class::ReturnValue 0.40
189 DBIx::SearchBuilder 1.59
199 Locale::Maketext 1.06
200 Locale::Maketext::Lexicon 0.32
201 Locale::Maketext::Fuzzy
214 Module::Versions::Report 1.05
215 Cache::Simple::TimedExpiry
219 Devel::StackTrace 1.19
220 Text::Password::Pronounceable
221 Devel::GlobalDestruction
224 Regexp::Common::net::CIDR
228 $deps{'MASON'} = [ text_to_hash( << '.') ];
236 Text::WikiFormat 0.76
238 Devel::StackTrace 1.19
243 $deps{'PSGI'} = [ text_to_hash( << '.') ];
246 HTML::Mason::PSGIHandler 0.52
248 Plack::Handler::Starlet
252 $deps{'MAILGATE'} = [ text_to_hash( << '.') ];
258 $deps{'SSL-MAILGATE'} = [ text_to_hash( << '.') ];
266 $deps{'CLI'} = [ text_to_hash( << '.') ];
269 HTTP::Request::Common
275 $deps{'DEV'} = [ text_to_hash( << '.') ];
281 Test::WWW::Mechanize 1.30
286 Test::Deep 0 # needed for shredder tests
287 String::ShellQuote 0 # needed for gnupg-incoming.t
290 Test::Builder 0.90 # needed for is_passing
293 Test::WWW::Mechanize::PSGI
294 Plack::Middleware::Test::StashWarnings 0.06
298 $deps{'FASTCGI'} = [ text_to_hash( << '.') ];
303 $deps{'MODPERL1'} = [ text_to_hash( << '.') ];
308 $deps{'MODPERL2'} = [ text_to_hash( << '.') ];
313 $deps{'MYSQL'} = [ text_to_hash( << '.') ];
317 $deps{'ORACLE'} = [ text_to_hash( << '.') ];
321 $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ];
325 $deps{'SQLITE'} = [ text_to_hash( << '.') ];
329 $deps{'GPG'} = [ text_to_hash( << '.') ];
334 $deps{'ICAL'} = [ text_to_hash( << '.') ];
338 $deps{'SMTP'} = [ text_to_hash( << '.') ];
342 $deps{'DASHBOARDS'} = [ text_to_hash( << '.') ];
343 HTML::RewriteAttributes 0.04
348 $deps{'GRAPHVIZ'} = [ text_to_hash( << '.') ];
353 $deps{'GD'} = [ text_to_hash( << '.') ];
359 $deps{'USERLOGO'} = [ text_to_hash( << '.') ];
363 $deps{'HTML-DOC'} = [ text_to_hash( <<'.') ];
369 'DBD::Oracle' => [qw(1.23)],
370 'Email::Address' => [qw(1.893 1.894)],
373 if ($args{'download'}) {
378 check_perl_version();
382 my %Missing_By_Type = ();
383 foreach my $type (sort grep $args{$_}, keys %args) {
384 next unless ($type =~ /^with-(.*?)$/) and $deps{$1};
387 section("$type dependencies");
390 my @deps = @{ $deps{$type} };
392 my %missing = test_deps(@deps);
394 if ( $args{'install'} ) {
395 for my $module (keys %missing) {
396 resolve_dep($module, $missing{$module}{version});
397 my $m = $module . '.pm';
399 if ( delete $INC{$m} ) {
400 my $symtab = $module . '::';
402 for my $symbol ( keys %{$symtab} ) {
403 next if substr( $symbol, -2, 2 ) eq '::';
404 delete $symtab->{$symbol};
407 delete $missing{$module}
408 if test_dep($module, $missing{$module}{version}, $AVOID{$module});
412 $Missing_By_Type{$type} = \%missing if keys %missing;
415 if ( $args{'install'} && keys %Missing_By_Type ) {
416 exec($0, @orig_argv, '--no-install');
419 conclude(%Missing_By_Type);
427 my $module = shift @deps;
428 my $version = shift @deps;
429 my($test, $error) = test_dep($module, $version, $AVOID{$module});
430 my $msg = $module . ($version && !$error ? " >= $version" : '');
431 print_found($msg, $test, $error);
433 $missing{$module} = { version => $version, error => $error } unless $test;
444 if ( $args{'list-deps'} ) {
445 print $module, ': ', $version || 0, "\n";
448 eval "use $module $version ()";
449 if ( my $error = $@ ) {
450 return 0 unless wantarray;
452 $error =~ s/\n(.*)$//s;
453 $error =~ s/at \(eval \d+\) line \d+\.$//;
454 undef $error if $error =~ /this is only/;
456 return ( 0, $error );
460 my $version = $module->VERSION;
461 if ( grep $version eq $_, @$avoid ) {
462 return 0 unless wantarray;
463 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.");
475 print "\nInstall module $module\n";
477 my $ext = $ENV{'RT_FIX_DEPS_CMD'} || $ENV{'PERL_PREFER_CPAN_CLIENT'};
482 if ( $ENV{'HOME'} ) {
483 unshift @INC, "$ENV{'HOME'}/.cpan";
485 $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config };
487 unless ( $configured ) {
489 You haven't configured the CPAN shell yet.
490 Please run `@PERL@ -MCPAN -e shell` to configure it.
494 my $rv = eval { require CPAN; CPAN::Shell->install($module) };
495 return $rv unless $@;
498 Failed to load module CPAN.
500 -------- Error ---------
502 ------------------------
504 When we tried to start installing RT's perl dependencies,
505 we were unable to load the CPAN client. This module is usually distributed
506 with Perl. This usually indicates that your vendor has shipped an unconfigured
507 or incorrectly configured CPAN client.
508 The error above may (or may not) give you a hint about what went wrong
510 You have several choices about how to install dependencies in
513 1) use a different tool to install dependencies by running setting the following
514 shell environment variable and rerunning this tool:
515 RT_FIX_DEPS_CMD='@PERL@ -MCPAN -e"install %s"'
516 2) Attempt to configure CPAN by running:
517 `@PERL@ -MCPAN -e shell` program from shell.
518 If this fails, you may have to manually upgrade CPAN (see below)
519 3) Try to update the CPAN client. Download it from:
520 http://search.cpan.org/dist/CPAN and try again
521 4) Install each dependency manually by downloading them one by one from
522 http://search.cpan.org
529 $ext =~ s/\%s/$module/g; # sprintf( $ext, $module );
533 print "\t\tcommand: '$ext'\n";
534 return scalar `$ext 1>&2`;
541 foreach my $key (keys %deps) {
542 my @deps = (@{$deps{$key}});
544 my $mod = shift @deps;
545 my $ver = shift @deps;
546 next if ($mod =~ /^(DBD-|Apache-Request)/);
547 $modules{$mod} = $ver;
550 my @mods = keys %modules;
552 my $moddir = $args{'download'};
553 foreach my $mod (@mods) {
554 $CPAN::Config->{'build_dir'} = $moddir;
558 opendir(DIR, $moddir);
559 while ( my $dir = readdir(DIR)) {
560 print "Dir is $dir\n";
561 next if ( $dir =~ /^\.\.?$/);
563 # Skip things we've previously tagged
564 my $out = `svn ls $args{'repository'}/tags/$dir`;
567 if ($dir =~ /^(.*)-(.*?)$/) {
568 `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`;
569 `rm -rf $moddir/$dir`;
578 sub check_perl_version {
580 eval {require 5.008003};
582 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.");
585 print_found( sprintf(">=5.8.3(%vd)", $^V), 1 );
591 print_found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@"));
592 print_found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@"));
593 print_found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@"));
594 print_found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@"));
595 print_found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@"));
596 print_found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@"));
605 rt-test-dependencies - test rt's dependencies
610 rt-test-dependencies --install
611 rt-test-dependencies --with-mysql --with-fastcgi
615 by default, C<rt-test-dependencies> determines whether you have installed all
616 the perl modules RT needs to run.
618 the "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of
619 the standard CPAN shell by --install to install any required modules. it will
620 be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will
621 replace the "%s" with the module name before calling the program.
629 install missing modules
633 list the status of all dependencies, rather than just the missing ones.
635 -v is equal to --verbose
637 =item specify dependencies
643 database interface for mysql
645 =item --with-postgresql
647 database interface for postgresql
651 database interface for oracle
655 database interface and driver for sqlite (unsupported)
659 libraries needed to support the fastcgi handler
663 libraries needed to support the modperl 1 handler
667 libraries needed to support the modperl 2 handler
671 tools needed for RT development