git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCHv2 (RFC)] git-instaweb: Add support for running gitweb via 'plackup'

From
Jakub Narebski <jnareb@gmail.com>
Date
May 20, 2010, 11:56 UTC
Message-ID
<1274356584-2400-1-git-send-email-jnareb@gmail.com>
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
Previous: Jakub NarebskiNext: Jakub Narebski
Message 3 of 12 in “git-instaweb: Add support for running gitweb via 'plackup'”
  1. git-instaweb: Add support for running gitweb via 'plackup'Jakub Narebski, May 19, 2010
  2. Jakub NarebskiMay 19, 2010
  3. [PATCHv2 (RFC)] git-instaweb: Add support for running gitweb via 'plackup'Jakub Narebski, May 20, 2010
  4. [RFC/PATCHv3] git-instaweb: Add support for running gitweb via 'plackup'Jakub Narebski, May 20, 2010
  5. Jakub NarebskiMay 22, 2010
  6. Eric WongMay 23, 2010
  7. Jakub NarebskiMay 23, 2010
  8. Ævar Arnfjörð BjarmasonMay 23, 2010
  9. Jakub NarebskiMay 25, 2010
  10. Jakub NarebskiMay 25, 2010
  11. Eric WongMay 23, 2010
  12. Jakub NarebskiMay 23, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.