Add `gitosis-gitweb`, for writing gitweb project lists.

Takes the list of repositories to publish from the gitosis config file.
This commit is contained in:
Tommi Virtanen 2007-06-04 22:12:29 +03:00
parent 67940f4b28
commit 418c5c3cfc
5 changed files with 223 additions and 1 deletions

View file

@ -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?

View file

@ -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]

115
gitosis/gitweb.py Normal file
View file

@ -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)

View file

@ -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
''')

View file

@ -16,6 +16,7 @@ setup(
'console_scripts': [
'gitosis-ssh = gitosis.ssh:main',
'gitosis-serve = gitosis.serve:main',
'gitosis-gitweb = gitosis.gitweb:main',
],
},
)