Improve the way we find repo paths

This patch improves the way we find the path to the repositories, both in the
recursive and in the non-recursive cases.

We now support specifying non-bare repositories directly, and also recursing
on them.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>
This commit is contained in:
Alberto Bertogli 2012-11-11 13:39:41 +00:00
parent 1c729578b2
commit ba3b2132f5
2 changed files with 43 additions and 11 deletions

42
git-arr

@ -49,14 +49,10 @@ def load_config(path):
# Do a first pass for general sanity checking and recursive expansion. # Do a first pass for general sanity checking and recursive expansion.
for s in config.sections(): for s in config.sections():
if not config.has_option(s, 'path'):
raise configparser.NoOptionError(
'%s is missing the mandatory path' % s)
if config.getboolean(s, 'recursive'): if config.getboolean(s, 'recursive'):
for path in os.listdir(config.get(s, 'path')): for path in os.listdir(config.get(s, 'path')):
fullpath = config.get(s, 'path') + '/' + path fullpath = find_git_dir(config.get(s, 'path') + '/' + path)
if not os.path.exists(fullpath + '/HEAD'): if not fullpath:
continue continue
if os.path.exists(fullpath + '/disable_gitweb'): if os.path.exists(fullpath + '/disable_gitweb'):
@ -76,7 +72,13 @@ def load_config(path):
config.remove_section(s) config.remove_section(s)
for s in config.sections(): for s in config.sections():
fullpath = config.get(s, 'path') fullpath = find_git_dir(config.get(s, 'path'))
if not fullpath:
raise ValueError(
'%s: path %s is not a valid git repository' % (
s, config.get(s, 'path')))
config.set(s, 'path', fullpath)
config.set(s, 'name', s) config.set(s, 'name', s)
desc = config.get(s, 'desc') desc = config.get(s, 'desc')
@ -102,6 +104,29 @@ def load_config(path):
repos[r.name] = r repos[r.name] = r
def find_git_dir(path):
"""Returns the path to the git directory for the given repository.
This function takes a path to a git repository, and returns the path to
its git directory. If the repo is bare, it will be the same path;
otherwise it will be path + '.git/'.
An empty string is returned if the given path is not a valid repository.
"""
def check(p):
"""A dirty check for whether this is a git dir or not."""
# Note silent stderr because we expect this to fail and don't want the
# noise; and also we strip the final \n from the output.
return git.run_git(p,
['rev-parse', '--git-dir'],
silent_stderr = True).read()[:-1]
for p in [ path, path + '/.git' ]:
if check(p):
return p
return ''
def repo_filter(unused_conf): def repo_filter(unused_conf):
"""Bottle route filter for repos.""" """Bottle route filter for repos."""
@ -367,8 +392,9 @@ def main():
try: try:
load_config(opts.config) load_config(opts.config)
except configparser.NoOptionError as e: except (configparser.NoOptionError, ValueError) as e:
print('Error parsing config:', e) print('Error parsing config:', e)
return
if not args: if not args:
parser.error('Must specify an action (serve|generate)') parser.error('Must specify an action (serve|generate)')

12
git.py

@ -41,7 +41,7 @@ class EncodeWrapper:
return s.decode(self.encoding, errors = self.errors) return s.decode(self.encoding, errors = self.errors)
def run_git(repo_path, params, stdin = None): def run_git(repo_path, params, stdin = None, silent_stderr = False):
"""Invokes git with the given parameters. """Invokes git with the given parameters.
This function invokes git with the given parameters, and returns a This function invokes git with the given parameters, and returns a
@ -49,11 +49,17 @@ def run_git(repo_path, params, stdin = None):
""" """
params = [GIT_BIN, '--git-dir=%s' % repo_path] + list(params) params = [GIT_BIN, '--git-dir=%s' % repo_path] + list(params)
stderr = None
if silent_stderr:
stderr = subprocess.PIPE
if not stdin: if not stdin:
p = subprocess.Popen(params, stdin = None, stdout = subprocess.PIPE) p = subprocess.Popen(params,
stdin = None, stdout = subprocess.PIPE, stderr = stderr)
else: else:
p = subprocess.Popen(params, p = subprocess.Popen(params,
stdin = subprocess.PIPE, stdout = subprocess.PIPE) stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = stderr)
p.stdin.write(stdin) p.stdin.write(stdin)
p.stdin.close() p.stdin.close()