ansible/roles/git/checks/files/distgit_check_hook.py
Pierre-Yves Chibon 8a180b87c0 Fix checking only a specific namespace
Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
2018-04-17 15:14:28 +02:00

123 lines
3.5 KiB
Python

#!/usr/bin/python
"""
This script goes through all the git repos in dist-git and adjust their
git hook so they are always as expected.
"""
import argparse
import os
import sys
_base_path = '/srv/git/repositories/'
_target_link = '/usr/share/git-core/post-receive-chained'
_target_link_forks = '/usr/share/git-core/post-receive-chained-forks'
namespaces = ['rpms', 'container', 'forks', 'modules', 'tests']
def parse_args():
""" Parses the command line arguments. """
parser = argparse.ArgumentParser(
description='Check the git hook situation for all repos in dist-git')
parser.add_argument(
'target', nargs='?', help='git repo to check')
parser.add_argument(
'--namespace', default=None,
help='Only check the git hooks, do not fix them')
parser.add_argument(
'--check', default=False, action="store_true",
help='Only check the git hooks, do not fix them')
return parser.parse_args()
def fix_link(hook, target_link):
""" Remove the existing hook and replace it with a symlink to the desired
one.
"""
if os.path.exists(hook):
os.unlink(hook)
os.symlink(target_link, hook)
def is_valid_hook(hook, target_link):
""" Simple utility function checking if the specified hook is valid. """
output = True
if not os.path.islink(hook):
print('%s is not a symlink' % hook)
output = False
else:
target = os.readlink(hook)
if target != target_link:
print('%s is not pointing to the expected target: %s' % (
hook, target_link))
output = False
return output
def process_namespace(namespace):
""" Process all the git repo in a specified namespace. """
target_link = _target_link
if namespace == 'forks':
target_link = _target_link_forks
print('Processing: %s' % namespace)
path = os.path.join(_base_path, namespace)
if not os.path.isdir(path):
continue
for dirpath, dirnames, filenames in os.walk(path):
# Don't go down the .git repos
if dirpath.endswith('.git'):
continue
for repo in dirnames:
repo_path = os.path.join(dirpath, repo)
if not repo_path.endswith('.git'):
continue
hook = os.path.join(repo_path, 'hooks', 'post-receive')
if not is_valid_hook(hook, target_link) and not args.check:
fix_link(hook, target_link)
def main():
""" This is the main method of the program.
It parses the command line arguments. If a specific repo was specified
it will only check and adjust that repo.
Otherwise, it will check and adjust all the repos.
"""
args = parse_args()
if args.target:
# Update on repo
print('Processing: %s' % args.target)
target_link = _target_link
if 'forks' in args.target:
target_link = _target_link_forks
path = os.path.join(_base_path, args.target)
if not path.endswith('.git'):
path += '.git'
if not os.path.isdir(path):
print('Git repo: %s not found on disk' % path)
hook = os.path.join(path, 'hooks', 'post-receive')
if not is_valid_hook(hook, target_link) and not args.check:
fix_link(hook, target_link)
elif args.namespace:
process_namespace(args.namespace)
else:
# Check all repos
for namespace in namespaces:
process_namespace(namespace)
if __name__ == '__main__':
sys.exit(main())