| |
@@ -8,11 +8,24 @@
|
| |
import argparse
|
| |
import os
|
| |
import sys
|
| |
+ from pathlib import Path
|
| |
|
| |
+ import pagure
|
| |
|
| |
- _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'
|
| |
+
|
| |
+ pagure_hookrunner = Path(pagure.__file__).parent / "hooks" / "files" / "hookrunner"
|
| |
+
|
| |
+ _base_path = Path('/srv/git/repositories/')
|
| |
+
|
| |
+ # hook name: link target (project), link target (fork, if different)
|
| |
+ hook_defs = {
|
| |
+ "post-receive": (
|
| |
+ "/usr/share/git-core/post-receive-chained",
|
| |
+ "/usr/share/git-core/post-receive-chained-forks",
|
| |
+ ),
|
| |
+ "pre-receive": (pagure_hookrunner,),
|
| |
+ "update": (pagure_hookrunner,),
|
| |
+ }
|
| |
|
| |
namespaces = ['rpms', 'container', 'forks', 'modules', 'tests']
|
| |
|
| |
@@ -25,7 +38,7 @@
|
| |
'target', nargs='?', help='git repo to check')
|
| |
parser.add_argument(
|
| |
'--namespace', default=None,
|
| |
- help='Only check the git hooks, do not fix them')
|
| |
+ help="Only operate on a certain namespace, not all of them.")
|
| |
parser.add_argument(
|
| |
'--check', default=False, action="store_true",
|
| |
help='Only check the git hooks, do not fix them')
|
| |
@@ -33,23 +46,23 @@
|
| |
return parser.parse_args()
|
| |
|
| |
|
| |
- def fix_link(hook, target_link):
|
| |
+ def fix_link(hook: Path, target_link: Path):
|
| |
""" 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)
|
| |
+ if hook.exists():
|
| |
+ hook.unlink()
|
| |
+ hook.symlink_to(target_link)
|
| |
|
| |
|
| |
- def is_valid_hook(hook, target_link):
|
| |
+ def is_valid_hook(hook: Path, target_link: Path) -> bool:
|
| |
""" Simple utility function checking if the specified hook is valid. """
|
| |
output = True
|
| |
- if not os.path.islink(hook):
|
| |
+ if not hook.is_symlink():
|
| |
print('%s is not a symlink' % hook)
|
| |
output = False
|
| |
else:
|
| |
- target = os.readlink(hook)
|
| |
+ target = Path(os.readlink(hook))
|
| |
if target != target_link:
|
| |
print('%s is not pointing to the expected target: %s' % (
|
| |
hook, target_link))
|
| |
@@ -57,40 +70,48 @@
|
| |
return output
|
| |
|
| |
|
| |
+ def test_and_fix_repo_hooks(repo_path, is_fork=False, check=False):
|
| |
+ hook_base = Path(repo_path) / "hooks"
|
| |
+
|
| |
+ for hook, hook_def in hook_defs.items():
|
| |
+ if is_fork:
|
| |
+ link_target = Path(hook_def[-1])
|
| |
+ else:
|
| |
+ link_target = Path(hook_def[0])
|
| |
+
|
| |
+ hook_path = hook_base / hook
|
| |
+
|
| |
+ if not is_valid_hook(hook_path, link_target) and not check:
|
| |
+ fix_link(hook_path, link_target)
|
| |
+
|
| |
+
|
| |
def process_namespace(namespace, check, walk=False):
|
| |
""" Process all the git repo in a specified namespace. """
|
| |
- target_link = _target_link
|
| |
- if namespace == 'forks':
|
| |
- target_link = _target_link_forks
|
| |
+ is_fork = namespace == "forks"
|
| |
|
| |
print('Processing: %s' % namespace)
|
| |
- path = os.path.join(_base_path, namespace)
|
| |
- if not os.path.isdir(path):
|
| |
+ path = _base_path / namespace
|
| |
+ if not path.is_dir():
|
| |
return
|
| |
|
| |
if walk:
|
| |
for dirpath, dirnames, filenames in os.walk(path):
|
| |
# Don't go down the .git repos
|
| |
- if '.git' in dirpath:
|
| |
+ if dirpath.endswith(".git"):
|
| |
continue
|
| |
|
| |
for repo in dirnames:
|
| |
- repo_path = os.path.join(dirpath, repo)
|
| |
- if not repo_path.endswith('.git'):
|
| |
+ repo_path = Path(dirpath, repo)
|
| |
+ if repo_path.suffix != '.git':
|
| |
continue
|
| |
|
| |
- hook = os.path.join(repo_path, 'hooks', 'post-receive')
|
| |
- if not is_valid_hook(hook, target_link) and not check:
|
| |
- fix_link(hook, target_link)
|
| |
+ test_and_fix_repo_hooks(repo_path, is_fork=is_fork, check=check)
|
| |
else:
|
| |
- for repo in os.listdir(path):
|
| |
- repo_path = os.path.join(path, repo)
|
| |
- if not repo_path.endswith('.git'):
|
| |
+ for repo_path in path.iterdir():
|
| |
+ if repo_path.suffix != '.git':
|
| |
continue
|
| |
|
| |
- hook = os.path.join(repo_path, 'hooks', 'post-receive')
|
| |
- if not is_valid_hook(hook, target_link) and not check:
|
| |
- fix_link(hook, target_link)
|
| |
+ test_and_fix_repo_hooks(repo_path, is_fork=is_fork, check=check)
|
| |
|
| |
|
| |
def main():
|
| |
@@ -102,23 +123,23 @@
|
| |
|
| |
args = parse_args()
|
| |
if args.target:
|
| |
+ path = Path(args.target)
|
| |
# Update on repo
|
| |
- print('Processing: %s' % args.target)
|
| |
+ print('Processing: %s' % path)
|
| |
+
|
| |
+ is_fork = "forks" in path.parts
|
| |
|
| |
- target_link = _target_link
|
| |
- if 'forks' in args.target:
|
| |
- target_link = _target_link_forks
|
| |
+ # Don't prefix absolute paths with _base_path
|
| |
+ if not path.is_absolute():
|
| |
+ path = _base_path / path
|
| |
|
| |
- path = os.path.join(_base_path, args.target)
|
| |
- if not path.endswith('.git'):
|
| |
- path += '.git'
|
| |
+ if path.suffix != ".git":
|
| |
+ path = path.with_name(path.name + ".git")
|
| |
|
| |
- if not os.path.isdir(path):
|
| |
+ if not path.is_dir():
|
| |
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)
|
| |
+ test_and_fix_repo_hooks(path, is_fork=is_fork, check=args.check)
|
| |
|
| |
elif args.namespace:
|
| |
walk = False
|
| |