changeset 2673:109a22f5434a

hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks all repository classes now have url() method that returns url of repo.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Tue, 25 Jul 2006 13:50:32 -0700
parents 82864a2eb709
children 7a6708e73e21
files doc/hgrc.5.txt mercurial/bundlerepo.py mercurial/commands.py mercurial/hgweb/hgweb_mod.py mercurial/httprepo.py mercurial/localrepo.py mercurial/sshrepo.py mercurial/sshserver.py mercurial/statichttprepo.py tests/test-bundle tests/test-bundle.out tests/test-hook tests/test-hook.out tests/test-http tests/test-http.out tests/test-push-http tests/test-push-http.out tests/test-ssh tests/test-ssh.out tests/test-static-http tests/test-static-http.out
diffstat 21 files changed, 119 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/doc/hgrc.5.txt	Tue Jul 25 21:22:56 2006 +0200
+++ b/doc/hgrc.5.txt	Tue Jul 25 13:50:32 2006 -0700
@@ -194,7 +194,8 @@
 
   changegroup;;
     Run after a changegroup has been added via push, pull or
-    unbundle. ID of the first new changeset is in $HG_NODE.
+    unbundle. ID of the first new changeset is in $HG_NODE.  URL from
+    which changes came is in $HG_URL.
   commit;;
     Run after a changeset has been created in the local repository.
     ID of the newly created changeset is in $HG_NODE.  Parent
@@ -202,7 +203,7 @@
   incoming;;
     Run after a changeset has been pulled, pushed, or unbundled into
     the local repository.  The ID of the newly arrived changeset is in
-    $HG_NODE.
+    $HG_NODE.  URL that was source of changes came is in $HG_URL.
   outgoing;;
     Run after sending changes from local repository to another.  ID of
     first changeset sent is in $HG_NODE.  Source of operation is in
@@ -210,7 +211,8 @@
   prechangegroup;;
     Run before a changegroup is added via push, pull or unbundle.
     Exit status 0 allows the changegroup to proceed.  Non-zero status
-    will cause the push, pull or unbundle to fail.
+    will cause the push, pull or unbundle to fail.  URL from which
+    changes will come is in $HG_URL.
   precommit;;
     Run before starting a local commit.  Exit status 0 allows the
     commit to proceed.  Non-zero status will cause the commit to fail.
@@ -236,7 +238,8 @@
     before accepting them.  Passed the ID of the first new changeset
     in $HG_NODE.  Exit status 0 allows the transaction to commit.
     Non-zero status will cause the transaction to be rolled back and
-    the push, pull or unbundle will fail.
+    the push, pull or unbundle will fail.  URL that was source of
+    changes is in $HG_URL.
   pretxncommit;;
     Run after a changeset has been created but the transaction not yet
     committed.  Changeset is visible to hook program.  This lets you
--- a/mercurial/bundlerepo.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/bundlerepo.py	Tue Jul 25 13:50:32 2006 -0700
@@ -159,6 +159,10 @@
 class bundlerepository(localrepo.localrepository):
     def __init__(self, ui, path, bundlename):
         localrepo.localrepository.__init__(self, ui, path)
+
+        self._url = 'bundle:' + bundlename
+        if path: self._url += '+' + path
+
         self.tempfile = None
         self.bundlefile = open(bundlename, "rb")
         header = self.bundlefile.read(6)
@@ -208,6 +212,9 @@
             for c in changegroup.chunkiter(self.bundlefile):
                 pass
 
+    def url(self):
+        return self._url
+
     def dev(self):
         return -1
 
--- a/mercurial/commands.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/commands.py	Tue Jul 25 13:50:32 2006 -0700
@@ -2763,7 +2763,8 @@
         raise util.Abort(_("%s: unknown bundle compression type")
                          % fname)
     gen = generator(util.filechunkiter(f, 4096))
-    modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle')
+    modheads = repo.addchangegroup(util.chunkbuffer(gen), 'unbundle',
+                                   'bundle:' + fname)
     return postincoming(ui, repo, modheads, opts['update'])
 
 def undo(ui, repo):
--- a/mercurial/hgweb/hgweb_mod.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/hgweb/hgweb_mod.py	Tue Jul 25 13:50:32 2006 -0700
@@ -904,9 +904,13 @@
         # require ssl by default, auth info cannot be sniffed and
         # replayed
         ssl_req = self.repo.ui.configbool('web', 'push_ssl', True)
-        if ssl_req and not req.env.get('HTTPS'):
-            bail(_('ssl required\n'))
-            return
+        if ssl_req:
+            if not req.env.get('HTTPS'):
+                bail(_('ssl required\n'))
+                return
+            proto = 'https'
+        else:
+            proto = 'http'
 
         # do not allow push unless explicitly allowed
         if not self.check_perm(req, 'push', False):
