Add git-instaweb, instantly browse the working repo with gitweb
authorEric Wong <normalperson@yhbt.net>
Sat, 1 Jul 2006 22:14:14 +0000 (15:14 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 2 Jul 2006 01:29:26 +0000 (18:29 -0700)
I got tired of having to configure gitweb for every repository
I work on.  I sometimes prefer gitweb to standard GUIs like gitk
or gitview; so this lets me automatically configure gitweb to
browse my working repository and also opens my browser to it.

Updates from the original patch:

Added Apache/mod_perl2 compatibility if Dennis Stosberg's gitweb
has been applied, too: <20060621130708.Gcbc6e5c@leonov.stosberg.net>

General cleanups in shell code usage.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
.gitignore
Documentation/git-instaweb.txt [new file with mode: 0644]
Makefile
git-instaweb.sh [new file with mode: 0755]

index 7b954d587ec48314dee6c7d179e57607f958e875..2bcc604afea1871b2783a8768a1078572899b92f 100644 (file)
@@ -46,6 +46,7 @@ git-http-push
 git-imap-send
 git-index-pack
 git-init-db
+git-instaweb
 git-local-fetch
 git-log
 git-lost-found
diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt
new file mode 100644 (file)
index 0000000..7dd393b
--- /dev/null
@@ -0,0 +1,84 @@
+git-instaweb(1)
+===============
+
+NAME
+----
+git-instaweb - instantly browse your working repository in gitweb
+
+SYNOPSIS
+--------
+'git-instaweb' [--local] [--httpd=<httpd>] [--port=<port>] [--browser=<browser>]
+
+'git-instaweb' [--start] [--stop] [--restart]
+
+DESCRIPTION
+-----------
+A simple script to setup gitweb and a web server for browsing the local
+repository.
+
+OPTIONS
+-------
+
+-l|--local::
+       Only bind the web server to the local IP (127.0.0.1).
+
+-d|--httpd::
+       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, lighttpd and apache2 are the only supported servers.
+       (Default: lighttpd)
+
+-m|--module-path::
+       The module path (only needed if httpd is Apache).
+       (Default: /usr/lib/apache2/modules)
+
+-p|--port::
+       The port number to bind the httpd to.  (Default: 1234)
+
+-b|--browser::
+
+       The web browser command-line to execute to view the gitweb page.
+       If blank, the URL of the gitweb instance will be printed to
+       stdout.  (Default: 'firefox')
+
+--start::
+       Start the httpd instance and exit.  This does not generate
+       any of the configuration files for spawning a new instance.
+
+--stop::
+       Stop the httpd instance and exit.  This does not generate
+       any of the configuration files for spawning a new instance,
+       nor does it close the browser.
+
+--restart::
+       Restart the httpd instance and exit.  This does not generate
+       any of the configuration files for spawning a new instance.
+
+CONFIGURATION
+-------------
+
+You may specify configuration in your .git/config
+
+-----------------------------------------------------------------------
+[instaweb]
+       local = true
+       httpd = apache2 -f
+       port = 4321
+       browser = konqueror
+       modulepath = /usr/lib/apache2/modules
+
+-----------------------------------------------------------------------
+
+Author
+------
+Written by Eric Wong <normalperson@yhbt.net>
+
+Documentation
+--------------
+Documentation by Eric Wong <normalperson@yhbt.net>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
index cde619c498da717ea665430f7d395358d0b1d06e..83d8922295fd7a87fc0f4bdd03e91b5c4e755b4c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -142,7 +142,7 @@ SCRIPT_PYTHON = \
 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \
          $(patsubst %.perl,%,$(SCRIPT_PERL)) \
          $(patsubst %.py,%,$(SCRIPT_PYTHON)) \
-         git-cherry-pick git-status
+         git-cherry-pick git-status git-instaweb
 
 # The ones that do not have to link with lcrypto, lz nor xdiff.
 SIMPLE_PROGRAMS = \
@@ -545,6 +545,20 @@ git-status: git-commit
        cp $< $@+
        mv $@+ $@
 
+git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css
+       rm -f $@ $@+
+       sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
+           -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
+           -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
+           -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \
+           $@.sh | sed \
+           -e 's|@@GITWEB_CGI@@|#!$(PERL_PATH_SQ)|; T; r gitweb/gitweb.cgi' \
+           | sed \
+           -e 's|@@GITWEB_CSS@@||; T; r gitweb/gitweb.css' \
+           > $@+
+       chmod +x $@+
+       mv $@+ $@
+
 # These can record GIT_VERSION
 git$X git.spec \
        $(patsubst %.sh,%,$(SCRIPT_SH)) \
diff --git a/git-instaweb.sh b/git-instaweb.sh
new file mode 100755 (executable)
index 0000000..51067d9
--- /dev/null
@@ -0,0 +1,235 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Eric Wong
+#
+USAGE='[--start] [--stop] [--restart]
+  [--local] [--httpd=<httpd>] [--port=<port>] [--browser=<browser>]
+  [--module-path=<path> (for Apache2 only)]'
+
+. git-sh-setup
+
+case "$GIT_DIR" in
+/*)
+       fqgitdir="$GIT_DIR" ;;
+*)
+       fqgitdir="$PWD/$GIT_DIR" ;;
+esac
+
+local="`git repo-config --bool --get instaweb.local`"
+httpd="`git repo-config --get instaweb.httpd`"
+browser="`git repo-config --get instaweb.browser`"
+port=`git repo-config --get instaweb.port`
+module_path="`git repo-config --get instaweb.modulepath`"
+
+conf=$GIT_DIR/gitweb/httpd.conf
+
+# Defaults:
+
+# if installed, it doens't need further configuration (module_path)
+test -z "$httpd" && httpd='lighttpd -f'
+
+# probably the most popular browser among gitweb users
+test -z "$browser" && browser='firefox'
+
+# any untaken local port will do...
+test -z "$port" && port=1234
+
+start_httpd () {
+       httpd_only="`echo $httpd | cut -f1 -d' '`"
+       if test "`expr index $httpd_only /`" -eq '1' || \
+                               which $httpd_only >/dev/null
+       then
+               $httpd $fqgitdir/gitweb/httpd.conf
+       else
+               # many httpds are installed in /usr/sbin or /usr/local/sbin
+               # these days and those are not in most users $PATHs
+               for i in /usr/local/sbin /usr/sbin
+               do
+                       if test -x "$i/$httpd_only"
+                       then
+                               # don't quote $httpd, there can be
+                               # arguments to it (-f)
+                               $i/$httpd "$fqgitdir/gitweb/httpd.conf"
+                               return
+                       fi
+               done
+       fi
+}
+
+stop_httpd () {
+       test -f "$fqgitdir/pid" && kill `cat "$fqgitdir/pid"`
+}
+
+while case "$#" in 0) break ;; esac
+do
+       case "$1" in
+       --stop|stop)
+               stop_httpd
+               exit 0
+               ;;
+       --start|start)
+               start_httpd
+               exit 0
+               ;;
+       --restart|restart)
+               stop_httpd
+               start_httpd
+               exit 0
+               ;;
+       --local|-l)
+               local=true
+               ;;
+       -d|--httpd|--httpd=*)
+               case "$#,$1" in
+               *,*=*)
+                       httpd=`expr "$1" : '-[^=]*=\(.*\)'` ;;
+               1,*)
+                       usage ;;
+               *)
+                       httpd="$2"
+                       shift ;;
+               esac
+               ;;
+       -b|--browser|--browser=*)
+               case "$#,$1" in
+               *,*=*)
+                       browser=`expr "$1" : '-[^=]*=\(.*\)'` ;;
+               1,*)
+                       usage ;;
+               *)
+                       browser="$2"
+                       shift ;;
+               esac
+               ;;
+       -p|--port|--port=*)
+               case "$#,$1" in
+               *,*=*)
+                       port=`expr "$1" : '-[^=]*=\(.*\)'` ;;
+               1,*)
+                       usage ;;
+               *)
+                       port="$2"
+                       shift ;;
+               esac
+               ;;
+       -m|--module-path=*|--module-path)
+               case "$#,$1" in
+               *,*=*)
+                       module_path=`expr "$1" : '-[^=]*=\(.*\)'` ;;
+               1,*)
+                       usage ;;
+               *)
+                       module_path="$2"
+                       shift ;;
+               esac
+               ;;
+       *)
+               usage
+               ;;
+       esac
+       shift
+done
+
+mkdir -p "$GIT_DIR/gitweb/tmp"
+GIT_EXEC_PATH="`git --exec-path`"
+GIT_DIR="$fqgitdir"
+export GIT_EXEC_PATH GIT_DIR
+
+
+lighttpd_conf () {
+       cat > "$conf" <<EOF
+server.document-root = "$fqgitdir/gitweb"
+server.port = $port
+server.modules = ( "mod_cgi" )
+server.indexfiles = ( "gitweb.cgi" )
+server.pid-file = "$fqgitdir/pid"
+cgi.assign = ( ".cgi" => "" )
+mimetype.assign = ( ".css" => "text/css" )
+EOF
+       test "$local" = true && echo 'server.bind = "127.0.0.1"' >> "$conf"
+}
+
+apache2_conf () {
+       test -z "$module_path" && module_path=/usr/lib/apache2/modules
+       mkdir -p "$GIT_DIR/gitweb/logs"
+       bind=
+       test "$local" = true && bind='127.0.0.1:'
+       echo 'text/css css' > $fqgitdir/mime.types
+       cat > "$conf" <<EOF
+ServerRoot "$fqgitdir/gitweb"
+DocumentRoot "$fqgitdir/gitweb"
+PidFile "$fqgitdir/pid"
+Listen $bind$port
+TypesConfig $fqgitdir/mime.types
+DirectoryIndex gitweb.cgi
+EOF
+
+       # check to see if Dennis Stosberg's mod_perl compatibility patch
+       # (<20060621130708.Gcbc6e5c@leonov.stosberg.net>) has been applied
+       if test -f "$module_path/mod_perl.so" && grep '^our $gitbin' \
+                               "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null
+       then
+               # favor mod_perl if available
+               cat >> "$conf" <<EOF
+LoadModule perl_module $module_path/mod_perl.so
+PerlPassEnv GIT_DIR
+PerlPassEnv GIT_EXEC_DIR
+<Location /gitweb.cgi>
+       SetHandler perl-script
+       PerlResponseHandler ModPerl::Registry
+       PerlOptions +ParseHeaders
+       Options +ExecCGI
+</Location>
+EOF
+       else
+               # plain-old CGI
+               cat >> "$conf" <<EOF
+LoadModule cgi_module $module_path/mod_cgi.so
+AddHandler cgi-script .cgi
+<Location /gitweb.cgi>
+       Options +ExecCGI
+</Location>
+EOF
+       fi
+}
+
+script='
+s#^\(my\|our\) $projectroot =.*#\1 $projectroot = "'`dirname $fqgitdir`'";#;
+s#\(my\|our\) $gitbin =.*#\1 $gitbin = "'$GIT_EXEC_PATH'";#;
+s#\(my\|our\) $projects_list =.*#\1 $projects_list = $projectroot;#;
+s#\(my\|our\) $git_temp =.*#\1 $git_temp = "'$fqgitdir/gitweb/tmp'";#'
+
+gitweb_cgi () {
+       cat > "$1.tmp" <<\EOFGITWEB
+@@GITWEB_CGI@@
+EOFGITWEB
+       sed "$script" "$1.tmp"  > "$1"
+       chmod +x "$1"
+       rm -f "$1.tmp"
+}
+
+gitweb_css () {
+       cat > "$1" <<\EOFGITWEB
+@@GITWEB_CSS@@
+EOFGITWEB
+}
+
+gitweb_cgi $GIT_DIR/gitweb/gitweb.cgi
+gitweb_css $GIT_DIR/gitweb/gitweb.css
+
+case "$httpd" in
+*lighttpd*)
+       lighttpd_conf
+       ;;
+*apache2*)
+       apache2_conf
+       ;;
+*)
+       echo "Unknown httpd specified: $httpd"
+       exit 1
+       ;;
+esac
+
+start_httpd
+test -z "$browser" && browser=echo
+$browser http://127.0.0.1:$port