git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Cc: Jakub Narebski <jnareb@gmail.com>, Eric Wong <normalperson@yhbt.net>
Subject: [PATCHv2 (RFC)] git-instaweb: Add support for running gitweb via 'plackup'
Date: Thu, 20 May 2010 13:56:24 +0200	[thread overview]
Message-ID: <1274356584-2400-1-git-send-email-jnareb@gmail.com> (raw)
In-Reply-To: <201005192252.49461.jnareb@gmail.com>

PSGI is an interface between Perl web applications and web servers, and
Plack is a Perl module and toolkit that contains PSGI middleware, helpers
and adapters to web servers; see http://plackperl.org

PSGI and Plack are inspired by Python's WSGI and Ruby's Rack.

Plack core distribution includes HTTP::Server::PSGI, a reference PSGI
standalone web server implementation.  plackup is a command line launcher
to run PSGI applications from command line, connecting web app to a web
server via Plack::Runner module.  By default it uses HTTP::Server::PSGI
as a web server.

git-instaweb generates gitweb.psgi wrapper (in $GIT_DIR/gitweb).  This
wrapper uses Plack::App::WrapCGI to compile gitweb.cgi (which is a CGI
script) into a PSGI application using CGI::Compile and CGI::Emulate::PSGI.
git-instaweb then runs this wrapper, using by default HTTP::Server::PSGI
standalone Perl server.

The configuration for 'plackup' is currently embedded in generated
gitweb.psgi wrapper, instead of using httpd.conf ($conf).


To run git-instaweb with '--httpd=plackup', you need to have instaled
Plack core, CGI::Emulate::PSGI, CGI::Compile.  Those modules have to be
available for Perl scripts (which can be done for example by setting
PERL5LIB environment variable).  This is currently not documented.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
It lives^W works!  I have added 'httpd_is_ready' function, which
ensures that server is fully started before running web browser.
Currently it is non-trivial only for '--httpd=plackup'.


Currently gitweb.psgi wrapper uses Perl she-bang line, and
Plack::Runner module (if gitweb.psgi is run as a standalone script) to
configure used PSGI server in a server-agnostic way.

Attempts which didn't work or wouldn't work:

* Configuring plackup via command line options, i.e. setting $httpd
  to e.g.

     httpd="plackup --port=$port --host=127.0.0.1"

  But this wouldn't preserve options across server restart.

* Using

    #!/usr/bin/env plackup --port=$port --host=127.0.0.1

  as a she-bang line for gitweb.psgi wrapper.  It doesn't work because
  (in most cases) system passes everything after interpreter name as
  a _single_ option; in this case it would try to run

    /usr/bin/env 'plackup --port=$port --host=127.0.0.1' ...

  It also requires for plackup to be in $PATH.

* Using

    #!$PLACKUP --port=$port --host=127.0.0.1

  as a she-bang line for gitweb.psgi wrapper, after finding full path
  to 'plackup' and putting it in $PLACKUP variable (similar to $PERL).
  It doesn't work because (in most cases) system passes everything
  after interpreter name as a _single_ option; in this case it would
  try to run

    /path/to/plackup '--port=$port --host=127.0.0.1' ...

  Well, it would work if git-instaweb is run without '--local'... 

 Documentation/git-instaweb.txt |    2 +-
 git-instaweb.sh                |   71 +++++++++++++++++++++++++++++++++++++---
 2 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
index a1f17df..2c3c4d2 100644
--- a/Documentation/git-instaweb.txt
+++ b/Documentation/git-instaweb.txt
@@ -29,7 +29,7 @@ OPTIONS
 	The HTTP daemon command-line that will be executed.
 	Command-line options may be specified here, and the
 	configuration file will be added at the end of the command-line.
-	Currently apache2, lighttpd, mongoose and webrick are supported.
+	Currently apache2, lighttpd, mongoose, plackup and webrick are supported.
 	(Default: lighttpd)
 
 -m::
diff --git a/git-instaweb.sh b/git-instaweb.sh
index f608014..f69cb71 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -46,6 +46,13 @@ resolve_full_httpd () {
 			httpd="$httpd -f"
 		fi
 		;;
+	*plackup*)
+		# 'plackup must be in $PATH of user, currently
+		# server is started by running via generated gitweb.psgi in $fqgitdir/gitweb
+		bind=
+		full_httpd="$fqgitdir/gitweb/gitweb.psgi"
+		return
+		;;
 	esac
 
 	httpd_only="$(echo $httpd | cut -f1 -d' ')"
