diff --git a/hgwebdir.cgi b/hgwebdir.cgi --- a/hgwebdir.cgi +++ b/hgwebdir.cgi @@ -8,10 +8,21 @@ cgitb.enable() # sys.path.insert(0, "/path/to/python/lib") # if not a system-wide install from mercurial import hgweb -# The config file looks like this: +# The config file looks like this. You can have paths to individual +# repos, collections of repos in a directory tree, or both. +# # [paths] # virtual/path = /real/path # virtual/path = /real/path +# +# [collections] +# /prefix/to/strip/off = /root/of/tree/full/of/repos +# +# collections example: say directory tree /foo contains repos /foo/bar, +# /foo/quux/baz. Give this config section: +# [collections] +# /foo = /foo +# Then repos will list as bar and quux/baz. # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples # or use a dictionary with entries like 'virtual/path': '/real/path' diff --git a/mercurial/hgweb.py b/mercurial/hgweb.py --- a/mercurial/hgweb.py +++ b/mercurial/hgweb.py @@ -1075,17 +1075,27 @@ def create_server(repo): class hgwebdir(object): def __init__(self, config): def cleannames(items): - return [(name.strip('/'), path) for name, path in items] + return [(name.strip(os.sep), path) for name, path in items] - if type(config) == type([]): + if isinstance(config, (list, tuple)): self.repos = cleannames(config) - elif type(config) == type({}): + elif isinstance(config, dict): self.repos = cleannames(config.items()) self.repos.sort() else: cp = ConfigParser.SafeConfigParser() cp.read(config) - self.repos = cleannames(cp.items("paths")) + self.repos = [] + if cp.has_section('paths'): + self.repos.extend(cleannames(cp.items('paths'))) + if cp.has_section('collections'): + for prefix, root in cp.items('collections'): + for path in util.walkrepos(root): + repo = os.path.normpath(path) + name = repo + if name.startswith(prefix): + name = name[len(prefix):] + self.repos.append((name.lstrip(os.sep), repo)) self.repos.sort() def run(self, req=hgrequest()): diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -690,3 +690,16 @@ def datestr(date=None, format='%c'): (time.strftime(format, time.gmtime(float(t) - tz)), -tz / 3600, ((-tz % 3600) / 60))) + +def walkrepos(path): + '''yield every hg repository under path, recursively.''' + def errhandler(err): + if err.filename == path: + raise err + + for root, dirs, files in os.walk(path, onerror=errhandler): + for d in dirs: + if d == '.hg': + yield root + dirs[:] = [] + break