aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommi Virtanen <tv@eagain.net>2007-06-04 22:12:29 +0300
committerTommi Virtanen <tv@eagain.net>2007-06-05 13:39:24 +0300
commit418c5c3cfc5812f2ea1dfc5219c43ab549878062 (patch)
tree20c88efbf28f150eca318da3ae421ecc859c8fe2
parentRemove completed todo entries. (diff)
downloadgitosis-gentoo-418c5c3cfc5812f2ea1dfc5219c43ab549878062.tar.gz
gitosis-gentoo-418c5c3cfc5812f2ea1dfc5219c43ab549878062.tar.bz2
gitosis-gentoo-418c5c3cfc5812f2ea1dfc5219c43ab549878062.zip
Add ``gitosis-gitweb``, for writing gitweb project lists.
Takes the list of repositories to publish from the gitosis config file.
-rw-r--r--TODO.rst5
-rw-r--r--example.conf6
-rw-r--r--gitosis/gitweb.py115
-rw-r--r--gitosis/test/test_gitweb.py97
-rwxr-xr-xsetup.py1
5 files changed, 223 insertions, 1 deletions
diff --git a/TODO.rst b/TODO.rst
index 3930931..b80fa14 100644
--- a/TODO.rst
+++ b/TODO.rst
@@ -3,3 +3,8 @@
===========
- guard against *.pub files named -foo.pub or foo;bar.pub
+
+- gitweb doesn't understand mappings, just visible/no,
+ physical and logical path are always the same
+
+ - maybe remove the whole mapping feature for good?
diff --git a/example.conf b/example.conf
index 935dccc..b6654ef 100644
--- a/example.conf
+++ b/example.conf
@@ -1,5 +1,7 @@
[gitosis]
repositories = repo
+gitweb = no
+# daemon-ok = no
[group quux]
members = jdoe wsmith @anothergroup
@@ -8,8 +10,10 @@ readonly = xyzzy
map writable visiblename1 = actualname1
map readonly visiblename2 = actualname2
-# [repo foo]
+[repo foo]
# description = blah blah
+gitweb = yes
+owner = John Doe
# daemon-ok = no
# [gitweb]
diff --git a/gitosis/gitweb.py b/gitosis/gitweb.py
new file mode 100644
index 0000000..2ae682e
--- /dev/null
+++ b/gitosis/gitweb.py
@@ -0,0 +1,115 @@
+"""
+Generate ``gitweb`` project list based on ``gitosis.conf``.
+
+To plug this into ``gitweb``, you have two choices.
+
+- The global way, edit ``/etc/gitweb.conf`` to say::
+
+ $projects_list = "/path/to/your/projects.list";
+
+ Note that there can be only one such use of gitweb.
+
+- The local way, create a new config file::
+
+ do "/etc/gitweb.conf" if -e "/etc/gitweb.conf";
+ $projects_list = "/path/to/your/projects.list";
+ # see ``repositories`` in the ``gitosis`` section
+ # of ``~/.gitosis.conf``; usually ``~/repos``
+ # but you need to expand the tilde here
+ $projectroot = "/path/to/your/repos";
+
+ Then in your web server, set environment variable ``GITWEB_CONFIG``
+ to point to this file.
+
+ This way allows you have multiple separate uses of ``gitweb``, and
+ isolates the changes a bit more nicely. Recommended.
+"""
+
+import os, urllib
+
+from ConfigParser import RawConfigParser, NoSectionError, NoOptionError
+
+def _escape_filename(s):
+ s = s.replace('\\', '\\\\')
+ s = s.replace('$', '\\$')
+ s = s.replace('"', '\\"')
+ return s
+
+def generate(config, fp):
+ """
+ Generate a config file and projects list for ``gitweb``.
+
+ :param config: configuration to read projects from
+ :type config: RawConfigParser
+
+ :param fp: writable for ``projects.list``
+ :type fp: (file-like, anything with ``.write(data)``)
+ """
+ try:
+ global_enable = config.getboolean('gitosis', 'gitweb')
+ except (NoSectionError, NoOptionError):
+ global_enable = False
+
+ for section in config.sections():
+ l = section.split(None, 1)
+ type_ = l.pop(0)
+ if type_ != 'repo':
+ continue
+ if not l:
+ continue
+
+ try:
+ enable = config.getboolean(section, 'gitweb')
+ except (NoSectionError, NoOptionError):
+ enable = global_enable
+
+ if not enable:
+ continue
+
+ name, = l
+ response = [name]
+ try:
+ owner = config.get(section, 'owner')
+ except (NoSectionError, NoOptionError):
+ pass
+ else:
+ response.append(owner)
+
+ line = ' '.join([urllib.quote_plus(s) for s in response])
+ print >>fp, line
+
+def _getParser():
+ import optparse
+ parser = optparse.OptionParser(
+ usage="%prog [--config=FILE] PROJECTSLIST")
+ parser.set_defaults(
+ config=os.path.expanduser('~/.gitosis.conf'),
+ )
+ parser.add_option('--config',
+ metavar='FILE',
+ help='read config from FILE (default %s)'
+ % parser.defaults['config'],
+ )
+ return parser
+
+def main():
+ parser = _getParser()
+ (options, args) = parser.parse_args()
+
+ if len(args) != 1:
+ parser.error('Expected one command line argument.')
+
+ path, = args
+
+ cfg = RawConfigParser()
+ cfg.read(options.config)
+
+ tmp = '%s.%d.tmp' % (path, os.getpid())
+
+ f = file(tmp, 'w')
+ try:
+ generate(config=cfg, fp=f)
+ finally:
+ f.close()
+
+ os.rename(tmp, path)
diff --git a/gitosis/test/test_gitweb.py b/gitosis/test/test_gitweb.py
new file mode 100644
index 0000000..4308371
--- /dev/null
+++ b/gitosis/test/test_gitweb.py
@@ -0,0 +1,97 @@
+from nose.tools import eq_ as eq
+
+from ConfigParser import RawConfigParser
+from cStringIO import StringIO
+
+from gitosis import gitweb
+
+def test_empty():
+ cfg = RawConfigParser()
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+''')
+
+def test_trickyFilenames():
+ cfg = RawConfigParser()
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+''')
+
+def test_projectsList_repoDenied():
+ cfg = RawConfigParser()
+ cfg.add_section('repo foo/bar')
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+''')
+
+def test_projectsList_noOwner():
+ cfg = RawConfigParser()
+ cfg.add_section('repo foo/bar')
+ cfg.set('repo foo/bar', 'gitweb', 'yes')
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+foo%2Fbar
+''')
+
+def test_projectsList_haveOwner():
+ cfg = RawConfigParser()
+ cfg.add_section('repo foo/bar')
+ cfg.set('repo foo/bar', 'gitweb', 'yes')
+ cfg.set('repo foo/bar', 'owner', 'John Doe')
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+foo%2Fbar John+Doe
+''')
+
+def test_projectsList_multiple():
+ cfg = RawConfigParser()
+ cfg.add_section('gitosis')
+ cfg.add_section('repo foo/bar')
+ cfg.set('repo foo/bar', 'owner', 'John Doe')
+ cfg.set('repo foo/bar', 'gitweb', 'yes')
+ cfg.add_section('repo quux')
+ cfg.set('repo quux', 'gitweb', 'yes')
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+quux
+foo%2Fbar John+Doe
+''')
+
+def test_projectsList_multiple_globalGitwebYes():
+ cfg = RawConfigParser()
+ cfg.add_section('gitosis')
+ cfg.set('gitosis', 'gitweb', 'yes')
+ cfg.add_section('repo foo/bar')
+ cfg.set('repo foo/bar', 'owner', 'John Doe')
+ cfg.add_section('repo quux')
+ # same as default, no effect
+ cfg.set('repo quux', 'gitweb', 'yes')
+ cfg.add_section('repo thud')
+ # this is still hidden
+ cfg.set('repo thud', 'gitweb', 'no')
+ got = StringIO()
+ gitweb.generate(
+ config=cfg,
+ fp=got)
+ eq(got.getvalue(), '''\
+quux
+foo%2Fbar John+Doe
+''')
diff --git a/setup.py b/setup.py
index 35def49..8a82e47 100755
--- a/setup.py
+++ b/setup.py
@@ -16,6 +16,7 @@ setup(
'console_scripts': [
'gitosis-ssh = gitosis.ssh:main',
'gitosis-serve = gitosis.serve:main',
+ 'gitosis-gitweb = gitosis.gitweb:main',
],
},
)