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