diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt index a1f17df074..2c3c4d2994 100644 --- a/Documentation/git-instaweb.txt +++ b/Documentation/git-instaweb.txt @@ -29,7 +29,7 @@ OPTIONS 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 apache2, lighttpd, mongoose and webrick are supported. + Currently apache2, lighttpd, mongoose, plackup and webrick are supported. (Default: lighttpd) -m:: diff --git a/Makefile b/Makefile index a07333b7c9..0a8dff3a1a 100644 --- a/Makefile +++ b/Makefile @@ -272,6 +272,7 @@ mandir = share/man infodir = share/info gitexecdir = libexec/git-core sharedir = $(prefix)/share +gitwebdir = $(sharedir)/gitweb template_dir = share/git-core/templates htmldir = share/doc/git-doc ifeq ($(prefix),/usr) @@ -1444,6 +1445,7 @@ gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_SQ = $(subst ','\'',$(htmldir)) prefix_SQ = $(subst ','\'',$(prefix)) +gitwebdir_SQ = $(subst ','\'',$(gitwebdir)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) @@ -1580,45 +1582,38 @@ gitweb: $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) all ifdef JSMIN -GITWEB_PROGRAMS += gitweb/gitweb.min.js -GITWEB_JS = gitweb/gitweb.min.js +GITWEB_PROGRAMS += gitweb/static/gitweb.min.js +GITWEB_JS = gitweb/static/gitweb.min.js else -GITWEB_JS = gitweb/gitweb.js +GITWEB_JS = gitweb/static/gitweb.js endif ifdef CSSMIN -GITWEB_PROGRAMS += gitweb/gitweb.min.css -GITWEB_CSS = gitweb/gitweb.min.css +GITWEB_PROGRAMS += gitweb/static/gitweb.min.css +GITWEB_CSS = gitweb/static/gitweb.min.css else -GITWEB_CSS = gitweb/gitweb.css +GITWEB_CSS = gitweb/static/gitweb.css endif OTHER_PROGRAMS += gitweb/gitweb.cgi $(GITWEB_PROGRAMS) gitweb/gitweb.cgi: gitweb/gitweb.perl $(GITWEB_PROGRAMS) $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@) ifdef JSMIN -gitweb/gitweb.min.js: gitweb/gitweb.js +gitweb/static/gitweb.min.js: gitweb/static/gitweb.js $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@) endif # JSMIN ifdef CSSMIN -gitweb/gitweb.min.css: gitweb/gitweb.css +gitweb/static/gitweb.min.css: gitweb/static/gitweb.css $(QUIET_SUBDIR0)gitweb $(QUIET_SUBDIR1) $(patsubst gitweb/%,%,$@) endif # CSSMIN -git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css gitweb/gitweb.js +git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/static/gitweb.css gitweb/static/gitweb.js $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ - -e '/@@GITWEB_CGI@@/r gitweb/gitweb.cgi' \ - -e '/@@GITWEB_CGI@@/d' \ - -e '/@@GITWEB_CSS@@/r $(GITWEB_CSS)' \ - -e '/@@GITWEB_CSS@@/d' \ - -e '/@@GITWEB_JS@@/r $(GITWEB_JS)' \ - -e '/@@GITWEB_JS@@/d' \ + -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \ -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ - -e 's|@@GITWEB_CSS_NAME@@|$(GITWEB_CSS)|' \ - -e 's|@@GITWEB_JS_NAME@@|$(GITWEB_JS)|' \ $@.sh > $@+ && \ chmod +x $@+ && \ mv $@+ $@ @@ -1988,6 +1983,7 @@ install: all $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install ifndef NO_PERL $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install + $(MAKE) -C gitweb gitwebdir=$(gitwebdir_SQ) install endif ifndef NO_PYTHON $(MAKE) -C git_remote_helpers prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install diff --git a/git-instaweb.sh b/git-instaweb.sh index f6080149c2..6635fbefdf 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -24,6 +24,7 @@ restart restart the web server fqgitdir="$GIT_DIR" local="$(git config --bool --get instaweb.local)" httpd="$(git config --get instaweb.httpd)" +root="$(git config --get instaweb.gitwebdir)" port=$(git config --get instaweb.port) module_path="$(git config --get instaweb.modulepath)" @@ -34,6 +35,9 @@ conf="$GIT_DIR/gitweb/httpd.conf" # if installed, it doesn't need further configuration (module_path) test -z "$httpd" && httpd='lighttpd -f' +# Default is @@GITWEBDIR@@ +test -z "$root" && root='@@GITWEBDIR@@' + # any untaken local port will do... test -z "$port" && port=1234 @@ -46,6 +50,12 @@ resolve_full_httpd () { httpd="$httpd -f" fi ;; + *plackup*) + # server is started by running via generated gitweb.psgi in $fqgitdir/gitweb + full_httpd="$fqgitdir/gitweb/gitweb.psgi" + httpd_only="${httpd%% *}" # cut on first space + return + ;; esac httpd_only="$(echo $httpd | cut -f1 -d' ')" @@ -57,7 +67,7 @@ resolve_full_httpd () { # these days and those are not in most users $PATHs # in addition, we may have generated a server script # in $fqgitdir/gitweb. - for i in /usr/local/sbin /usr/sbin "$fqgitdir/gitweb" + for i in /usr/local/sbin /usr/sbin "$root" "$fqgitdir/gitweb" do if test -x "$i/$httpd_only" then @@ -83,8 +93,8 @@ start_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 + *mongoose*|*plackup*) + #These servers don'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=$! @@ -110,6 +120,20 @@ EOF stop_httpd () { test -f "$fqgitdir/pid" && kill $(cat "$fqgitdir/pid") + rm -f "$fqgitdir/pid" +} + +httpd_is_ready () { + "$PERL" -MIO::Socket::INET -e " +local \$| = 1; # turn on autoflush +exit if (IO::Socket::INET->new('127.0.0.1:$port')); +print 'Waiting for \'$httpd\' to start ..'; +do { + print '.'; + sleep(1); +} until (IO::Socket::INET->new('127.0.0.1:$port')); +print qq! (done)\n!; +" } while test $# != 0 @@ -159,8 +183,8 @@ done mkdir -p "$GIT_DIR/gitweb/tmp" GIT_EXEC_PATH="$(git --exec-path)" GIT_DIR="$fqgitdir" -export GIT_EXEC_PATH GIT_DIR - +GITWEB_CONFIG="$fqgitdir/gitweb/gitweb_config.perl" +export GIT_EXEC_PATH GIT_DIR GITWEB_CONFIG webrick_conf () { # generate a standalone server script in $fqgitdir/gitweb. @@ -192,7 +216,7 @@ EOF cat >"$conf" < "$conf" < env.PATH ) +setenv.add-environment = ( "PATH" => env.PATH, "GITWEB_CONFIG" => env.GITWEB_CONFIG ) cgi.assign = ( ".cgi" => "" ) @@ -277,14 +301,15 @@ EOF apache2_conf () { test -z "$module_path" && module_path=/usr/lib/apache2/modules - mkdir -p "$GIT_DIR/gitweb/logs" bind= test x"$local" = xtrue && bind='127.0.0.1:' echo 'text/css css' > "$fqgitdir/mime.types" cat > "$conf" <) has been applied if test -f "$module_path/mod_perl.so" && - sane_grep 'MOD_PERL' "$GIT_DIR/gitweb/gitweb.cgi" >/dev/null + sane_grep 'MOD_PERL' "$root/gitweb.cgi" >/dev/null then # favor mod_perl if available cat >> "$conf" < SetHandler perl-script PerlResponseHandler ModPerl::Registry @@ -353,15 +379,15 @@ mongoose_conf() { # For detailed description of every option, visit # http://code.google.com/p/mongoose/wiki/MongooseManual -root $fqgitdir/gitweb +root $root 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 +error_log $fqgitdir/gitweb/$httpd_only/error.log +access_log $fqgitdir/gitweb/$httpd_only/access.log #cgi setup -cgi_env PATH=$PATH,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH +cgi_env PATH=$PATH,GIT_DIR=$GIT_DIR,GIT_EXEC_PATH=$GIT_EXEC_PATH,GITWEB_CONFIG=$GITWEB_CONFIG cgi_interp $PERL cgi_ext cgi,pl @@ -370,41 +396,165 @@ mime_types .gz=application/x-gzip,.tar.gz=application/x-tgz,.tgz=application/x-t 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'";#;' - -gitweb_cgi () { - cat > "$1.tmp" <<\EOFGITWEB -@@GITWEB_CGI@@ -EOFGITWEB - # 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" +plackup_conf () { + # generate a standalone 'plackup' server script in $fqgitdir/gitweb + # with embedded configuration; it does not use "$conf" file + cat > "$fqgitdir/gitweb/gitweb.psgi" <add_type( + ".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" +); + +my \$app = builder { + # to be able to override \$SIG{__WARN__} to log build time warnings + use CGI::Carp; # it sets \$SIG{__WARN__} itself + + my \$logdir = "$fqgitdir/gitweb/$httpd_only"; + open my \$access_log_fh, '>>', "\$logdir/access.log" + or die "Couldn't open access log '\$logdir/access.log': \$!"; + open my \$error_log_fh, '>>', "\$logdir/error.log" + or die "Couldn't open error log '\$logdir/error.log': \$!"; + + \$access_log_fh->autoflush(1); + \$error_log_fh->autoflush(1); + + # redirect build time warnings to error.log + \$SIG{'__WARN__'} = sub { + my \$msg = shift; + # timestamp warning like in CGI::Carp::warn + my \$stamp = CGI::Carp::stamp(); + \$msg =~ s/^/\$stamp/gm; + print \$error_log_fh \$msg; + }; + + # write errors to error.log, access to access.log + enable 'AccessLog', + format => "combined", + logger => sub { print \$access_log_fh @_; }; + enable sub { + my \$app = shift; + sub { + my \$env = shift; + \$env->{'psgi.errors'} = \$error_log_fh; + \$app->(\$env); + } + }; + # gitweb currently doesn't work with $SIG{CHLD} set to 'IGNORE', + # because it uses 'close $fd or die...' on piped filehandle $fh + # (which causes the parent process to wait for child to finish). + enable_if { \$SIG{'CHLD'} eq 'IGNORE' } sub { + my \$app = shift; + sub { + my \$env = shift; + local \$SIG{'CHLD'} = 'DEFAULT'; + local \$SIG{'CLD'} = 'DEFAULT'; + \$app->(\$env); + } + }; + # serve static files, i.e. stylesheet, images, script + enable 'Static', + path => sub { m!\.(js|css|png)\$! && s!^/gitweb/!! }, + root => "$root/", + encoding => 'utf-8'; # encoding for 'text/plain' files + # convert CGI application to PSGI app + Plack::App::WrapCGI->new(script => "$root/gitweb.cgi")->to_app; +}; + +# make it runnable as standalone app, +# like it would be run via 'plackup' utility +if (__FILE__ eq \$0) { + require Plack::Runner; + + my \$runner = Plack::Runner->new(); + \$runner->parse_options(qw(--env deployment --port $port), + "$local" ? qw(--host 127.0.0.1) : ()); + \$runner->run(\$app); } +__END__ +EOF -gitweb_css () { - cat > "$1" <<\EOFGITWEB -@@GITWEB_CSS@@ - -EOFGITWEB + chmod a+x "$fqgitdir/gitweb/gitweb.psgi" + # configuration is embedded in server script file, gitweb.psgi + rm -f "$conf" } -gitweb_js () { - cat > "$1" <<\EOFGITWEB -@@GITWEB_JS@@ - -EOFGITWEB +gitweb_conf() { + cat > "$fqgitdir/gitweb/gitweb_config.perl" <$@ else -GITWEB_FILES += gitweb.js +GITWEB_FILES += static/gitweb.js endif ifdef CSSMIN -GITWEB_FILES += gitweb.min.css -GITWEB_CSS = gitweb.min.css -all:: gitweb.min.css -gitweb.min.css: gitweb.css GITWEB-BUILD-OPTIONS +GITWEB_FILES += static/gitweb.min.css +GITWEB_CSS = static/gitweb.min.css +all:: static/gitweb.min.css +static/gitweb.min.css: static/gitweb.css GITWEB-BUILD-OPTIONS $(QUIET_GEN)$(CSSMIN) <$ >$@ else -GITWEB_FILES += gitweb.css +GITWEB_FILES += static/gitweb.css endif -GITWEB_FILES += git-logo.png git-favicon.png +GITWEB_FILES += static/git-logo.png static/git-favicon.png GITWEB_REPLACE = \ -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ @@ -147,12 +148,13 @@ gitweb.cgi: gitweb.perl GITWEB-BUILD-OPTIONS install: all $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitwebdir_SQ)' $(INSTALL) -m 755 $(GITWEB_PROGRAMS) '$(DESTDIR_SQ)$(gitwebdir_SQ)' - $(INSTALL) -m 644 $(GITWEB_FILES) '$(DESTDIR_SQ)$(gitwebdir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitwebstaticdir_SQ)' + $(INSTALL) -m 644 $(GITWEB_FILES) '$(DESTDIR_SQ)$(gitwebstaticdir_SQ)' ### Cleaning rules clean: - $(RM) gitweb.cgi gitweb.min.js gitweb.min.css GITWEB-BUILD-OPTIONS + $(RM) gitweb.cgi static/gitweb.min.js static/gitweb.min.css GITWEB-BUILD-OPTIONS .PHONY: all clean install .FORCE-GIT-VERSION-FILE FORCE diff --git a/gitweb/README b/gitweb/README index 71742b335d..0e19be8d21 100644 --- a/gitweb/README +++ b/gitweb/README @@ -80,24 +80,26 @@ You can specify the following configuration variables when building GIT: Points to the location where you put gitweb.css on your web server (or to be more generic, the URI of gitweb stylesheet). Relative to the base URI of gitweb. Note that you can setup multiple stylesheets from - the gitweb config file. [Default: gitweb.css (or gitweb.min.css if the - CSSMIN variable is defined / CSS minifier is used)] + the gitweb config file. [Default: static/gitweb.css (or + static/gitweb.min.css if the CSSMIN variable is defined / CSS minifier + is used)] * GITWEB_LOGO Points to the location where you put git-logo.png on your web server (or to be more generic URI of logo, 72x27 size, displayed in top right corner of each gitweb page, and used as logo for Atom feed). Relative - to base URI of gitweb. [Default: git-logo.png] + to base URI of gitweb. [Default: static/git-logo.png] * GITWEB_FAVICON Points to the location where you put git-favicon.png on your web server (or to be more generic URI of favicon, assumed to be image/png type; web browsers that support favicons (website icons) may display them in the browser's URL bar and next to site name in bookmarks). Relative - to base URI of gitweb. [Default: git-favicon.png] + to base URI of gitweb. [Default: static/git-favicon.png] * GITWEB_JS Points to the localtion where you put gitweb.js on your web server (or to be more generic URI of JavaScript code used by gitweb). - Relative to base URI of gitweb. [Default: gitweb.js (or gitweb.min.js - if JSMIN build variable is defined / JavaScript minifier is used)] + Relative to base URI of gitweb. [Default: static/gitweb.js (or + static/gitweb.min.js if JSMIN build variable is defined / JavaScript + minifier is used)] * GITWEB_CONFIG This Perl file will be loaded using 'do' and can be used to override any of the options above as well as some other options -- see the "Runtime diff --git a/gitweb/git-favicon.png b/gitweb/static/git-favicon.png similarity index 100% rename from gitweb/git-favicon.png rename to gitweb/static/git-favicon.png diff --git a/gitweb/git-logo.png b/gitweb/static/git-logo.png similarity index 100% rename from gitweb/git-logo.png rename to gitweb/static/git-logo.png diff --git a/gitweb/gitweb.css b/gitweb/static/gitweb.css similarity index 100% rename from gitweb/gitweb.css rename to gitweb/static/gitweb.css diff --git a/gitweb/gitweb.js b/gitweb/static/gitweb.js similarity index 100% rename from gitweb/gitweb.js rename to gitweb/static/gitweb.js diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index 5a734b1b7b..b70b891b62 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -19,9 +19,9 @@ our \$site_name = '[localhost]'; our \$site_header = ''; our \$site_footer = ''; our \$home_text = 'indextext.html'; -our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/gitweb.css'); -our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/git-logo.png'; -our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/git-favicon.png'; +our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/static/gitweb.css'); +our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/static/git-logo.png'; +our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/static/git-favicon.png'; our \$projects_list = ''; our \$export_ok = ''; our \$strict_export = '';