@@ -952,7 +956,9 @@
                 sys.stdout = cStringIO.StringIO()
 
                 try:
-                    ret = self.repo.addchangegroup(fp, 'serve')
+                    url = 'remote:%s:%s' % (proto,
+                                            req.env.get('REMOTE_HOST', ''))
+                    ret = self.repo.addchangegroup(fp, 'serve', url)
                 finally:
                     val = sys.stdout.getvalue()
                     sys.stdout = old_stdout
--- a/mercurial/httprepo.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/httprepo.py	Tue Jul 25 13:50:32 2006 -0700
@@ -115,6 +115,7 @@
 
 class httprepository(remoterepository):
     def __init__(self, ui, path):
+        self.path = path
         self.caps = None
         scheme, netloc, urlpath, query, frag = urlparse.urlsplit(path)
         if query or frag:
@@ -124,8 +125,8 @@
         host, port, user, passwd = netlocsplit(netloc)
 
         # urllib cannot handle URLs with embedded user or passwd
-        self.url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
-                                        urlpath, '', ''))
+        self._url = urlparse.urlunsplit((scheme, netlocunsplit(host, port),
+                                         urlpath, '', ''))
         self.ui = ui
 
         proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
@@ -189,6 +190,9 @@
         opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
         urllib2.install_opener(opener)
 
+    def url(self):
+        return self.path
+
     # look up capabilities only when needed
 
     def get_caps(self):
@@ -213,7 +217,7 @@
         q = {"cmd": cmd}
         q.update(args)
         qs = urllib.urlencode(q)
-        cu = "%s?%s" % (self.url, qs)
+        cu = "%s?%s" % (self._url, qs)
         try:
             resp = urllib2.urlopen(urllib2.Request(cu, data, headers))
         except urllib2.HTTPError, inst:
@@ -234,13 +238,13 @@
                not proto.startswith('text/plain') and \
                not proto.startswith('application/hg-changegroup'):
             raise hg.RepoError(_("'%s' does not appear to be an hg repository") %
-                               self.url)
+                               self._url)
 
         if proto.startswith('application/mercurial'):
             version = proto[22:]
             if float(version) > 0.1:
                 raise hg.RepoError(_("'%s' uses newer protocol %s") %
-                                   (self.url, version))
+                                   (self._url, version))
 
         return resp
 
--- a/mercurial/localrepo.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/localrepo.py	Tue Jul 25 13:50:32 2006 -0700
@@ -83,6 +83,9 @@
 
         self.dirstate = dirstate.dirstate(self.opener, self.ui, self.root)
 
