diff --git a/dzonegit.py b/dzonegit.py index e176ee4..dd51376 100644 --- a/dzonegit.py +++ b/dzonegit.py @@ -265,39 +265,55 @@ def replace_serial(path, oldserial, newserial): path.write_text(updated) -def pre_commit(): - against = get_head() - autoupdate_serial = not get_config("hooks.noserialupdate", bool) +def do_commit_checks(against, revision=None, autoupdate_serial=False): try: - if not get_config("hooks.ignorewhitespaceerrors", bool): - check_whitespace_errors(against) - check_updated_zones(against, autoupdate_serial=autoupdate_serial) + if not get_config("dzonegit.ignorewhitespaceerrors", bool): + check_whitespace_errors(against, revision=revision) + check_updated_zones( + against, revision=revision, + autoupdate_serial=autoupdate_serial, + ) except HookException as e: print(e) raise SystemExit(1) -def update(): +def pre_commit(): + against = get_head() + autoupdate_serial = not get_config("dzonegit.noserialupdate", bool) + do_commit_checks(against, autoupdate_serial=autoupdate_serial) + + +def update(argv=sys.argv): if "GIT_DIR" not in os.environ: - raise SystemExit("Don't run this hook from command line") - if len(sys.argv) < 4: + raise SystemExit("Don't run this hook from the command line") + if len(argv) < 4: raise SystemExit( - "Usage: {} ".format(sys.argv[0]), + "Usage: {} ".format(argv[0]), ) - refname, against, revision = sys.argv[1:4] + refname, against, revision = argv[1:4] if against == "0000000000000000000000000000000000000000": against = get_head() # Empty commit if refname != "refs/heads/master": - raise SystemExit("Nothing else except master branch is accepted here") - try: - if not get_config("hooks.ignorewhitespaceerrors", bool): - check_whitespace_errors(against, revision) - check_updated_zones(against, revision) - except HookException as e: - print(e) - raise SystemExit(1) + raise SystemExit("Nothing else than master branch is accepted here") + do_commit_checks(against, revision) + + +def pre_receive(stdin=sys.stdin): + if stdin.isatty(): + raise SystemExit("Don't run this hook from the command line") + for line in stdin: + against, revision, refname = line.rstrip().split(" ") + if refname != "refs/heads/master": + raise SystemExit( + "Nothing else than master branch " + "is accepted here", + ) + if against == "0000000000000000000000000000000000000000": + against = get_head() # Empty commit + do_commit_checks(against, revision) def main(): @@ -307,6 +323,8 @@ def main(): pre_commit() elif name == "update": update() + elif name == "pre-receive": + pre_receive() else: sys.exit("No valid command found") diff --git a/setup.py b/setup.py index 3bcfd3b..8f3a0de 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ setup( "console_scripts": [ "dzonegit = dzonegit:main", "dzonegit-pre-commit = dzonegit:pre_commit", + "dzonegit-pre-receive = dzonegit:pre_receive", "dzonegit-update = dzonegit:update", ], }, diff --git a/test_dzonegit.py b/test_dzonegit.py index 593f4f6..a833c63 100644 --- a/test_dzonegit.py +++ b/test_dzonegit.py @@ -3,6 +3,8 @@ import pytest import subprocess import time import datetime +import os +from io import StringIO from pathlib import Path import dzonegit @@ -244,3 +246,24 @@ def test_get_config(): assert dzonegit.get_config("test.bool", bool) assert not dzonegit.get_config("test.bool2", bool) assert 42 == dzonegit.get_config("test.int", int) + + +def test_update(git_dir): + git_dir.chdir() + os.environ.update({"GIT_DIR": str(git_dir.join(".git"))}) + with pytest.raises(SystemExit): + dzonegit.update(["update", "refs/heads/slave", "0", "0"]) + dzonegit.update([ + "update", "refs/heads/master", + "0"*40, dzonegit.get_head(), + ]) + + +def test_pre_receive(git_dir): + git_dir.chdir() + revisions = "{} {} ".format("0"*40, dzonegit.get_head()) + stdin = StringIO(revisions + "refs/heads/slave\n") + with pytest.raises(SystemExit): + dzonegit.pre_receive(stdin) + stdin = StringIO(revisions + "refs/heads/master\n") + dzonegit.pre_receive(stdin)