view tests/test-hook @ 4369:d7ad1e42a368

util._matcher: speed up regexp matching. In 4babaa52badf, Benoit made a change that substantially slows matching when a big .hgignore file is in play, because it calls into the regexp matching engine potentially hundreds of times per file to be matched. I've partly rolled back his change, so that we only call into the matcher once per file, but preserved the ability to report a meaningful error message if there's a syntax error in the regexp.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue, 24 Apr 2007 10:53:25 -0700
parents 97962a3e73cf
children e6d105a51ec7
line wrap: on
line source

#!/bin/sh

cp "$TESTDIR"/printenv.py .

# commit hooks can see env vars
hg init a
cd a
echo "[hooks]" > .hg/hgrc
echo 'commit = unset HG_LOCAL HG_TAG; python ../printenv.py commit' >> .hg/hgrc
echo 'commit.b = unset HG_LOCAL HG_TAG; python ../printenv.py commit.b' >> .hg/hgrc
echo 'precommit = unset HG_LOCAL HG_NODE HG_TAG; python ../printenv.py precommit' >> .hg/hgrc
echo 'pretxncommit = unset HG_LOCAL HG_TAG; python ../printenv.py pretxncommit' >> .hg/hgrc
echo 'pretxncommit.tip = hg -q tip' >> .hg/hgrc
echo a > a
hg add a
hg commit -m a -d "1000000 0"

hg clone . ../b
cd ../b

# changegroup hooks can see env vars
echo '[hooks]' > .hg/hgrc
echo 'prechangegroup = python ../printenv.py prechangegroup' >> .hg/hgrc
echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
echo 'incoming = python ../printenv.py incoming' >> .hg/hgrc

# pretxncommit and commit hooks can see both parents of merge
cd ../a
echo b >> a
hg commit -m a1 -d "1 0"
hg update -C 0
echo b > b
hg add b
hg commit -m b -d '1 0'
hg merge 1
hg commit -m merge -d '2 0'

cd ../b
hg pull ../a

# tag hooks can see env vars
cd ../a
echo 'pretag = python ../printenv.py pretag' >> .hg/hgrc
echo 'tag = unset HG_PARENT1 HG_PARENT2; python ../printenv.py tag' >> .hg/hgrc
hg tag -d '3 0' a
hg tag -l la

# pretag hook can forbid tagging
echo 'pretag.forbid = python ../printenv.py pretag.forbid 1' >> .hg/hgrc
hg tag -d '4 0' fa
hg tag -l fla

# pretxncommit hook can see changeset, can roll back txn, changeset
# no more there after
echo 'pretxncommit.forbid0 = hg tip -q' >> .hg/hgrc
echo 'pretxncommit.forbid1 = python ../printenv.py pretxncommit.forbid 1' >> .hg/hgrc
echo z > z
hg add z
hg -q tip
hg commit -m 'fail' -d '4 0'
hg -q tip

# precommit hook can prevent commit
echo 'precommit.forbid = python ../printenv.py precommit.forbid 1' >> .hg/hgrc
hg commit -m 'fail' -d '4 0'
hg -q tip

# preupdate hook can prevent update
echo 'preupdate = python ../printenv.py preupdate' >> .hg/hgrc
hg update 1

# update hook
echo 'update = python ../printenv.py update' >> .hg/hgrc
hg update

# prechangegroup hook can prevent incoming changes
cd ../b
hg -q tip
echo '[hooks]' > .hg/hgrc
echo 'prechangegroup.forbid = python ../printenv.py prechangegroup.forbid 1' >> .hg/hgrc
hg pull ../a

# pretxnchangegroup hook can see incoming changes, can roll back txn,
# incoming changes no longer there after
echo '[hooks]' > .hg/hgrc
echo 'pretxnchangegroup.forbid0 = hg tip -q' >> .hg/hgrc
echo 'pretxnchangegroup.forbid1 = python ../printenv.py pretxnchangegroup.forbid 1' >> .hg/hgrc
hg pull ../a
hg -q tip

# outgoing hooks can see env vars
rm .hg/hgrc
echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing = python ../printenv.py preoutgoing' >> ../a/.hg/hgrc
echo 'outgoing = python ../printenv.py outgoing' >> ../a/.hg/hgrc
hg pull ../a
hg rollback

# preoutgoing hook can prevent outgoing changes
echo 'preoutgoing.forbid = python ../printenv.py preoutgoing.forbid 1' >> ../a/.hg/hgrc
hg pull ../a

cat > hooktests.py <<EOF
from mercurial import util

uncallable = 0

def printargs(args):
    args.pop('ui', None)
    args.pop('repo', None)
    a = list(args.items())
    a.sort()
    print 'hook args:'
    for k, v in a:
       print ' ', k, v

def passhook(**args):
    printargs(args)

def failhook(**args):
    printargs(args)
    return True

class LocalException(Exception):
    pass

def raisehook(**args):
    raise LocalException('exception from hook')

def aborthook(**args):
    raise util.Abort('raise abort from hook')

def brokenhook(**args):
    return 1 + {}

class container:
    unreachable = 1
EOF

echo '# test python hooks'
PYTHONPATH="`pwd`:$PYTHONPATH"
export PYTHONPATH

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
hg pull ../a 2>&1 | grep 'raised an exception'

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
hg pull ../a 2>&1 | grep 'raised an exception'

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
hg pull ../a

echo '[hooks]' > ../a/.hg/hgrc
echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
hg pull ../a

echo '# make sure --traceback works'
echo '[hooks]' > .hg/hgrc
echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc

echo a >> a
hg --traceback commit -A -m a 2>&1 | grep '^Traceback'

cd ..
hg init c
cd c

cat > hookext.py <<EOF
def autohook(**args):
    print "Automatically installed hook"

def reposetup(ui, repo):
    repo.ui.setconfig("hooks", "commit.auto", autohook)
EOF
echo '[extensions]' >> .hg/hgrc
echo 'hookext = hookext.py' >> .hg/hgrc

touch foo
hg add foo
hg ci -m 'add foo'
echo >> foo
hg ci --debug -m 'change foo' | sed -e 's/ at .*>/>/'

hg showconfig hooks | sed -e 's/ at .*>/>/'

exit 0