summaryrefslogtreecommitdiff
path: root/rt/devel
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2014-09-15 20:44:48 -0700
committerIvan Kohler <ivan@freeside.biz>2014-09-15 20:44:48 -0700
commited1f84b4e8f626245995ecda5afcf83092c153b2 (patch)
tree3f58bbef5fbf2502e65d29b37b5dbe537519e89d /rt/devel
parentfe9ea9183e8a16616d6d04a7b5c7498d28e78248 (diff)
RT 4.0.22
Diffstat (limited to 'rt/devel')
-rw-r--r--rt/devel/tools/localhost.crt17
-rw-r--r--rt/devel/tools/localhost.key27
-rw-r--r--rt/devel/tools/mime.types4
-rw-r--r--rt/devel/tools/rt-apache439
-rw-r--r--rt/devel/tools/rt-static-docs225
5 files changed, 712 insertions, 0 deletions
diff --git a/rt/devel/tools/localhost.crt b/rt/devel/tools/localhost.crt
new file mode 100644
index 0000000..bc8e572
--- /dev/null
+++ b/rt/devel/tools/localhost.crt
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAY4CCQDLtMptx45HuDANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDEwls
+b2NhbGhvc3QwIBcNMTIwMjE3MjIxMTU3WhgPMjExMjAxMjQyMjExNTdaMBQxEjAQ
+BgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKokK5sAKbNkJDoOInDQpwRxDDfanXKUR7MK761G2gWmUpxy+hlUn457VLgDKgDp
+s3gSUk0x3rsXcMxpsSDQ+E37kz5DnbPGSGdiS5tJD6VoQ2NsMfvrY1pZFWNv8wHu
+c4MDtStxsIxvZHjqguWeVUsXLKSfGEMTQ/MbKbn4d/7FSRpQDum2o3AsxHi4VbrS
+aWXRgCfcPlwaoOSc73lCD0kuXIl66wO8DBQOqqBtkuS59BcH+cq1T5wwKzMdJNfp
+Rx0TXISGUa4DSbTjqfAAJe4TzavH73PgNjXBl6+GsGb5/pf8Zad+t62xRcocDfOQ
+5e2ASmInsDtlSX0pfLfBHg0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAUuiDKlBN
+RcR/YYkk/hCgDB4ronO3AO+d264Y3vDK+JsH2lI6/kwxpmJj+bA2IVM+eM5NrcFh
+zEm+LKnyz4EvmxXTI4gI1iFPhOP4NJYmMtyKGavlZP3gNW4JQRYOiA0vQ2Egcngo
+uW2k7xUaNPPkpHptkI0P1jLVl4bX/qKA6tzrmwsmdwNOW9j9zk9BOq8HVvduBDeU
+XFsrdmN4EgD0nU39olaArg/RqMacIfCfKqYdRo9OSbBfQ7x2di9HgI1h2VVfPGi5
+cDRyLlpAY9KNuuStutcFMoQbdwKU/0GFkRuguFPJbIcDg7nhZDXRMU+XugQ8dsZ/
+0VgszAIRc510nA==
+-----END CERTIFICATE-----
diff --git a/rt/devel/tools/localhost.key b/rt/devel/tools/localhost.key
new file mode 100644
index 0000000..4b9dfe2
--- /dev/null
+++ b/rt/devel/tools/localhost.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAqiQrmwAps2QkOg4icNCnBHEMN9qdcpRHswrvrUbaBaZSnHL6
+GVSfjntUuAMqAOmzeBJSTTHeuxdwzGmxIND4TfuTPkOds8ZIZ2JLm0kPpWhDY2wx
+++tjWlkVY2/zAe5zgwO1K3GwjG9keOqC5Z5VSxcspJ8YQxND8xspufh3/sVJGlAO
+6bajcCzEeLhVutJpZdGAJ9w+XBqg5JzveUIPSS5ciXrrA7wMFA6qoG2S5Ln0Fwf5
+yrVPnDArMx0k1+lHHRNchIZRrgNJtOOp8AAl7hPNq8fvc+A2NcGXr4awZvn+l/xl
+p363rbFFyhwN85Dl7YBKYiewO2VJfSl8t8EeDQIDAQABAoIBAGeZsrulM786QRzg
+snQDeU+pDomMIsc8JxSMmjjmpac/CZqeIFAASU/XJVUPCCqaI1//uAGtVjSSJ2sx
+CFw1Ip1JjPUi8woeuMPLBMK/kDll7XLC1QTS5iKDkBSGfHA2pDuorE6R4bEBuyot
+khsDeGhK6jIrdfiR6JRFe/jzpQ2KUV7PDKhcGjWdCCGoss7s2d0Gx4UdlYn456Dr
+atPLXU9Aspg7uIUSO44Zwal03k25S0EW4WjdFCx3+1WqXs8l+XNXlqowZSL8qjOy
+cL2H5bpElE+NjSsHtTZdzC8jcDhbIRp8cZD32t+BRY5gqodKw+Z3MmblL2b3/qPi
+xNMaq8ECgYEA3ACjPUhRb7kYMgmowOXR/HL9Aht+4uCM+UM/pz0S4rn4MooBuCwv
+Nc0oFi5wFNJpFsOsiJwik7re1/olPPneZWgZWgBoiQl4+OB5hzvLc56B9Ez3Z84X
+19BxKcUaf5gXjxVAAAeKxn8ZbL/OHB3WvYP4zsIO1J+ijOe2LZJFEpUCgYEAxfr4
+RsK8avAdgOC0e/uB007rtiErCIaVnK/1WMPwWb5FxDkkl31MTB6oLO/JU5zfCsE1
+ROtnehB69c73sokWzAqMCuVFs+M0Owq1Kdm63b1k0wtUZL7v3wfGoUgZFL/65LDg
+RQ2Grntul5H7XS9c9v7Tn9GSo8VIbej6fvPPN5kCgYAqbL0N7ko1/z2ZOJ+gQzFR
+O2Nq6p53ZdIJp1w5BeAEdNRV+qMGPw8DkwJt9JqMiV7WkvlMhr9sOZcLkyNnNNAc
+QgzRfE6sTnVTmQYWfANp0mFBGS6EiAu1BG8uHOJVRKEWaISk/M9YI95lSD+Y0HA+
+r5plVKrDed1AytYox5ImWQKBgC/VNQsTnaZQoTA0GiciWvmMxdJZLSaALcGPmb16
+iaWFHSINlFOtiDOT7Jn+zSuQaSsWByLBpVyOgsbE3H+cM4/UtIUlY7PUnxfsvFyC
+KG3Ohn+e6yL0JsxB+rGY08Z5o8qBGY5VeEbLt6qTMKIRAWsDommonr9GuPslIPBv
+Q49xAoGAI7LBHEJtPTJx56EcKicST++NzUYha7E8nkqogs9oTTpdT6n+viHDCNud
+YUUK2slnEvgOPtNEkf1kHTqcajKZmIVpQi1cZqKzPCgk49JM+2OU+98qFR8UKe8i
+s5t09zDVhy9Hy+MaASqbU1AQT9bWbyfsgormjQ5jzadDdP5zovE=
+-----END RSA PRIVATE KEY-----
diff --git a/rt/devel/tools/mime.types b/rt/devel/tools/mime.types
new file mode 100644
index 0000000..83ef24d
--- /dev/null
+++ b/rt/devel/tools/mime.types
@@ -0,0 +1,4 @@
+# This is a mime.types for only the file types which we serve
+# statically (those that Apache might care about).
+image/gif gif
+image/png png
diff --git a/rt/devel/tools/rt-apache b/rt/devel/tools/rt-apache
new file mode 100644
index 0000000..ba130de
--- /dev/null
+++ b/rt/devel/tools/rt-apache
@@ -0,0 +1,439 @@
+#!/usr/bin/env perl
+
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+# <sales@bestpractical.com>
+#
+# (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/licenses/old-licenses/gpl-2.0.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 }}}
+use strict;
+use warnings;
+
+use Getopt::Long;
+use FindBin;
+use Pod::Usage;
+use File::Spec::Functions qw(rel2abs);
+
+my %opt = (
+ root => ($ENV{RTHOME} || "/opt/rt4"),
+
+ fcgid => 0,
+ fastcgi => 0,
+ perl => 0,
+
+ modules => "/usr/lib/apache2/modules",
+);
+
+GetOptions( \%opt,
+ "root=s",
+
+ "rt3|3!",
+
+ "fcgid!",
+ "fastcgi!",
+ "perl!",
+
+ "port|p=i",
+ "ssl:i",
+ "single|X",
+
+ "modules=s",
+
+ "help|h|?",
+) or pod2usage( 1 );
+pod2usage( {verbose => 2} ) if $opt{help};
+
+# All paths must be absolute
+$opt{$_} = rel2abs($opt{$_})
+ for qw(root modules);
+
+# Determine what module to use
+my $mod;
+if ($opt{fcgid} + $opt{fastcgi} + $opt{perl} > 1) {
+ die "Can only supply one of fcgid, fastcgi, or perl\n";
+} elsif ($opt{fcgid} + $opt{fastcgi} + $opt{perl} == 0) {
+ my @guess = qw(fastcgi fcgid perl);
+ @guess = grep {-f "$opt{modules}/mod_$_.so"} @guess;
+ die "Neither mod_fcgid, mod_fastcgi, nor mod_perl are installed; aborting\n"
+ unless @guess;
+ warn "No deployment given -- assuming mod_$guess[0] deployment\n";
+ $mod = $guess[0];
+} else {
+ $mod = (grep {$opt{$_}} qw(fastcgi fcgid perl))[0];
+}
+
+# Sanity check that the root contains an RT install
+die "$opt{root} doesn't look like an RT install\n"
+ unless -e "$opt{root}/lib/RT.pm";
+
+# Detect if we are actually rt3
+if (not -e "$opt{root}/sbin/rt-server.fcgi"
+ and -e "$opt{root}/bin/mason_handler.fcgi") {
+ $opt{rt3}++;
+ warn "RT3 install detected!\n";
+}
+
+# Parse etc/RT_SiteConfig.pm for the default port
+my $RTCONF;
+$opt{port} ||= parseconf( "WebPort" );
+unless ($opt{port}) {
+ warn "Defaulting to port 8888\n";
+ $opt{port} = 8888;
+}
+
+# Set ssl port if they want it but didn't provide a number
+$opt{ssl} = 4430 if defined $opt{ssl} and not $opt{ssl};
+
+# Parse out the WebPath
+my $path = parseconf( "WebPath" ) || "";
+
+my $template = join("", <DATA>);
+$template =~ s/\$PORT/$opt{port}/g;
+$template =~ s!\$PATH/!$path/!g;
+$template =~ s!\$PATH!$path || "/"!ge;
+$template =~ s/\$SSL/$opt{ssl} || 0/ge;
+$template =~ s/\$RTHOME/$opt{root}/g;
+$template =~ s/\$MODULES/$opt{modules}/g;
+$template =~ s/\$TOOLS/$FindBin::Bin/g;
+$template =~ s/\$PROCESSES/$opt{single} ? 1 : 3/ge;
+
+my $conf = "$opt{root}/var/apache.conf";
+open(CONF, ">", $conf)
+ or die "Can't write $conf: $!";
+print CONF $template;
+close CONF;
+
+my @opts = ("-f", $conf, "-D" . uc($mod) );
+push @opts, "-DSSL" if $opt{ssl};
+push @opts, "-DRT3" if $opt{rt3};
+push @opts, "-DSINGLE" if $opt{single};
+
+# Wait for a previous run to terminate
+if ( open( PIDFILE, "<", "$opt{root}/var/apache2.pid") ) {
+ my $pid = <PIDFILE>;
+ chomp $pid;
+ close PIDFILE;
+ if ($pid and kill 0, $pid) {
+ warn "Waiting for previous run (pid $pid) to finish...\n";
+ sleep 1 while kill 0, $pid;
+ }
+}
+
+# Clean out the log in preparation
+my $log = "$opt{root}/var/log/apache-error.log";
+unlink($log);
+
+# Start 'er up
+warn "Starting apache server on http://localhost:$opt{port}$path/"
+ . ($opt{ssl} ? " and https://localhost:$opt{ssl}$path/" : "") . "\n";
+!system("apache2", @opts, "-k", "start")
+ or die "Can't exec apache2: $@";
+# Ignore the return value, as we expect it to be ^C'd
+system("tail", "-f", $log);
+warn "Shutting down apache...\n";
+!system("apache2", @opts, "-k", "stop")
+ or die "Can't exec apache2: $@";
+
+
+sub parseconf {
+ my ($optname) = @_;
+ # We're going to be evil, and try to parse the config
+ unless (defined $RTCONF) {
+ unless ( open(CONF, "<", "$opt{root}/etc/RT_SiteConfig.pm") ) {
+ warn "Can't open $opt{root}/etc/RT_SiteConfig.pm: $!\n";
+ $RTCONF = "";
+ return;
+ }
+ $RTCONF = join("", <CONF>);
+ close CONF;
+ }
+
+ return unless $RTCONF =~ /^\s*Set\(\s*\$$optname\s*(?:,|=>)\s*['"]?(.*?)['"]?\s*\)/m;
+ return $1;
+}
+
+=head1 NAME
+
+rt-apache - Wrapper to start Apache running RT
+
+=head1 DESCRIPTION
+
+This script exists to make it easier to run RT under Apache for testing.
+It is not intended as a way to deploy RT, or to provide example Apache
+configuration for RT. For instructions on how to deploy RT with Apache,
+please read the provided F<docs/web_deployment.pod> file.
+
+Running this script will start F<apache2> with a custom-built
+configuration file, built based on command-line options and the contents
+of your F<RT_SiteConfig.pm>. It will work with either RT 3.8.x or RT
+4.0.x. As it is primarily for simple testing, it runs Apache as the
+current user.
+
+=head1 OPTIONS
+
+C<rt-apache> will parse your F<RT_SiteConfig.pm> for its C<WebPath> and
+C<WebPort> configuration, and adjust its defaults accordingly.
+
+=over
+
+=item --root B<path>
+
+The path to the RT install to serve. This defaults to the C<RTHOME>
+environment variable, or C</opt/rt4>.
+
+=item --fastcgi, --fcgid, --perl
+
+Determines the Apache module which is used. By default, the first one
+of that list which exists will be used. See also L</--modules>.
+
+=item --port B<number>
+
+Choses the port to listen on. By default, this is parsed from the
+F<RT_SiteConfig.pm>, and falling back to 8888.
+
+=item --ssl [B<number>]
+
+Also listens on the provided port with HTTPS, using a self-signed
+certificate for C<localhost>. If the port number is not specified,
+defaults to port 4430.
+
+=item --single, -X
+
+Run only one process or thread, for ease of debugging.
+
+=item --rt3, -3
+
+Declares that the RT install in question is RT 3.8.x. C<rt-apache> can
+usually detect this for you, however.
+
+=item --modules B<path>
+
+The path to the Apache2 modules directory, which is expected to contain
+at least one of F<mod_fcgid.so>, F<mod_fastcgi.so>, or F<mod_perl.so>.
+Defaults to F</usr/lib/apache2/modules>.
+
+=back
+
+=cut
+
+__DATA__
+<IfDefine SINGLE>
+ <IfModule mpm_prefork_module>
+ StartServers 1
+ MinSpareServers 1
+ MaxSpareServers 1
+ MaxClients 1
+ MaxRequestsPerChild 0
+ </IfModule>
+
+ <IfModule mpm_worker_module>
+ StartServers 1
+ MinSpareThreads 1
+ MaxSpareThreads 1
+ ThreadLimit 1
+ ThreadsPerChild 1
+ MaxClients 1
+ MaxRequestsPerChild 0
+ </IfModule>
+</IfDefine>
+
+Listen $PORT
+<IfDefine SSL>
+ Listen $SSL
+</IfDefine>
+
+ServerName localhost
+ServerRoot $RTHOME/var
+PidFile $RTHOME/var/apache2.pid
+LockFile $RTHOME/var/apache2.lock
+ServerAdmin root@localhost
+
+LoadModule authz_host_module $MODULES/mod_authz_host.so
+LoadModule env_module $MODULES/mod_env.so
+LoadModule alias_module $MODULES/mod_alias.so
+LoadModule mime_module $MODULES/mod_mime.so
+TypesConfig $TOOLS/mime.types
+
+<IfDefine PERL>
+ LoadModule perl_module $MODULES/mod_perl.so
+</IfDefine>
+<IfDefine FASTCGI>
+ LoadModule fastcgi_module $MODULES/mod_fastcgi.so
+</IfDefine>
+<IfDefine FCGID>
+ LoadModule fcgid_module $MODULES/mod_fcgid.so
+</IfDefine>
+<IfDefine SSL>
+ LoadModule ssl_module $MODULES/mod_ssl.so
+</IfDefine>
+
+<IfModule !log_config_module>
+ LoadModule log_config_module $MODULES/mod_log_config.so
+</IfModule>
+ErrorLog "$RTHOME/var/log/apache-error.log"
+TransferLog "$RTHOME/var/log/apache-access.log"
+LogLevel notice
+
+<Directory />
+ Options FollowSymLinks
+ AllowOverride None
+ Order deny,allow
+ Deny from all
+</Directory>
+
+AddDefaultCharset UTF-8
+
+DocumentRoot $RTHOME/share/html
+<Directory $RTHOME/share/html>
+ Order allow,deny
+ Allow from all
+</Directory>
+
+Alias $PATH/NoAuth/images/ $RTHOME/share/html/NoAuth/images/
+<Directory $RTHOME/share/html/NoAuth/images>
+ Order allow,deny
+ Allow from all
+</Directory>
+
+<IfDefine !RT3>
+########## 4.0 mod_perl
+<IfDefine PERL>
+ PerlSetEnv RT_SITE_CONFIG $RTHOME/etc/RT_SiteConfig.pm
+ <Location $PATH>
+ Order allow,deny
+ Allow from all
+ SetHandler modperl
+ PerlResponseHandler Plack::Handler::Apache2
+ PerlSetVar psgi_app $RTHOME/sbin/rt-server
+ </Location>
+ <Perl>
+ use Plack::Handler::Apache2;
+ Plack::Handler::Apache2->preload("$RTHOME/sbin/rt-server");
+ </Perl>
+</IfDefine>
+
+########## 4.0 mod_fastcgi
+<IfDefine FASTCGI>
+ FastCgiIpcDir $RTHOME/var
+ FastCgiServer $RTHOME/sbin/rt-server.fcgi -processes $PROCESSES -idle-timeout 300
+ ScriptAlias $PATH $RTHOME/sbin/rt-server.fcgi/
+ <Location $PATH>
+ Order allow,deny
+ Allow from all
+ Options +ExecCGI
+ AddHandler fastcgi-script fcgi
+ </Location>
+</IfDefine>
+
+########## 4.0 mod_fcgid
+<IfDefine FCGID>
+ FcgidProcessTableFile $RTHOME/var/fcgid_shm
+ FcgidIPCDir $RTHOME/var
+ FcgidMaxRequestLen 1073741824
+ ScriptAlias $PATH $RTHOME/sbin/rt-server.fcgi/
+ <Location $PATH>
+ Order allow,deny
+ Allow from all
+ Options +ExecCGI
+ AddHandler fcgid-script fcgi
+ </Location>
+</IfDefine>
+</IfDefine>
+
+
+<IfDefine RT3>
+########## 3.8 mod_perl
+<IfDefine PERL>
+ PerlSetEnv RT_SITE_CONFIG $RTHOME/etc/RT_SiteConfig.pm
+ PerlRequire "$RTHOME/bin/webmux.pl"
+ <Location $PATH/NoAuth/images>
+ SetHandler default
+ </Location>
+ <Location $PATH>
+ SetHandler perl-script
+ PerlResponseHandler RT::Mason
+ </Location>
+</IfDefine>
+
+########## 3.8 mod_fastcgi
+<IfDefine FASTCGI>
+ FastCgiIpcDir $RTHOME/var
+ FastCgiServer $RTHOME/bin/mason_handler.fcgi -processes $PROCESSES -idle-timeout 300
+ ScriptAlias $PATH $RTHOME/bin/mason_handler.fcgi/
+ <Location $PATH>
+ Order allow,deny
+ Allow from all
+ Options +ExecCGI
+ AddHandler fastcgi-script fcgi
+ </Location>
+</IfDefine>
+
+########## 3.8 mod_fcgid
+<IfDefine FCGID>
+ FcgidProcessTableFile $RTHOME/var/fcgid_shm
+ FcgidIPCDir $RTHOME/var
+ FcgidMaxRequestLen 1073741824
+ ScriptAlias $PATH $RTHOME/bin/mason_handler.fcgi/
+ <Location $PATH>
+ Order allow,deny
+ Allow from all
+ Options +ExecCGI
+ AddHandler fcgid-script fcgi
+ </Location>
+</IfDefine>
+</IfDefine>
+
+<IfDefine SSL>
+ SSLRandomSeed startup builtin
+ SSLRandomSeed startup file:/dev/urandom 512
+ SSLRandomSeed connect builtin
+ SSLRandomSeed connect file:/dev/urandom 512
+ SSLSessionCache shmcb:$RTHOME/var/ssl_scache(512000)
+ SSLMutex file:$RTHOME/var/ssl_mutex
+ <VirtualHost *:$SSL>
+ SSLEngine on
+ SSLCertificateFile $TOOLS/localhost.crt
+ SSLCertificateKeyFile $TOOLS/localhost.key
+ </VirtualHost>
+</IfDefine>
diff --git a/rt/devel/tools/rt-static-docs b/rt/devel/tools/rt-static-docs
new file mode 100644
index 0000000..30d422d
--- /dev/null
+++ b/rt/devel/tools/rt-static-docs
@@ -0,0 +1,225 @@
+#!/usr/bin/env perl
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC
+# <sales@bestpractical.com>
+#
+# (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/licenses/old-licenses/gpl-2.0.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 }}}
+use strict;
+use warnings;
+
+use Getopt::Long;
+use File::Temp;
+use File::Spec;
+use File::Path qw(make_path rmtree);
+use File::Copy qw(copy);
+use HTML::Entities qw(encode_entities);
+use RT::Pod::HTMLBatch;
+
+my %opts;
+GetOptions(
+ \%opts,
+ "help|h",
+ "rt=s",
+ "to=s",
+);
+
+if ( $opts{'help'} ) {
+ require Pod::Usage;
+ print Pod::Usage::pod2usage( -verbose => 2 );
+ exit;
+}
+
+die "--to=DIRECTORY is required\n" unless $opts{to};
+
+$opts{to} = File::Spec->rel2abs($opts{to});
+
+make_path( $opts{to} ) unless -e $opts{to};
+die "--to MUST be a directory\n" unless -d $opts{to};
+
+# Unpack the tarball, if that's what we're given.
+my $tmpdir;
+if (($opts{rt} || '') =~ /\.tar\.gz$/ and -f $opts{rt}) {
+ $tmpdir = File::Temp->newdir();
+
+ system("tar", "xzpf", $opts{rt}, "-C", $tmpdir);
+ $opts{rt} = <$tmpdir/rt-*>;
+}
+chdir $opts{rt} if $opts{rt};
+
+my @dirs = (
+ qw(
+ docs
+ etc
+ lib
+ bin
+ sbin
+ devel/tools
+ local/lib
+ local/sbin
+ local/bin
+ ),
+ glob("local/plugins/*/{lib,sbin,bin}"),
+ glob("docs/UPGRADING*"),
+);
+
+my $converter = RT::Pod::HTMLBatch->new;
+
+sub generate_configure_help {
+ my $configure = shift;
+ my $help = `./$configure --help`;
+ my $dest = "$opts{to}/configure.html";
+
+ if ($help and open my $html, ">", $dest) {
+ print $html join "\n",
+ "<pre>", encode_entities($help), "</pre>", "\n";
+ close $html;
+ $converter->note_for_contents_file(["configure options"], $configure, $dest);
+ } else {
+ warn "Can't open $dest: $!";
+ }
+}
+
+# Generate a page for ./configure --help if we can
+if (-x "configure.ac" and -d ".git") {
+ rmtree("autom4te.cache") if -d "autom4te.cache";
+ generate_configure_help("configure.ac");
+}
+elsif (-x "configure") {
+ generate_configure_help("configure");
+}
+else {
+ warn "Unable to generate a page for ./configure --help!\n";
+}
+
+# Manually "convert" README* and 3.8-era UPGRADING* to HTML and push them into
+# the known contents.
+for my $file (<README* UPGRADING*>) {
+ (my $name = $file) =~ s{^.+/}{};
+ my $dest = "$opts{to}/$name.html";
+
+ open my $source, "<", $file
+ or warn "Can't open $file: $!", next;
+
+ open my $html, ">", $dest
+ or warn "Can't open $dest: $!", next;
+
+ print $html "<pre>";
+ print $html encode_entities($_) while <$source>;
+ print $html "</pre>";
+
+ close $source; close $html;
+
+ $converter->note_for_contents_file([$name], $file, $dest);
+}
+
+# Copy images into place
+make_path("$opts{to}/images/");
+copy($_, "$opts{to}/images/")
+ for <docs/images/*.{png,jpeg,jpg,gif}>;
+
+# Temporarily set executable bits on upgrading doc to work around
+# Pod::Simple::Search limitation/bug:
+# https://rt.cpan.org/Ticket/Display.html?id=80082
+sub system_chmod {
+ system("chmod", @_) == 0
+ or die "Unable to chmod: $! (exit $?)";
+}
+system_chmod("+x", $_) for <docs/UPGRADING*>;
+
+# Convert each POD file to HTML
+$converter->batch_convert( \@dirs, $opts{to} );
+
+# Remove execution bit from workaround above
+system_chmod("-x", $_) for <docs/UPGRADING*>;
+
+# Need to chdir back out, if we are in the tmpdir, to let it clean up
+chdir "/" if $tmpdir;
+
+exit 0;
+
+__END__
+
+=head1 NAME
+
+rt-static-docs - generate doc shipped with RT
+
+=head1 SYNOPSIS
+
+ rt-static-docs --to /path/to/output [--rt /path/to/rt]
+
+=head1 DESCRIPTION
+
+RT ships with documentation (written in POD) embedded in library files, at the
+end of utility scripts, and in standalone files. This script finds all of that
+documentation, collects and converts it into a nice set of HTML files, and tops
+it off with a helpful index.
+
+Best Practical uses this to publish documentation under
+L<http://bestpractical.com/rt/docs/>.
+
+=head1 OPTIONS
+
+=over
+
+=item --to
+
+Set the destination directory for the output files.
+
+=item --rt
+
+Set the RT base directory to search under. Defaults to the current working
+directory, which is fine if you're running this script as
+C<devel/tools/rt-static-docs>.
+
+May also point to a tarball (a file ending in C<.tar.gz>) which will be
+unpacked into a temporary directory and used as the RT base directory.
+
+=item --help
+
+Print this help.
+
+=back
+
+=cut