@@ -83,9 +90,9 @@ start_httpd () {
 
 	# don't quote $full_httpd, there can be arguments to it (-f)
 	case "$httpd" in
-	*mongoose*)
-		#The mongoose server doesn't have a daemon mode so we'll have to fork it
-		$full_httpd "$fqgitdir/gitweb/httpd.conf" &
+	*mongoose*|*plackup*)
+		#The mongoose server and plackup don't have a daemon mode so we'll have to fork it
+		$full_httpd "$fqgitdir/gitweb/httpd.conf" 2>"$fqgitdir/error_log" &
 		#Save the pid before doing anything else (we'll print it later)
 		pid=$!
 
@@ -112,6 +119,21 @@ stop_httpd () {
 	test -f "$fqgitdir/pid" && kill $(cat "$fqgitdir/pid")
 }
 
+httpd_is_ready () {
+	case "$httpd" in
+	*plackup*)
+		echo -n "Waiting for '$httpd' to start"
+		while ! grep 'Accepting connections' "$fqgitdir/error_log" >/dev/null 2>&1
+		do
+			sleep 1
+			echo -n "."
+		done
+		echo " (done)"
+		;;
+	esac
+	true
+}
+
 while test $# != 0
 do
 	case "$1" in
@@ -370,6 +392,42 @@ mime_types	.gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-t
 EOF
 }
 
+plackup_conf () {
+	cat > "$fqgitdir/gitweb/gitweb.psgi" <<GITWEB_PSGI_EOF
+#!$PERL
+
+# gitweb - simple web interface to track changes in git repositories
+#          PSGI wrapper (see http://plackperl.org)
+
+use strict;
+
+use Plack::Builder;
+use Plack::App::WrapCGI;
+use CGI::Emulate::PSGI 0.07; # minimum version required to work with gitweb
+
+my \$app = builder {
+	# serve static files, i.e. stylesheet, images, script
+	enable 'Static',
+		path => sub { m!\.(js|css|png)\$! && s!^/gitweb/!! },
+		root => "$fqgitdir/gitweb/";
+	# convert CGI application to PSGI app
+	Plack::App::WrapCGI->new(script => "$fqgitdir/gitweb/gitweb.cgi")->to_app;
+};
+
+# make it runnable as standalone app, like via plackup
+if (__FILE__ eq \$0) {
+	require Plack::Runner;
+
+	my \$runner = Plack::Runner->new();
+	\$runner->parse_options(qw(--port $port),
+	                       "$local" ? qw(--host 127.0.0.1) : ());
+	\$runner->run(\$app);
+}
+GITWEB_PSGI_EOF
+
+	chmod a+x "$fqgitdir/gitweb/gitweb.psgi"
+	rm -f "$fqgitdir/gitweb/gitweb.psgi.tmp" "$conf"
+}
 
 script='
 s#^(my|our) \$projectroot =.*#$1 \$projectroot = "'$(dirname "$fqgitdir")'";#;
@@ -419,6 +477,9 @@ webrick)
 *mongoose*)
 	mongoose_conf
 	;;
+*plackup*)
+	plackup_conf
+	;;
 *)
 	echo "Unknown httpd specified: $httpd"
 	exit 1
@@ -429,7 +490,7 @@ start_httpd
 url=http://127.0.0.1:$port
 
 if test -n "$browser"; then
-	git web--browse -b "$browser" $url || echo $url
+	httpd_is_ready && git web--browse -b "$browser" $url || echo $url
 else
-	git web--browse -c "instaweb.browser" $url || echo $url
+	httpd_is_ready && git web--browse -c "instaweb.browser" $url || echo $url
 fi
-- 
1.7.0.1

  reply	other threads:[~2010-05-20 11:56 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-19 17:31 [RFC/PATCH] git-instaweb: Add support for running gitweb via 'plackup' Jakub Narebski
2010-05-19 20:52 ` Jakub Narebski
2010-05-20 11:56   ` Jakub Narebski [this message]
2010-05-20 21:55     ` [RFC/PATCHv3] " Jakub Narebski
2010-05-22 21:30       ` Jakub Narebski
2010-05-23  9:19         ` Eric Wong
2010-05-23 11:17           ` Jakub Narebski
2010-05-23 12:38         ` Ævar Arnfjörð Bjarmason
2010-05-25  0:11           ` Jakub Narebski
2010-05-25  9:02       ` Jakub Narebski
2010-05-23  9:31   ` [RFC/PATCH] " Eric Wong
2010-05-23 20:21     ` Jakub Narebski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1274356584-2400-1-git-send-email-jnareb@gmail.com \
    --to=jnareb@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=normalperson@yhbt.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).