tests/test-hook
changeset 11831 00fee6394daf
parent 11829 3152c978496a
parent 11823 f1c2de22b8a8
child 11832 7fa36341e7a0
equal deleted inserted replaced
11829:3152c978496a 11831:00fee6394daf
     1 #!/bin/sh
       
     2 
       
     3 cp "$TESTDIR"/printenv.py .
       
     4 
       
     5 # commit hooks can see env vars
       
     6 hg init a
       
     7 cd a
       
     8 echo "[hooks]" > .hg/hgrc
       
     9 echo 'commit = unset HG_LOCAL HG_TAG; python ../printenv.py commit' >> .hg/hgrc
       
    10 echo 'commit.b = unset HG_LOCAL HG_TAG; python ../printenv.py commit.b' >> .hg/hgrc
       
    11 echo 'precommit = unset HG_LOCAL HG_NODE HG_TAG; python ../printenv.py precommit' >> .hg/hgrc
       
    12 echo 'pretxncommit = unset HG_LOCAL HG_TAG; python ../printenv.py pretxncommit' >> .hg/hgrc
       
    13 echo 'pretxncommit.tip = hg -q tip' >> .hg/hgrc
       
    14 echo 'pre-identify = python ../printenv.py pre-identify 1' >> .hg/hgrc
       
    15 echo 'pre-cat = python ../printenv.py pre-cat' >> .hg/hgrc
       
    16 echo 'post-cat = python ../printenv.py post-cat' >> .hg/hgrc
       
    17 echo a > a
       
    18 hg add a
       
    19 hg commit -m a -d "1000000 0"
       
    20 
       
    21 hg clone . ../b
       
    22 cd ../b
       
    23 
       
    24 # changegroup hooks can see env vars
       
    25 echo '[hooks]' > .hg/hgrc
       
    26 echo 'prechangegroup = python ../printenv.py prechangegroup' >> .hg/hgrc
       
    27 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
       
    28 echo 'incoming = python ../printenv.py incoming' >> .hg/hgrc
       
    29 
       
    30 # pretxncommit and commit hooks can see both parents of merge
       
    31 cd ../a
       
    32 echo b >> a
       
    33 hg commit -m a1 -d "1 0"
       
    34 hg update -C 0
       
    35 echo b > b
       
    36 hg add b
       
    37 hg commit -m b -d '1 0'
       
    38 hg merge 1
       
    39 hg commit -m merge -d '2 0'
       
    40 
       
    41 # test generic hooks
       
    42 hg id
       
    43 hg cat b
       
    44 
       
    45 cd ../b
       
    46 hg pull ../a
       
    47 
       
    48 # tag hooks can see env vars
       
    49 cd ../a
       
    50 echo 'pretag = python ../printenv.py pretag' >> .hg/hgrc
       
    51 echo 'tag = unset HG_PARENT1 HG_PARENT2; python ../printenv.py tag' >> .hg/hgrc
       
    52 hg tag -d '3 0' a
       
    53 hg tag -l la
       
    54 
       
    55 # pretag hook can forbid tagging
       
    56 echo 'pretag.forbid = python ../printenv.py pretag.forbid 1' >> .hg/hgrc
       
    57 hg tag -d '4 0' fa
       
    58 hg tag -l fla
       
    59 
       
    60 # pretxncommit hook can see changeset, can roll back txn, changeset
       
    61 # no more there after
       
    62 echo 'pretxncommit.forbid0 = hg tip -q' >> .hg/hgrc
       
    63 echo 'pretxncommit.forbid1 = python ../printenv.py pretxncommit.forbid 1' >> .hg/hgrc
       
    64 echo z > z
       
    65 hg add z
       
    66 hg -q tip
       
    67 hg commit -m 'fail' -d '4 0'
       
    68 hg -q tip
       
    69 
       
    70 # precommit hook can prevent commit
       
    71 echo 'precommit.forbid = python ../printenv.py precommit.forbid 1' >> .hg/hgrc
       
    72 hg commit -m 'fail' -d '4 0'
       
    73 hg -q tip
       
    74 
       
    75 # preupdate hook can prevent update
       
    76 echo 'preupdate = python ../printenv.py preupdate' >> .hg/hgrc
       
    77 hg update 1
       
    78 
       
    79 # update hook
       
    80 echo 'update = python ../printenv.py update' >> .hg/hgrc
       
    81 hg update
       
    82 
       
    83 # prechangegroup hook can prevent incoming changes
       
    84 cd ../b
       
    85 hg -q tip
       
    86 echo '[hooks]' > .hg/hgrc
       
    87 echo 'prechangegroup.forbid = python ../printenv.py prechangegroup.forbid 1' >> .hg/hgrc
       
    88 hg pull ../a
       
    89 
       
    90 # pretxnchangegroup hook can see incoming changes, can roll back txn,
       
    91 # incoming changes no longer there after
       
    92 echo '[hooks]' > .hg/hgrc
       
    93 echo 'pretxnchangegroup.forbid0 = hg tip -q' >> .hg/hgrc
       
    94 echo 'pretxnchangegroup.forbid1 = python ../printenv.py pretxnchangegroup.forbid 1' >> .hg/hgrc
       
    95 hg pull ../a
       
    96 hg -q tip
       
    97 
       
    98 # outgoing hooks can see env vars
       
    99 rm .hg/hgrc
       
   100 echo '[hooks]' > ../a/.hg/hgrc
       
   101 echo 'preoutgoing = python ../printenv.py preoutgoing' >> ../a/.hg/hgrc
       
   102 echo 'outgoing = python ../printenv.py outgoing' >> ../a/.hg/hgrc
       
   103 hg pull ../a
       
   104 hg rollback
       
   105 
       
   106 # preoutgoing hook can prevent outgoing changes
       
   107 echo 'preoutgoing.forbid = python ../printenv.py preoutgoing.forbid 1' >> ../a/.hg/hgrc
       
   108 hg pull ../a
       
   109 
       
   110 # outgoing hooks work for local clones
       
   111 cd ..
       
   112 echo '[hooks]' > a/.hg/hgrc
       
   113 echo 'preoutgoing = python ../printenv.py preoutgoing' >> a/.hg/hgrc
       
   114 echo 'outgoing = python ../printenv.py outgoing' >> a/.hg/hgrc
       
   115 hg clone a c
       
   116 rm -rf c
       
   117 
       
   118 # preoutgoing hook can prevent outgoing changes for local clones
       
   119 echo 'preoutgoing.forbid = python ../printenv.py preoutgoing.forbid 1' >> a/.hg/hgrc
       
   120 hg clone a zzz
       
   121 cd b
       
   122 
       
   123 cat > hooktests.py <<EOF
       
   124 from mercurial import util
       
   125 
       
   126 uncallable = 0
       
   127 
       
   128 def printargs(args):
       
   129     args.pop('ui', None)
       
   130     args.pop('repo', None)
       
   131     a = list(args.items())
       
   132     a.sort()
       
   133     print 'hook args:'
       
   134     for k, v in a:
       
   135        print ' ', k, v
       
   136 
       
   137 def passhook(**args):
       
   138     printargs(args)
       
   139 
       
   140 def failhook(**args):
       
   141     printargs(args)
       
   142     return True
       
   143 
       
   144 class LocalException(Exception):
       
   145     pass
       
   146 
       
   147 def raisehook(**args):
       
   148     raise LocalException('exception from hook')
       
   149 
       
   150 def aborthook(**args):
       
   151     raise util.Abort('raise abort from hook')
       
   152 
       
   153 def brokenhook(**args):
       
   154     return 1 + {}
       
   155 
       
   156 class container:
       
   157     unreachable = 1
       
   158 EOF
       
   159 
       
   160 echo '# test python hooks'
       
   161 PYTHONPATH="`pwd`:$PYTHONPATH"
       
   162 export PYTHONPATH
       
   163 
       
   164 echo '[hooks]' > ../a/.hg/hgrc
       
   165 echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
       
   166 hg pull ../a 2>&1 | grep 'raised an exception'
       
   167 
       
   168 echo '[hooks]' > ../a/.hg/hgrc
       
   169 echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
       
   170 hg pull ../a 2>&1 | grep 'raised an exception'
       
   171 
       
   172 echo '[hooks]' > ../a/.hg/hgrc
       
   173 echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
       
   174 hg pull ../a
       
   175 
       
   176 echo '[hooks]' > ../a/.hg/hgrc
       
   177 echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
       
   178 hg pull ../a
       
   179 
       
   180 echo '[hooks]' > ../a/.hg/hgrc
       
   181 echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
       
   182 hg pull ../a
       
   183 
       
   184 echo '[hooks]' > ../a/.hg/hgrc
       
   185 echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
       
   186 hg pull ../a
       
   187 
       
   188 echo '[hooks]' > ../a/.hg/hgrc
       
   189 echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
       
   190 hg pull ../a
       
   191 
       
   192 echo '[hooks]' > ../a/.hg/hgrc
       
   193 echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
       
   194 hg pull ../a
       
   195 
       
   196 echo '[hooks]' > ../a/.hg/hgrc
       
   197 echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
       
   198 hg pull ../a
       
   199 
       
   200 echo '[hooks]' > ../a/.hg/hgrc
       
   201 echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
       
   202 hg pull ../a
       
   203 
       
   204 echo '# make sure --traceback works'
       
   205 echo '[hooks]' > .hg/hgrc
       
   206 echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
       
   207 
       
   208 echo aa > a
       
   209 hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
       
   210 
       
   211 cd ..
       
   212 hg init c
       
   213 cd c
       
   214 
       
   215 cat > hookext.py <<EOF
       
   216 def autohook(**args):
       
   217     print "Automatically installed hook"
       
   218 
       
   219 def reposetup(ui, repo):
       
   220     repo.ui.setconfig("hooks", "commit.auto", autohook)
       
   221 EOF
       
   222 echo '[extensions]' >> .hg/hgrc
       
   223 echo 'hookext = hookext.py' >> .hg/hgrc
       
   224 
       
   225 touch foo
       
   226 hg add foo
       
   227 hg ci -d '0 0' -m 'add foo'
       
   228 echo >> foo
       
   229 hg ci --debug -d '0 0' -m 'change foo' | sed -e 's/ at .*>/>/'
       
   230 
       
   231 hg showconfig hooks | sed -e 's/ at .*>/>/'
       
   232 
       
   233 echo '# test python hook configured with python:[file]:[hook] syntax'
       
   234 cd ..
       
   235 mkdir d
       
   236 cd d
       
   237 hg init repo
       
   238 mkdir hooks
       
   239 
       
   240 cd hooks
       
   241 cat > testhooks.py <<EOF
       
   242 def testhook(**args):
       
   243     print 'hook works'
       
   244 EOF
       
   245 echo '[hooks]' > ../repo/.hg/hgrc
       
   246 echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
       
   247 
       
   248 cd ../repo
       
   249 hg commit -d '0 0'
       
   250 
       
   251 cd ../../b
       
   252 echo '# make sure --traceback works on hook import failure'
       
   253 cat > importfail.py <<EOF
       
   254 import somebogusmodule
       
   255 # dereference something in the module to force demandimport to load it
       
   256 somebogusmodule.whatever
       
   257 EOF
       
   258 
       
   259 echo '[hooks]' > .hg/hgrc
       
   260 echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
       
   261 
       
   262 echo a >> a
       
   263 hg --traceback commit -d '0 0' -ma 2>&1 | egrep '^(exception|Traceback|ImportError)'
       
   264 
       
   265 echo '# commit and update hooks should run after command completion (issue 1827)'
       
   266 echo '[hooks]' > .hg/hgrc
       
   267 echo 'commit = hg id' >> .hg/hgrc
       
   268 echo 'update = hg id' >> .hg/hgrc
       
   269 echo bb > a
       
   270 hg ci -d '0 0' -ma
       
   271 hg up 0
       
   272 
       
   273 exit 0