diff options
Diffstat (limited to 'git-instaweb.sh')
-rwxr-xr-x | git-instaweb.sh | 372 |
1 files changed, 275 insertions, 97 deletions
diff --git a/git-instaweb.sh b/git-instaweb.sh index cbc7418e35..b8e6456208 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -2,72 +2,117 @@ # # 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 +PERL='@@PERL@@' +OPTIONS_KEEPDASHDASH= +OPTIONS_SPEC="\ +git instaweb [options] (--start | --stop | --restart) +-- +l,local only bind on 127.0.0.1 +p,port= the port to bind to +d,httpd= the command to launch +b,browser= the browser to launch +m,module-path= the module path (only needed for apache2) + Action +stop stop the web server +start start the web server +restart restart the web server +" -case "$GIT_DIR" in -/*) - fqgitdir="$GIT_DIR" ;; -*) - fqgitdir="$PWD/$GIT_DIR" ;; -esac +. git-sh-setup -local="`git config --bool --get instaweb.local`" -httpd="`git config --get instaweb.httpd`" -browser="`git config --get instaweb.browser`" -port=`git config --get instaweb.port` -module_path="`git config --get instaweb.modulepath`" +fqgitdir="$GIT_DIR" +local="$(git config --bool --get instaweb.local)" +httpd="$(git config --get instaweb.httpd)" +port=$(git config --get instaweb.port) +module_path="$(git config --get instaweb.modulepath)" -conf=$GIT_DIR/gitweb/httpd.conf +conf="$GIT_DIR/gitweb/httpd.conf" # Defaults: # if installed, it doesn'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 +resolve_full_httpd () { + case "$httpd" in + *apache2*|*lighttpd*) + # ensure that the apache2/lighttpd command ends with "-f" + if ! echo "$httpd" | sane_grep -- '-f *$' >/dev/null 2>&1 + then + httpd="$httpd -f" + fi + ;; + esac + + httpd_only="$(echo $httpd | cut -f1 -d' ')" + if case "$httpd_only" in /*) : ;; *) which $httpd_only >/dev/null 2>&1;; esac then - $httpd $fqgitdir/gitweb/httpd.conf + full_httpd=$httpd 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 + # in addition, we may have generated a server script + # in $fqgitdir/gitweb. + for i in /usr/local/sbin /usr/sbin "$fqgitdir/gitweb" 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" + full_httpd=$i/$httpd return fi done - echo "$httpd_only not found. Install $httpd_only or use" \ - "--httpd to specify another http daemon." + + echo >&2 "$httpd_only not found. Install $httpd_only or use" \ + "--httpd to specify another httpd daemon." exit 1 fi - if test $? != 0; then - echo "Could not execute http daemon $httpd." - exit 1 +} + +start_httpd () { + if test -f "$fqgitdir/pid"; then + say "Instance already running. Restarting..." + stop_httpd fi + + # here $httpd should have a meaningful value + resolve_full_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" & + #Save the pid before doing anything else (we'll print it later) + pid=$! + + if test $? != 0; then + echo "Could not execute http daemon $httpd." + exit 1 + fi + + cat > "$fqgitdir/pid" <<EOF +$pid +EOF + ;; + *) + $full_httpd "$fqgitdir/gitweb/httpd.conf" + if test $? != 0; then + echo "Could not execute http daemon $httpd." + exit 1 + fi + ;; + esac } stop_httpd () { - test -f "$fqgitdir/pid" && kill `cat "$fqgitdir/pid"` + test -f "$fqgitdir/pid" && kill $(cat "$fqgitdir/pid") } -while case "$#" in 0) break ;; esac +while test $# != 0 do case "$1" in --stop|stop) @@ -83,52 +128,26 @@ do start_httpd exit 0 ;; - --local|-l) + -l|--local) local=true ;; - -d|--httpd|--httpd=*) - case "$#,$1" in - *,*=*) - httpd=`expr "$1" : '-[^=]*=\(.*\)'` ;; - 1,*) - usage ;; - *) - httpd="$2" - shift ;; - esac + -d|--httpd) + shift + httpd="$1" + ;; + -b|--browser) + shift + browser="$1" ;; - -b|--browser|--browser=*) - case "$#,$1" in - *,*=*) - browser=`expr "$1" : '-[^=]*=\(.*\)'` ;; - 1,*) - usage ;; - *) - browser="$2" - shift ;; - esac + -p|--port) + shift + port="$1" ;; - -p|--port|--port=*) - case "$#,$1" in - *,*=*) - port=`expr "$1" : '-[^=]*=\(.*\)'` ;; - 1,*) - usage ;; - *) - port="$2" - shift ;; - esac + -m|--module-path) + shift + module_path="$1" ;; - -m|--module-path=*|--module-path) - case "$#,$1" in - *,*=*) - module_path=`expr "$1" : '-[^=]*=\(.*\)'` ;; - 1,*) - usage ;; - *) - module_path="$2" - shift ;; - esac + --) ;; *) usage @@ -138,30 +157,130 @@ do done mkdir -p "$GIT_DIR/gitweb/tmp" -GIT_EXEC_PATH="`git --exec-path`" +GIT_EXEC_PATH="$(git --exec-path)" GIT_DIR="$fqgitdir" export GIT_EXEC_PATH GIT_DIR +webrick_conf () { + # generate a standalone server script in $fqgitdir/gitweb. + cat >"$fqgitdir/gitweb/$httpd.rb" <<EOF +require 'webrick' +require 'yaml' +options = YAML::load_file(ARGV[0]) +options[:StartCallback] = proc do + File.open(options[:PidFile],"w") do |f| + f.puts Process.pid + end +end +options[:ServerType] = WEBrick::Daemon +server = WEBrick::HTTPServer.new(options) +['INT', 'TERM'].each do |signal| + trap(signal) {server.shutdown} +end +server.start +EOF + # generate a shell script to invoke the above ruby script, + # which assumes _ruby_ is in the user's $PATH. that's _one_ + # portable way to run ruby, which could be installed anywhere, + # really. + cat >"$fqgitdir/gitweb/$httpd" <<EOF +#!/bin/sh +exec ruby "$fqgitdir/gitweb/$httpd.rb" \$* +EOF + chmod +x "$fqgitdir/gitweb/$httpd" + + cat >"$conf" <<EOF +:Port: $port +:DocumentRoot: "$fqgitdir/gitweb" +:DirectoryIndex: ["gitweb.cgi"] +:PidFile: "$fqgitdir/pid" +EOF + test "$local" = true && echo ':BindAddress: "127.0.0.1"' >> "$conf" +} + lighttpd_conf () { cat > "$conf" <<EOF server.document-root = "$fqgitdir/gitweb" server.port = $port -server.modules = ( "mod_cgi" ) +server.modules = ( "mod_setenv", "mod_cgi" ) server.indexfiles = ( "gitweb.cgi" ) server.pid-file = "$fqgitdir/pid" +server.errorlog = "$fqgitdir/gitweb/error.log" + +# to enable, add "mod_access", "mod_accesslog" to server.modules +# variable above and uncomment this +#accesslog.filename = "$fqgitdir/gitweb/access.log" + +setenv.add-environment = ( "PATH" => "/usr/local/bin:/usr/bin:/bin" ) + cgi.assign = ( ".cgi" => "" ) -mimetype.assign = ( ".css" => "text/css" ) + +# mimetype mapping +mimetype.assign = ( + ".pdf" => "application/pdf", + ".sig" => "application/pgp-signature", + ".spl" => "application/futuresplash", + ".class" => "application/octet-stream", + ".ps" => "application/postscript", + ".torrent" => "application/x-bittorrent", + ".dvi" => "application/x-dvi", + ".gz" => "application/x-gzip", + ".pac" => "application/x-ns-proxy-autoconfig", + ".swf" => "application/x-shockwave-flash", + ".tar.gz" => "application/x-tgz", + ".tgz" => "application/x-tgz", + ".tar" => "application/x-tar", + ".zip" => "application/zip", + ".mp3" => "audio/mpeg", + ".m3u" => "audio/x-mpegurl", + ".wma" => "audio/x-ms-wma", + ".wax" => "audio/x-ms-wax", + ".ogg" => "application/ogg", + ".wav" => "audio/x-wav", + ".gif" => "image/gif", + ".jpg" => "image/jpeg", + ".jpeg" => "image/jpeg", + ".png" => "image/png", + ".xbm" => "image/x-xbitmap", + ".xpm" => "image/x-xpixmap", + ".xwd" => "image/x-xwindowdump", + ".css" => "text/css", + ".html" => "text/html", + ".htm" => "text/html", + ".js" => "text/javascript", + ".asc" => "text/plain", + ".c" => "text/plain", + ".cpp" => "text/plain", + ".log" => "text/plain", + ".conf" => "text/plain", + ".text" => "text/plain", + ".txt" => "text/plain", + ".dtd" => "text/xml", + ".xml" => "text/xml", + ".mpeg" => "video/mpeg", + ".mpg" => "video/mpeg", + ".mov" => "video/quicktime", + ".qt" => "video/quicktime", + ".avi" => "video/x-msvideo", + ".asf" => "video/x-ms-asf", + ".asx" => "video/x-ms-asf", + ".wmv" => "video/x-ms-wmv", + ".bz2" => "application/x-bzip", + ".tbz" => "application/x-bzip-compressed-tar", + ".tar.bz2" => "application/x-bzip-compressed-tar", + "" => "text/plain" + ) EOF - test "$local" = true && echo 'server.bind = "127.0.0.1"' >> "$conf" + test x"$local" = xtrue && 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 + test x"$local" = xtrue && bind='127.0.0.1:' + echo 'text/css css' > "$fqgitdir/mime.types" cat > "$conf" <<EOF ServerName "git-instaweb" ServerRoot "$fqgitdir/gitweb" @@ -177,14 +296,14 @@ EOF fi done cat >> "$conf" <<EOF -TypesConfig $fqgitdir/mime.types +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 + if test -f "$module_path/mod_perl.so" && + sane_grep 'MOD_PERL' "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null then # favor mod_perl if available cat >> "$conf" <<EOF @@ -200,9 +319,24 @@ PerlPassEnv GIT_EXEC_DIR EOF else # plain-old CGI - list_mods=`echo "$httpd" | sed "s/-f$/-l/"` - $list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \ - echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf" + resolve_full_httpd + list_mods=$(echo "$full_httpd" | sed "s/-f$/-l/") + $list_mods | sane_grep 'mod_cgi\.c' >/dev/null 2>&1 || \ + if test -f "$module_path/mod_cgi.so" + then + echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf" + else + $list_mods | grep 'mod_cgid\.c' >/dev/null 2>&1 || \ + if test -f "$module_path/mod_cgid.so" + then + echo "LoadModule cgid_module $module_path/mod_cgid.so" \ + >> "$conf" + else + echo "You have no CGI support!" + exit 2 + fi + echo "ScriptSock logs/gitweb.sock" >> "$conf" + fi cat >> "$conf" <<EOF AddHandler cgi-script .cgi <Location /gitweb.cgi> @@ -212,17 +346,44 @@ EOF fi } +mongoose_conf() { + cat > "$conf" <<EOF +# Mongoose web server configuration file. +# Lines starting with '#' and empty lines are ignored. +# For detailed description of every option, visit +# http://code.google.com/p/mongoose/wiki/MongooseManual + +root $fqgitdir/gitweb +ports $port +index_files gitweb.cgi +#ssl_cert $fqgitdir/gitweb/ssl_cert.pem +error_log $fqgitdir/gitweb/error.log +access_log $fqgitdir/gitweb/access.log + +#cgi setup +cgi_env PATH=/usr/local/bin:/usr/bin:/bin,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH +cgi_interp $PERL +cgi_ext cgi,pl + +# mimetype mapping +mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-tgz,.tar=application/x-tar,.zip=application/zip,.gif=image/gif,.jpg=image/jpeg,.jpeg=image/jpeg,.png=image/png,.css=text/css,.html=text/html,.htm=text/html,.js=text/javascript,.c=text/plain,.cpp=text/plain,.log=text/plain,.conf=text/plain,.text=text/plain,.txt=text/plain,.dtd=text/xml,.bz2=application/x-bzip,.tbz=application/x-bzip-compressed-tar,.tar.bz2=application/x-bzip-compressed-tar +EOF +} + + 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'";#' +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" + # Use the configured full path to perl to match the generated + # scripts' 'hashpling' line + "$PERL" -p -e "$script" "$1.tmp" > "$1" chmod +x "$1" rm -f "$1.tmp" } @@ -233,8 +394,15 @@ gitweb_css () { EOFGITWEB } -gitweb_cgi $GIT_DIR/gitweb/gitweb.cgi -gitweb_css $GIT_DIR/gitweb/gitweb.css +gitweb_js () { + cat > "$1" <<\EOFGITWEB +@@GITWEB_JS@@ +EOFGITWEB +} + +gitweb_cgi "$GIT_DIR/gitweb/gitweb.cgi" +gitweb_css "$GIT_DIR/gitweb/gitweb.css" +gitweb_js "$GIT_DIR/gitweb/gitweb.js" case "$httpd" in *lighttpd*) @@ -243,6 +411,12 @@ case "$httpd" in *apache2*) apache2_conf ;; +webrick) + webrick_conf + ;; +*mongoose*) + mongoose_conf + ;; *) echo "Unknown httpd specified: $httpd" exit 1 @@ -250,6 +424,10 @@ case "$httpd" in esac start_httpd -test -z "$browser" && browser=echo url=http://127.0.0.1:$port -$browser $url || echo $url + +if test -n "$browser"; then + git web--browse -b "$browser" $url || echo $url +else + git web--browse -c "instaweb.browser" $url || echo $url +fi |