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