git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCHv2 1/2 (RFC?)] gitweb: Prepare for splitting gitweb

From
Jakub Narebski <jnareb@gmail.com>
Date
May 3, 2011, 14:04 UTC
Message-ID
<1304431450-23901-2-git-send-email-jnareb@gmail.com>
In-Reply-To
<1304431450-23901-1-git-send-email-jnareb@gmail.com>

Prepare gitweb for being split into modules that would be installed in $(gitweblibdir), by default alongside gitweb in 'lib/' subdirectory.

Gitweb would search first in 'lib/' subdirectory from where gitweb.cgi is installed, via

  use lib __DIR__.'/lib';

(This allow for tests to work with source version of gitweb without changes.) Then it searches in $(gitweblibdir) directory (set during build time), by default "$(gitwebdir)/lib", via

  use lib "++GITWEBLIBDIR++";

which is set to requested dir during building of gitweb.cgi. Note that 'use lib' assures no trailing duplicate entries in @INC.

This preparatory work allows to add new module to gitweb by simply adding

  GITWEB_MODULES += <module>

to gitweb/Makefile (assuming that the module is in 'gitweb/lib/' directory).

While at it pass GITWEBLIBDIR in addition to GITWEB_TEST_INSTALLED to allow testing installed version of gitweb and installed version of modules (for future tests which would check individual (sub)modules).

At Pavan Kumar Sankara suggestion gitweb/Makefile uses
  install [OPTION]... SOURCE... DIRECTORY
format (2nd format) with single SOURCE rather than
  install [OPTION]... SOURCE DEST

format (1st format) because of security reasons (race conditions). Modern GNU install has `-T' / `--no-target-directory' option, but we cannot rely that the $(INSTALL) we are using supports this option.

The install-modules target in gitweb/Makefile uses shell 'for' loop, instead of make's $(foreach) function, to avoid possible problem with generating a command line that exceeded the maximum argument list length.

Helped-by: Pavan Kumar Sunkara <pavan.sss1991@gmail.com>
Helped-by: Alejandro R. Sedeño <asedeno@mit.edu>
Signed-off-by: Jakub Narębski <jnareb@gmail.com>
---
This patch is closest to
  [PATCH (version C) 1/2] gitweb: Prepare for splitting gitweb
  http://thread.gmane.org/gmane.comp.version-control.git/165824/focus=165826
from previous (v1) version of this series.
  Advantages:
  - can run source version of gitweb (gitweb/gitweb.perl) as a script simply
  - supports relocating gitweb modules (to gitweblibdir)
  - allow users to simply install extra modules by hand alongside gitweb
  Disadvantages:
  - most complicated code of all cases

In this version modules from __DIR__."/lib", i.e. installed alongside gitweb.cgi take preference over common modules installed in "++GITWEBLIBDIR++", as suggested / requested by Alejandro:

  http://thread.gmane.org/gmane.comp.version-control.git/165824/focus=165926  

This patch is marked as possible RFC because I am not sure if "$(gitwebdir)/lib" directory to install modules alongside gitweb.cgi should be created unconditionally; it might be empty if $(gitweblibdir) is changed from its default version.

This version also include update to gitweb/INSTALL.
Side-note: I have thought about adding sanity check for empty
"++GITWEBLIBDIR++" in the form of
  use if "++GITWEBLIBDIR++", lib => "++GITWEBLIBDIR++";
or
  use lib "++GITWEBLIBDIR++" || '.';

But because default value of "++GITWEBLIBDIR++" is never empty, I don't think it is worth complicating code protecting against unlikely user error; Perl would give the following warning:

  Empty compile time value given to use lib
 gitweb/INSTALL     |    7 +++++++
 gitweb/Makefile    |   20 ++++++++++++++++++--
 gitweb/gitweb.perl |   11 +++++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/gitweb/INSTALL b/gitweb/INSTALL
index 4964a67..7af343a 100644
--- a/gitweb/INSTALL
+++ b/gitweb/INSTALL
@@ -243,6 +243,13 @@ The following optional Perl modules are required for extra features
  - HTML::TagCloud - for fancy tag cloud in project list view
  - HTTP::Date or Time::ParseDate - to support If-Modified-Since for feeds
 
+Those modules can be installed, in order of search, alongside
+gitweb.cgi in 'lib/' subdirectory, in '$(gitweblibdir)' directory
+(given during build), or in one of directories in which Perl looks for
+library files (PERL5LIB, PERLLIB, standard places, current directory,
+etc.).  Note that the first two places are by default the same
+directory; "$(gitweblibdir)" is "$(gitwebdir)/lib".
+
 
 Example web server configuration
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/gitweb/Makefile b/gitweb/Makefile
index 0a6ac00..b353d15 100644
--- a/gitweb/Makefile
+++ b/gitweb/Makefile
@@ -13,6 +13,7 @@ all::
 prefix ?= $(HOME)
 bindir ?= $(prefix)/bin
 gitwebdir ?= /var/www/cgi-bin