+    def url(self):
+        return 'file:' + self.root
+
     def hook(self, name, throw=False, **args):
         def callhook(hname, funcname):
             '''call python hook. hook is callable object, looked up as
@@ -1185,7 +1188,7 @@
             cg = remote.changegroup(fetch, 'pull')
         else:
             cg = remote.changegroupsubset(fetch, heads, 'pull')
-        return self.addchangegroup(cg, 'pull')
+        return self.addchangegroup(cg, 'pull', remote.url())
 
     def push(self, remote, force=False, revs=None):
         # there are two ways to push to remote repo:
@@ -1241,7 +1244,7 @@
         ret = self.prepush(remote, force, revs)
         if ret[0] is not None:
             cg, remote_heads = ret
-            return remote.addchangegroup(cg, 'push')
+            return remote.addchangegroup(cg, 'push', self.url())
         return ret[1]
 
     def push_unbundle(self, remote, force, revs):
@@ -1594,7 +1597,7 @@
 
         return util.chunkbuffer(gengroup())
 
-    def addchangegroup(self, source, srctype):
+    def addchangegroup(self, source, srctype, url):
         """add changegroup to repo.
         returns number of heads modified or added + 1."""
 
@@ -1608,7 +1611,7 @@
         if not source:
             return 0
 
-        self.hook('prechangegroup', throw=True, source=srctype)
+        self.hook('prechangegroup', throw=True, source=srctype, url=url)
 
         changesets = files = revisions = 0
 
@@ -1675,17 +1678,18 @@
 
         if changesets > 0:
             self.hook('pretxnchangegroup', throw=True,
-                      node=hex(self.changelog.node(cor+1)), source=srctype)
+                      node=hex(self.changelog.node(cor+1)), source=srctype,
+                      url=url)
 
         tr.close()
 
         if changesets > 0:
             self.hook("changegroup", node=hex(self.changelog.node(cor+1)),
-                      source=srctype)
+                      source=srctype, url=url)
 
             for i in range(cor + 1, cnr + 1):
                 self.hook("incoming", node=hex(self.changelog.node(i)),
-                          source=srctype)
+                          source=srctype, url=url)
 
         return newheads - oldheads + 1
 
--- a/mercurial/sshrepo.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/sshrepo.py	Tue Jul 25 13:50:32 2006 -0700
@@ -13,7 +13,7 @@
 
 class sshrepository(remoterepository):
     def __init__(self, ui, path, create=0):
-        self.url = path
+        self._url = path
         self.ui = ui
 
         m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path)
@@ -48,6 +48,9 @@
 
         self.validate_repo(ui, sshcmd, args, remotecmd)
 
+    def url(self):
+        return self._url
+
     def validate_repo(self, ui, sshcmd, args, remotecmd):
         cmd = '%s %s "%s -R %s serve --stdio"'
         cmd = cmd % (sshcmd, args, remotecmd, self.path)
@@ -180,7 +183,7 @@
             return 1
         return int(r)
 
-    def addchangegroup(self, cg, source):
+    def addchangegroup(self, cg, source, url):
         d = self.call("addchangegroup")
         if d:
             raise hg.RepoError(_("push refused: %s") % d)
--- a/mercurial/sshserver.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/sshserver.py	Tue Jul 25 13:50:32 2006 -0700
@@ -117,9 +117,13 @@
             return
 
         self.respond("")
-        r = self.repo.addchangegroup(self.fin, 'serve')
+        r = self.repo.addchangegroup(self.fin, 'serve', self.client_url())
         self.respond(str(r))
 
+    def client_url(self):
+        client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
+        return 'remote:ssh:' + client
+        
     def do_unbundle(self):
         their_heads = self.getarg()[1].split()
 
@@ -159,7 +163,7 @@
                 # push can proceed
 
                 fp.seek(0)
-                r = self.repo.addchangegroup(fp, 'serve')
+                r = self.repo.addchangegroup(fp, 'serve', self.client_url())
                 self.respond(str(r))
             finally:
                 if not was_locked:
--- a/mercurial/statichttprepo.py	Tue Jul 25 21:22:56 2006 +0200
+++ b/mercurial/statichttprepo.py	Tue Jul 25 13:50:32 2006 -0700
@@ -30,6 +30,7 @@
 
 class statichttprepository(localrepo.localrepository):
     def __init__(self, ui, path):
+        self._url = path
         self.path = (path + "/.hg")
         self.ui = ui
         self.revlogversion = 0
@@ -41,6 +42,9 @@
         self.encodepats = None
         self.decodepats = None
 
+    def url(self):
+        return 'static-' + self._url
+
     def dev(self):
         return -1
 
--- a/tests/test-bundle	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-bundle	Tue Jul 25 13:50:32 2006 -0700
@@ -38,6 +38,8 @@
 hg init empty
 cd empty
 hg -R bundle://../full.hg log
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
 #doesn't work (yet ?)
 #hg -R bundle://../full.hg verify
 hg pull bundle://../full.hg
--- a/tests/test-bundle.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-bundle.out	Tue Jul 25 13:50:32 2006 -0700
@@ -81,6 +81,7 @@
 date:        Mon Jan 12 13:46:40 1970 +0000
 summary:     0.0
 
+changegroup: u=bundle:../full.hg
 pulling from bundle://../full.hg
 requesting all changes
 adding changesets
--- a/tests/test-hook	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-hook	Tue Jul 25 13:50:32 2006 -0700
@@ -17,9 +17,9 @@
 
 # changegroup hooks can see env vars
 echo '[hooks]' > .hg/hgrc
-echo 'prechangegroup = echo prechangegroup hook' >> .hg/hgrc
-echo 'changegroup = echo changegroup hook: n=$HG_NODE' >> .hg/hgrc
-echo 'incoming = echo incoming hook: n=$HG_NODE' >> .hg/hgrc
+echo 'prechangegroup = echo prechangegroup hook: u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
+echo 'changegroup = echo changegroup hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
+echo 'incoming = echo incoming hook: n=$HG_NODE u=`echo $HG_URL | sed s,file:.*,file:,`' >> .hg/hgrc
 
 # pretxncommit and commit hooks can see both parents of merge
 cd ../a
--- a/tests/test-hook.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-hook.out	Tue Jul 25 13:50:32 2006 -0700
@@ -22,11 +22,11 @@
 3:4c52fb2e4022
 commit hook: n=4c52fb2e402287dd5dc052090682536c8406c321 p1=1324a5531bac09b329c3845d35ae6a7526874edb p2=b702efe9688826e3a91283852b328b84dbf37bc2
 commit hook b
-prechangegroup hook
-changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
-incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2
-incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb
-incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321
+prechangegroup hook: u=file:
+changegroup hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
+incoming hook: n=b702efe9688826e3a91283852b328b84dbf37bc2 u=file:
+incoming hook: n=1324a5531bac09b329c3845d35ae6a7526874edb u=file:
+incoming hook: n=4c52fb2e402287dd5dc052090682536c8406c321 u=file:
 pulling from ../a
 searching for changes
 adding changesets
--- a/tests/test-http	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-http	Tue Jul 25 13:50:32 2006 -0700
@@ -23,3 +23,13 @@
 http_proxy= hg clone http://localhost:20059/ copy-pull
 cd copy-pull
 hg verify
+
+cd test
+echo bar > bar
+hg commit -A -d '1 0' -m 2
+
+echo % pull
+cd ../copy-pull
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
+hg pull
--- a/tests/test-http.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-http.out	Tue Jul 25 13:50:32 2006 -0700
@@ -28,3 +28,9 @@
 crosschecking files in changesets and manifests
 checking files
 1 files, 1 changesets, 1 total revisions
+/home/bos/hg/hg/hg-url/tests/test-http: line 27: cd: test: No such file or directory
+adding bar
+% pull
+pulling from http://localhost:20059/
+searching for changes
+no changes found
--- a/tests/test-push-http	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-push-http	Tue Jul 25 13:50:32 2006 -0700
@@ -36,13 +36,19 @@
 
 echo % expect success
 echo 'allow_push = *' >> .hg/hgrc
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup: u=$HG_URL >> $HGTMP/urls' >> .hg/hgrc
 hg serve -p 20059 -d --pid-file=hg.pid
 cat hg.pid >> $DAEMON_PIDS
 hg --cwd ../test2 push http://localhost:20059/
 kill `cat hg.pid`
 hg rollback
 
+sed 's/\(remote:http.*\):.*/\1/' $HGTMP/urls
+
 echo % expect authorization error: all users denied
+echo '[web]' > .hg/hgrc
+echo 'push_ssl = false' >> .hg/hgrc
 echo 'deny_push = *' >> .hg/hgrc
 hg serve -p 20059 -d --pid-file=hg.pid
 cat hg.pid >> $DAEMON_PIDS
--- a/tests/test-push-http.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-push-http.out	Tue Jul 25 13:50:32 2006 -0700
@@ -20,6 +20,7 @@
 adding file changes
 added 1 changesets with 1 changes to 1 files
 rolling back last transaction
+changegroup: u=remote:http
 % expect authorization error: all users denied
 pushing to http://localhost:20059/
 searching for changes
--- a/tests/test-ssh	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-ssh	Tue Jul 25 13:50:32 2006 -0700
@@ -17,6 +17,8 @@
 	exit -1
 fi
 
+SSH_CLIENT='127.0.0.1 1 2'
+export SSH_CLIENT
 echo Got arguments 1:$1 2:$2 3:$3 4:$4 5:$5 >> dummylog
 $2
 EOF
@@ -29,6 +31,8 @@
 hg ci -A -m "init" -d "1000000 0" foo
 echo '[server]' > .hg/hgrc
 echo 'uncompressed = True' >> .hg/hgrc
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup in remote: u=$HG_URL >> ../dummylog' >> .hg/hgrc
 
 cd ..
 
@@ -46,6 +50,9 @@
 cd local
 hg verify
 
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup in local: u=$HG_URL >> ../dummylog' >> .hg/hgrc
+
 echo "# empty default pull"
 hg paths
 hg pull -e ../dummyssh
--- a/tests/test-ssh.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-ssh.out	Tue Jul 25 13:50:32 2006 -0700
@@ -83,5 +83,7 @@
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
 Got arguments 1:user@dummy 2:hg -R local serve --stdio 3: 4: 5:
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
+changegroup in remote: u=remote:ssh:127.0.0.1
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
 Got arguments 1:user@dummy 2:hg -R remote serve --stdio 3: 4: 5:
+changegroup in remote: u=remote:ssh:127.0.0.1
--- a/tests/test-static-http	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-static-http	Tue Jul 25 13:50:32 2006 -0700
@@ -37,6 +37,14 @@
 cd local
 hg verify
 cat bar
+
+cd ../remote
+echo baz > quux
+hg commit -A -mtest2 -d '100000000 0'
+
+cd ../local
+echo '[hooks]' >> .hg/hgrc
+echo 'changegroup = echo changegroup: u=$HG_URL' >> .hg/hgrc
 http_proxy= hg pull
 
 kill $!
--- a/tests/test-static-http.out	Tue Jul 25 21:22:56 2006 +0200
+++ b/tests/test-static-http.out	Tue Jul 25 13:50:32 2006 -0700
@@ -19,6 +19,12 @@
 checking files
 1 files, 1 changesets, 1 total revisions
 foo
+adding quux
+changegroup: u=static-http://localhost:20059/remote
 pulling from static-http://localhost:20059/remote
 searching for changes
-no changes found
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+(run 'hg update' to get a working copy)