#!@PERL@ # BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: # # This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) # # # LICENSE: # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 or visit their web page on the internet at # http://www.gnu.org/copyleft/gpl.html. # # # CONTRIBUTION SUBMISSION POLICY: # # (The following paragraph is not intended to limit the rights granted # to you to modify and distribute this software under the terms of # the GNU General Public License and is only of importance to you if # you choose to contribute your changes and enhancements to the # community by submitting them to Best Practical Solutions, LLC.) # # By intentionally submitting any modifications, corrections or # derivatives to this work, or any other work intended for use with # Request Tracker, to Best Practical Solutions, LLC, you confirm that # you are the copyright holder for those contributions and you grant # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, # royalty-free, perpetual, license to use, copy, create derivative # works based on those contributions, and sublicense and distribute # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} # # This is just a basic script that checks to make sure that all # the modules needed by RT before you can install it. # use strict; no warnings qw(numeric redefine); use Getopt::Long; my %args; my %deps; GetOptions( \%args, 'v|verbose', 'install', 'with-MYSQL', 'with-POSTGRESQL|with-pg|with-pgsql', 'with-SQLITE', 'with-ORACLE', 'with-FASTCGI', 'with-SPEEDYCGI', 'with-MODPERL1', 'with-MODPERL2', 'with-DEV', 'with-STANDALONE', 'download=s', 'repository=s' ); unless (keys %args) { help(); exit(0); } # Set up defaults my %default = ( 'with-MASON' => 1, 'with-CORE' => 1, 'with-CLI' => 1, 'with-MAILGATE' => 1, 'with-DEV' => @RT_DEVEL_MODE@, 'with-STANDALONE' => @RT_STANDALONE@, ); $args{$_} = $default{$_} foreach grep !exists $args{$_}, keys %default; use Data::Dumper; print Dumper( \%args ); { my $section; my %always_show_sections = ( perl => 1, users => 1, ); sub section { my $s = shift; $section = $s; print "$s:\n"; } my $any_missing = 0; sub found { my $msg = shift; my $test = shift; my $extra = shift; $any_missing = 1 unless $test; if ($args{'v'} or not $test or $always_show_sections{$section}) { print "\t$msg..."; print $test ? "found" : "MISSING"; print "\n"; } print "\t\t$extra\n" if defined $extra; } sub conclude { if ($any_missing) { print "\nSOMETHING WAS MISSING!\n"; } else { print "\nEverything was found.\n"; } } } sub help { print <<'.'; By default, testdeps determine whether you have installed all the perl modules RT needs to run. --install Install missing modules The following switches will tell the tool to check for specific dependencies --with-mysql Database interface for MySQL --with-postgresql Database interface for PostgreSQL --with-sqlite Database interface and driver for SQLite (unsupported) --with-oracle Database interface for oracle (unsupported) --with-standalone Libraries needed to support the standalone simple pure perl server --with-fastcgi Libraries needed to support the fastcgi handler --with-speedycgi Libraries needed to support the speedycgi handler --with-modperl1 Libraries needed to support the modperl 1 handler --with-modperl2 Libraries needed to support the modperl 2 handler --with-dev Tools needed for RT development You can also specify -v or --verbose to list the status of all dependencies, rather than just the missing ones. The "RT_FIX_DEPS_CMD" environment variable, if set, will be used instead of the standard CPAN shell by --install to install any required modules. It will be called with the module name, or, if "RT_FIX_DEPS_CMD" contains a "%s", will replace the "%s" with the module name before calling the program. . } sub text_to_hash { my %hash; for my $line ( split /\n/, $_[0] ) { my($key, $value) = $line =~ /(\S+)\s*(\S*)/; $value ||= ''; $hash{$key} = $value; } return %hash; } $deps{'CORE'} = [ text_to_hash( << '.') ]; Digest::base Digest::MD5 2.27 DBI 1.37 Class::ReturnValue 0.40 Date::Format DBIx::SearchBuilder 1.48 Text::Template File::Spec 0.8 HTML::Entities HTML::Scrubber 0.08 Log::Dispatch 2.0 Locale::Maketext 1.06 Locale::Maketext::Lexicon 0.32 Locale::Maketext::Fuzzy MIME::Entity 5.108 Mail::Mailer 1.57 Net::SMTP Text::Wrapper Time::ParseDate Time::HiRes File::Temp Text::Autoformat Text::Quoted 2.02 Tree::Simple 1.04 Regexp::Common Scalar::Util Module::Versions::Report 1.03 Cache::Simple::TimedExpiry UNIVERSAL::require Calendar::Simple . $deps{'MASON'} = [ text_to_hash( << '.') ]; HTML::Mason 1.23 Errno Digest::MD5 2.27 CGI::Cookie 1.20 Storable 2.08 Apache::Session 1.53 XML::RSS 1.05 GD GD::Graph GD::Text Text::WikiFormat 0.76 . $deps{'STANDALONE'} = [ text_to_hash( << '.') ]; HTTP::Server::Simple 0.07 HTTP::Server::Simple::Mason 0.09 . $deps{'MAILGATE'} = [ text_to_hash( << '.') ]; HTML::TreeBuilder HTML::FormatText Getopt::Long LWP::UserAgent Pod::Usage . $deps{'CLI'} = [ text_to_hash( << '.') ]; Getopt::Long 2.24 LWP HTTP::Request::Common Text::ParseWords Term::ReadLine Term::ReadKey . $deps{'DEV'} = [ text_to_hash( << '.') ]; Test::Inline Apache::Test HTML::Form HTML::TokeParser WWW::Mechanize Test::WWW::Mechanize 1.04 Module::Refresh 0.03 Test::Expect 0.30 XML::Simple File::Find . $deps{'FASTCGI'} = [ text_to_hash( << '.') ]; CGI 2.92 FCGI CGI::Fast . $deps{'SPEEDYCGI'} = [ text_to_hash( << '.') ]; CGI 2.92 CGI::SpeedyCGI . $deps{'MODPERL1'} = [ text_to_hash( << '.') ]; CGI 2.92 Apache::Request Apache::DBI 0.92 . $deps{'MODPERL2'} = [ text_to_hash( << '.') ]; CGI 2.92 Apache::DBI HTML::Mason 1.31 . $deps{'MYSQL'} = [ text_to_hash( << '.') ]; DBD::mysql 2.1018 . $deps{'ORACLE'} = [ text_to_hash( << '.') ]; DBD::Oracle . $deps{'POSTGRESQL'} = [ text_to_hash( << '.') ]; DBD::Pg 1.43 . $deps{'SQLITE'} = [ text_to_hash( << '.') ]; DBD::SQLite 1.00 . if ($args{'download'}) { download_mods(); } check_perl_version(); check_users(); foreach my $type (sort grep $args{$_}, keys %args) { next unless ($type =~ /^with-(.*?)$/); $type = $1; section("$type dependencies"); my @missing; my @deps = @{ $deps{$type} }; while (@deps) { my $module = shift @deps; my $version = shift @deps; my $ret = test_dep($module, $version); push @missing, $module, $version unless $ret; } if ( $args{'install'} ) { while( @missing ) { resolve_dep(shift @missing, shift @missing); } } } conclude(); sub test_dep { my $module = shift; my $version = shift; eval "use $module $version ()"; if ($@) { my $error = $@; $error =~ s/\n(.*)$//s; undef $error unless $error =~ /this is only/; found("$module $version", 0, $error); return undef; } else { my $msg = "$module"; $msg .= " >=$version" if $version; found($msg, 1); return 1; } } sub resolve_dep { my $module = shift; my $version = shift; print "\nInstall module $module\n"; my $ext = $ENV{'RT_FIX_DEPS_CMD'}; unless( $ext ) { my $configured = 1; { local @INC = @INC; if ( $ENV{'HOME'} ) { unshift @INC, "$ENV{'HOME'}/.cpan"; } $configured = eval { require CPAN::MyConfig } || eval { require CPAN::Config }; } unless ( $configured ) { print <install($module) }; return $rv unless $@; print <&2`; } sub download_mods { my %modules; use CPAN; foreach my $key (keys %deps) { my @deps = (@{$deps{$key}}); while (@deps) { my $mod = shift @deps; my $ver = shift @deps; next if ($mod =~ /^(DBD-|Apache-Request)/); $modules{$mod} = $ver; } } my @mods = keys %modules; CPAN::get(); my $moddir = $args{'download'}; foreach my $mod (@mods) { $CPAN::Config->{'build_dir'} = $moddir; CPAN::get($mod); } opendir(DIR, $moddir); while ( my $dir = readdir(DIR)) { print "Dir is $dir\n"; next if ( $dir =~ /^\.\.?$/); # Skip things we've previously tagged my $out = `svn ls $args{'repository'}/tags/$dir`; next if ($out); if ($dir =~ /^(.*)-(.*?)$/) { `svn_load_dirs -no_user_input -t tags/$dir -v $args{'repository'} dists/$1 $moddir/$dir`; `rm -rf $moddir/$dir`; } } closedir(DIR); exit; } sub check_perl_version { section("perl"); eval {require 5.008003}; if ($@) { 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."); exit(1); } else { found( ">=5.8.3($])", 1); } } sub check_users { section("users"); found("rt group (@RTGROUP@)", defined getgrnam("@RTGROUP@")); found("bin owner (@BIN_OWNER@)", defined getpwnam("@BIN_OWNER@")); found("libs owner (@LIBS_OWNER@)", defined getpwnam("@LIBS_OWNER@")); found("libs group (@LIBS_GROUP@)", defined getgrnam("@LIBS_GROUP@")); found("web owner (@WEB_USER@)", defined getpwnam("@WEB_USER@")); found("web group (@WEB_GROUP@)", defined getgrnam("@WEB_GROUP@")); } 1;