blob: 1df7011194d8bab0d7cfa4f5d4abb0441fc8408c [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Creates a Git hook that calls a script with certain arguments."""
import argparse
import logging
import os
from pathlib import Path
import shlex
import subprocess
from typing import Sequence, Union
_LOG: logging.Logger = logging.getLogger(__name__)
def git_repo_root(path: Union[Path, str]) -> Path:
return Path(
subprocess.run(['git', '-C', path, 'rev-parse', '--show-toplevel'],
check=True,
stdout=subprocess.PIPE).stdout.strip().decode())
def install_hook(script,
hook: str,
args: Sequence[str] = (),
repository: Union[Path, str] = '.') -> None:
"""Installs a simple Git hook that calls a script with arguments."""
root = git_repo_root(repository).resolve()
script = os.path.relpath(script, root)
hook_path = root.joinpath('.git', 'hooks', hook)
command = ' '.join(shlex.quote(arg) for arg in (script, *args))
with hook_path.open('w') as file:
line = lambda *args: print(*args, file=file)
line('#!/bin/sh')
line(f'# {hook} hook generated by {__file__}')
line()
line(command)
hook_path.chmod(0o755)
logging.info('Created %s hook for %s at %s', hook, script, hook_path)
def argument_parser(parser=None) -> argparse.ArgumentParser:
if parser is None:
parser = argparse.ArgumentParser(description=__doc__)
def path(arg: str) -> Path:
if not os.path.exists(arg):
raise argparse.ArgumentTypeError(f'"{arg}" is not a valid path')
return Path(arg)
parser.add_argument(
'-r',
'--repository',
default='.',
type=path,
help='Path to the repository in which to install the hook')
parser.add_argument('--hook',
required=True,
help='Which type of Git hook to create')
parser.add_argument('-s',
'--script',
required=True,
type=path,
help='Path to the script to execute in the hook')
parser.add_argument('args',
nargs='*',
help='Arguments to provide to the commit hook')
return parser
if __name__ == '__main__':
logging.basicConfig(format='%(message)s', level=logging.INFO)
install_hook(**vars(argument_parser().parse_args()))