+gitweblibdir ?= $(gitwebdir)/lib
 
 RM ?= rm -f
 INSTALL ?= install
@@ -57,6 +58,7 @@ PERL_PATH  ?= /usr/bin/perl
 bindir_SQ = $(subst ','\'',$(bindir))#'
 gitwebdir_SQ = $(subst ','\'',$(gitwebdir))#'
 gitwebstaticdir_SQ = $(subst ','\'',$(gitwebdir)/static)#'
+gitweblibdir_SQ = $(subst ','\'',$(gitweblibdir))#'
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))#'
 PERL_PATH_SQ  = $(subst ','\'',$(PERL_PATH))#'
 DESTDIR_SQ    = $(subst ','\'',$(DESTDIR))#'
@@ -115,6 +117,7 @@ GITWEB_FILES += static/git-logo.png static/git-favicon.png
 GITWEB_REPLACE = \
 	-e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
 	-e 's|++GIT_BINDIR++|$(bindir)|g' \
+	-e 's|++GITWEBLIBDIR++|$(gitweblibdir)|g' \
 	-e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
 	-e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \
 	-e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
@@ -153,20 +156,33 @@ test:
 
 test-installed:
 	GITWEB_TEST_INSTALLED='$(DESTDIR_SQ)$(gitwebdir_SQ)' \
+	GITWEBLIBDIR='$(DESTDIR_SQ)$(gitweblibdir_SQ)' \
 		$(MAKE) -C ../t gitweb-test
 
 ### Installation rules
 
-install: all
+install: all install-modules
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitwebdir_SQ)'
 	$(INSTALL) -m 755 $(GITWEB_PROGRAMS) '$(DESTDIR_SQ)$(gitwebdir_SQ)'
 	$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitwebstaticdir_SQ)'
 	$(INSTALL) -m 644 $(GITWEB_FILES) '$(DESTDIR_SQ)$(gitwebstaticdir_SQ)'
 
+install-modules:
+	$(INSTALL) -m 755 $(GITWEB_PROGRAMS) '$(DESTDIR_SQ)$(gitwebdir_SQ)/lib'
+	install_dirs="$(sort $(dir $(GITWEB_MODULES)))" && \
+	for dir in $$install_dirs; do \
+		test -d '$(DESTDIR_SQ)$(gitweblibdir_SQ)'/"$$dir" || \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitweblibdir_SQ)'/"$$dir"; \
+	done
+	gitweb_modules="$(GITWEB_MODULES)" && \
+	for mod in $$gitweb_modules; do \
+		$(INSTALL) -m 644 "lib/$$mod" '$(DESTDIR_SQ)$(gitweblibdir_SQ)'/"$$(dirname $$mod)"; \
+	done
+
 ### Cleaning rules
 
 clean:
 	$(RM) gitweb.cgi static/gitweb.min.js static/gitweb.min.css GITWEB-BUILD-OPTIONS
 
-.PHONY: all clean install test test-installed .FORCE-GIT-VERSION-FILE FORCE
+.PHONY: all clean install install-modules test test-installed .FORCE-GIT-VERSION-FILE FORCE
 
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index ee69ea6..f094471 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -10,6 +10,17 @@
 use 5.008;
 use strict;
 use warnings;
+
+use File::Spec;
+
+# __DIR__ is excerpt from Dir::Self
+sub __DIR__ () {
+	File::Spec->rel2abs(join '', (File::Spec->splitpath(__FILE__))[0, 1]);
+}
+use lib "++GITWEBLIBDIR++";
+use lib __DIR__ . '/lib';
+
+
 use CGI qw(:standard :escapeHTML -nosticky);
 use CGI::Util qw(unescape);
 use CGI::Carp qw(fatalsToBrowser set_message);
-- 
1.7.3
Previous: Jakub NarebskiNext: Jakub Narebski
Message 2 of 6 in “[PATCHv2 0/2] gitweb: Beginnings of splitting gitweb into modules”
  1. Jakub NarebskiMay 3, 2011
  2. 1/2 gitweb: Prepare for splitting gitwebJakub Narebski, May 3, 2011
  3. 2/2 gitweb: Create Gitweb::Util moduleJakub Narebski, May 3, 2011
  4. Sylvain RabotAug 23, 2011
  5. J.H.Aug 23, 2011
  6. Pavan Kumar SunkaraAug 24, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.