git-instaweb.shon commit git-cvsserver runs hooks/post-receive (cdf6328)
   1#!/bin/sh
   2#
   3# Copyright (c) 2006 Eric Wong
   4#
   5
   6OPTIONS_KEEPDASHDASH=
   7OPTIONS_SPEC="\
   8git-instaweb [options] (--start | --stop | --restart)
   9--
  10l,local        only bind on 127.0.0.1
  11p,port=        the port to bind to
  12d,httpd=       the command to launch
  13b,browser=     the browser to launch
  14m,module-path= the module path (only needed for apache2)
  15 Action
  16stop           stop the web server
  17start          start the web server
  18restart        restart the web server
  19"
  20
  21. git-sh-setup
  22
  23fqgitdir="$GIT_DIR"
  24local="`git config --bool --get instaweb.local`"
  25httpd="`git config --get instaweb.httpd`"
  26browser="`git config --get instaweb.browser`"
  27port=`git config --get instaweb.port`
  28module_path="`git config --get instaweb.modulepath`"
  29
  30conf="$GIT_DIR/gitweb/httpd.conf"
  31
  32# Defaults:
  33
  34# if installed, it doesn't need further configuration (module_path)
  35test -z "$httpd" && httpd='lighttpd -f'
  36
  37# probably the most popular browser among gitweb users
  38test -z "$browser" && browser='firefox'
  39
  40# any untaken local port will do...
  41test -z "$port" && port=1234
  42
  43start_httpd () {
  44        httpd_only="`echo $httpd | cut -f1 -d' '`"
  45        if case "$httpd_only" in /*) : ;; *) which $httpd_only >/dev/null;; esac
  46        then
  47                $httpd "$fqgitdir/gitweb/httpd.conf"
  48        else
  49                # many httpds are installed in /usr/sbin or /usr/local/sbin
  50                # these days and those are not in most users $PATHs
  51                # in addition, we may have generated a server script
  52                # in $fqgitdir/gitweb.
  53                for i in /usr/local/sbin /usr/sbin "$fqgitdir/gitweb"
  54                do
  55                        if test -x "$i/$httpd_only"
  56                        then
  57                                # don't quote $httpd, there can be
  58                                # arguments to it (-f)
  59                                $i/$httpd "$fqgitdir/gitweb/httpd.conf"
  60                                return
  61                        fi
  62                done
  63                echo "$httpd_only not found. Install $httpd_only or use" \
  64                     "--httpd to specify another http daemon."
  65                exit 1
  66        fi
  67        if test $? != 0; then
  68                echo "Could not execute http daemon $httpd."
  69                exit 1
  70        fi
  71}
  72
  73stop_httpd () {
  74        test -f "$fqgitdir/pid" && kill `cat "$fqgitdir/pid"`
  75}
  76
  77while test $# != 0
  78do
  79        case "$1" in
  80        --stop|stop)
  81                stop_httpd
  82                exit 0
  83                ;;
  84        --start|start)
  85                start_httpd
  86                exit 0
  87                ;;
  88        --restart|restart)
  89                stop_httpd
  90                start_httpd
  91                exit 0
  92                ;;
  93        -l|--local)
  94                local=true
  95                ;;
  96        -d|--httpd)
  97                shift
  98                httpd="$1"
  99                ;;
 100        -b|--browser)
 101                shift
 102                browser="$1"
 103                ;;
 104        -p|--port)
 105                shift
 106                port="$1"
 107                ;;
 108        -m|--module-path)
 109                shift
 110                module_path="$1"
 111                ;;
 112        --)
 113                ;;
 114        *)
 115                usage
 116                ;;
 117        esac
 118        shift
 119done
 120
 121mkdir -p "$GIT_DIR/gitweb/tmp"
 122GIT_EXEC_PATH="`git --exec-path`"
 123GIT_DIR="$fqgitdir"
 124export GIT_EXEC_PATH GIT_DIR
 125
 126
 127webrick_conf () {
 128        # generate a standalone server script in $fqgitdir/gitweb.
 129        cat >"$fqgitdir/gitweb/$httpd.rb" <<EOF
 130require 'webrick'
 131require 'yaml'
 132options = YAML::load_file(ARGV[0])
 133options[:StartCallback] = proc do
 134  File.open(options[:PidFile],"w") do |f|
 135    f.puts Process.pid
 136  end
 137end
 138options[:ServerType] = WEBrick::Daemon
 139server = WEBrick::HTTPServer.new(options)
 140['INT', 'TERM'].each do |signal|
 141  trap(signal) {server.shutdown}
 142end
 143server.start
 144EOF
 145        # generate a shell script to invoke the above ruby script,
 146        # which assumes _ruby_ is in the user's $PATH. that's _one_
 147        # portable way to run ruby, which could be installed anywhere,
 148        # really.
 149        cat >"$fqgitdir/gitweb/$httpd" <<EOF
 150#!/bin/sh
 151exec ruby "$fqgitdir/gitweb/$httpd.rb" \$*
 152EOF
 153        chmod +x "$fqgitdir/gitweb/$httpd"
 154
 155        cat >"$conf" <<EOF
 156:Port: $port
 157:DocumentRoot: "$fqgitdir/gitweb"
 158:DirectoryIndex: ["gitweb.cgi"]
 159:PidFile: "$fqgitdir/pid"
 160EOF
 161        test "$local" = true && echo ':BindAddress: "127.0.0.1"' >> "$conf"
 162}
 163
 164lighttpd_conf () {
 165        cat > "$conf" <<EOF
 166server.document-root = "$fqgitdir/gitweb"
 167server.port = $port
 168server.modules = ( "mod_cgi" )
 169server.indexfiles = ( "gitweb.cgi" )
 170server.pid-file = "$fqgitdir/pid"
 171cgi.assign = ( ".cgi" => "" )
 172mimetype.assign = ( ".css" => "text/css" )
 173EOF
 174        test x"$local" = xtrue && echo 'server.bind = "127.0.0.1"' >> "$conf"
 175}
 176
 177apache2_conf () {
 178        test -z "$module_path" && module_path=/usr/lib/apache2/modules
 179        mkdir -p "$GIT_DIR/gitweb/logs"
 180        bind=
 181        test x"$local" = xtrue && bind='127.0.0.1:'
 182        echo 'text/css css' > $fqgitdir/mime.types
 183        cat > "$conf" <<EOF
 184ServerName "git-instaweb"
 185ServerRoot "$fqgitdir/gitweb"
 186DocumentRoot "$fqgitdir/gitweb"
 187PidFile "$fqgitdir/pid"
 188Listen $bind$port
 189EOF
 190
 191        for mod in mime dir; do
 192                if test -e $module_path/mod_${mod}.so; then
 193                        echo "LoadModule ${mod}_module " \
 194                             "$module_path/mod_${mod}.so" >> "$conf"
 195                fi
 196        done
 197        cat >> "$conf" <<EOF
 198TypesConfig $fqgitdir/mime.types
 199DirectoryIndex gitweb.cgi
 200EOF
 201
 202        # check to see if Dennis Stosberg's mod_perl compatibility patch
 203        # (<20060621130708.Gcbc6e5c@leonov.stosberg.net>) has been applied
 204        if test -f "$module_path/mod_perl.so" && grep '^our $gitbin' \
 205                                "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null
 206        then
 207                # favor mod_perl if available
 208                cat >> "$conf" <<EOF
 209LoadModule perl_module $module_path/mod_perl.so
 210PerlPassEnv GIT_DIR
 211PerlPassEnv GIT_EXEC_DIR
 212<Location /gitweb.cgi>
 213        SetHandler perl-script
 214        PerlResponseHandler ModPerl::Registry
 215        PerlOptions +ParseHeaders
 216        Options +ExecCGI
 217</Location>
 218EOF
 219        else
 220                # plain-old CGI
 221                list_mods=`echo "$httpd" | sed "s/-f$/-l/"`
 222                $list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \
 223                echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
 224                cat >> "$conf" <<EOF
 225AddHandler cgi-script .cgi
 226<Location /gitweb.cgi>
 227        Options +ExecCGI
 228</Location>
 229EOF
 230        fi
 231}
 232
 233script='
 234s#^\(my\|our\) $projectroot =.*#\1 $projectroot = "'$(dirname "$fqgitdir")'";#
 235s#\(my\|our\) $gitbin =.*#\1 $gitbin = "'$GIT_EXEC_PATH'";#
 236s#\(my\|our\) $projects_list =.*#\1 $projects_list = $projectroot;#
 237s#\(my\|our\) $git_temp =.*#\1 $git_temp = "'$fqgitdir/gitweb/tmp'";#'
 238
 239gitweb_cgi () {
 240        cat > "$1.tmp" <<\EOFGITWEB
 241@@GITWEB_CGI@@
 242EOFGITWEB
 243        sed "$script" "$1.tmp"  > "$1"
 244        chmod +x "$1"
 245        rm -f "$1.tmp"
 246}
 247
 248gitweb_css () {
 249        cat > "$1" <<\EOFGITWEB
 250@@GITWEB_CSS@@
 251EOFGITWEB
 252}
 253
 254gitweb_cgi "$GIT_DIR/gitweb/gitweb.cgi"
 255gitweb_css "$GIT_DIR/gitweb/gitweb.css"
 256
 257case "$httpd" in
 258*lighttpd*)
 259        lighttpd_conf
 260        ;;
 261*apache2*)
 262        apache2_conf
 263        ;;
 264webrick)
 265        webrick_conf
 266        ;;
 267*)
 268        echo "Unknown httpd specified: $httpd"
 269        exit 1
 270        ;;
 271esac
 272
 273start_httpd
 274url=http://127.0.0.1:$port
 275"$browser" $url || echo $url