bug 454077 - link to pushlog by single changeset
authorTed Mielczarek <ted.mielczarek@gmail.com>
Fri, 21 Nov 2008 14:02:21 -0500
changeset 53 959e0ddb41337bb0dee7e3b1d0d9b5bfdfdbe5d1
parent 52 1ecaabab0765c903b50cce67f5356d12a326a909
child 54 e955a1f05004d8d03be4f334a62b75af898d07c4
push id27
push usertmielczarek@mozilla.com
push dateFri, 21 Nov 2008 19:02:25 +0000
bugs454077
bug 454077 - link to pushlog by single changeset
pushlog-feed.py
runtests.py
testdata/test-repo-changeset-query.json
testdata/test-repo-multi-changeset-query.json
--- a/pushlog-feed.py
+++ b/pushlog-feed.py
@@ -49,29 +49,31 @@ class PushlogQuery:
     querystart_value = PUSHES_PER_PAGE
     # don't need a default here, since by default
     # we'll get everything newer than whatever your start
     # query is
     queryend = None
     queryend_value = None
     # Allow query-by-user
     userquery = []
+    # Allow query-by-individual-changeset
+    changesetquery = []
 
     def __init__(self, repo, dbconn, urlbase='', tipsonly=False, reponame=''):
         self.repo = repo
         self.conn = dbconn
         self.urlbase = urlbase
         self.tipsonly = tipsonly
         self.reponame = reponame
 
     def DoQuery(self):
         """Figure out what the query parameters are, and query the database
         using those parameters."""
         self.entries = []
-        if self.querystart == QueryType.COUNT and not self.userquery:
+        if self.querystart == QueryType.COUNT and not self.userquery and not self.changesetquery:
             # Get entries from self.page, using self.querystart_value as
             # the number of pushes per page.
             try:
                 res = self.conn.execute("SELECT id, user, date FROM pushlog ORDER BY date DESC LIMIT ? OFFSET ?",
                                         (self.querystart_value,
                                          (self.page - 1) * self.querystart_value))
                 for (id,user,date) in res:
                     limit = ""
@@ -113,16 +115,25 @@ class PushlogQuery:
             if self.userquery:
                 i = 0
                 subquery = []
                 for u in self.userquery:
                     subquery.append("user = :user%d" % i)
                     params['user%d' % i] = u
                     i += 1
                 where.append('(' + ' OR '.join(subquery) + ')')
+
+            if self.changesetquery:
+                i = 0
+                subquery = []
+                for c in self.changesetquery:
+                    subquery.append("id = (select c.pushid from changesets c where c.node = :node%s)" % i)
+                    params['node%d' % i] = hex(self.repo.lookup(c))
+                    i += 1
+                where.append('(' + ' OR '.join(subquery) + ')')
             
             query = basequery + ' AND '.join(where) + ' ORDER BY id DESC, rev DESC'
             #print "query: %s" % query
             #print "params: %s" % params
             try:
                 res = self.conn.execute(query, params)
                 lastid = None
                 for (id, user, date, node) in res:
@@ -130,17 +141,17 @@ class PushlogQuery:
                         continue
                     self.entries.append((id,user,date,node))
                     lastid = id
             except sqlite.OperationalError:
                 # likely just an empty db, so return an empty result
                 pass
 
     def description(self):
-        if self.querystart == QueryType.COUNT and self.userquery is None:
+        if self.querystart == QueryType.COUNT and not self.userquery and not self.changesetquery:
             return ''
         bits = []
         isotime = lambda x: datetime.utcfromtimestamp(x).isoformat(' ')
         if self.querystart == QueryType.DATE:
             bits.append('after %s' % isotime(self.querystart_value))
         elif self.querystart == QueryType.CHANGESET:
             bits.append('after changeset %s' % self.querystart_value)
         elif self.querystart == QueryType.PUSHID:
@@ -148,19 +159,22 @@ class PushlogQuery:
 
         if self.queryend == QueryType.DATE:
             bits.append('before %s' % isotime(self.queryend_value))
         elif self.queryend == QueryType.CHANGESET:
             bits.append('up to and including changeset %s' % self.queryend_value)
         elif self.queryend == QueryType.PUSHID:
             bits.append('up to and including push ID %s' % self.queryend_value)
 
-        if self.userquery is not None:
+        if self.userquery:
             bits.append('by user %s' % ' or '.join(self.userquery))
 
+        if self.changesetquery:
+            bits.append('with changeset %s' % ' and '.join(self.changesetquery))
+
         return 'Changes pushed ' + ', '.join(bits)
 
 def localdate(ts):
     """Given a timestamp, return a (timestamp, tzoffset) tuple,
     which is what Mercurial works with. Attempts to get DST
     correct as well."""
     t = time.localtime(ts)
     offset = time.timezone
@@ -243,16 +257,20 @@ def pushlogSetup(repo, req):
         query.queryend_value = req.form.get('tochange', ['default'])[0]
     elif 'endID' in req.form:
         query.queryend = QueryType.PUSHID
         query.queryend_value = req.form.get('endID', [None])[0]
 
     if 'user' in req.form:
         query.userquery = req.form.get('user', [])
 
+    #TODO: use rev here, switch page to ?page=foo ?
+    if 'changeset' in req.form:
+        query.changesetquery = req.form.get('changeset', [])
+
     query.DoQuery()
     return query
     
 def pushlogFeed(web, req):
     """WebCommand for producing the ATOM feed of the pushlog."""
     query = pushlogSetup(web.repo, req)
     isotime = lambda x: datetime.utcfromtimestamp(x).isoformat() + 'Z'
     
--- a/runtests.py
+++ b/runtests.py
@@ -213,16 +213,28 @@ class TestPushlog(unittest.TestCase):
         self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
 
     def teststartdatetochangequery(self):
         """Query with a startdate and tochange."""
         testjson = loadjsonurl("http://localhost:8000/json-pushes?startdate=2008-11-20%2010:52:25&tochange=af5fb85d9324")
         expectedjson = loadjsonfile("testdata/test-repo-startdate-tochange-query.json")
         self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
 
+    def testsinglechangesetquery(self):
+        """Query for a single changeset."""        
+        testjson = loadjsonurl("http://localhost:8000/json-pushes?changeset=91826025c77c")
+        expectedjson = loadjsonfile("testdata/test-repo-changeset-query.json")
+        self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
+
+    def testmultichangesetquery(self):
+        """Query for two changesets at once."""
+        testjson = loadjsonurl("http://localhost:8000/json-pushes?changeset=91826025c77c&changeset=a79451771352")
+        expectedjson = loadjsonfile("testdata/test-repo-multi-changeset-query.json")
+        self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
+
 class TestPushlogUserQueries(unittest.TestCase):
     hgwebprocess = None
     repodir = ''
 
     def setUp(self):
         "Untar the test repo and add the pushlog extension to it."
         # unpack the test repo
         repoarchive = os.path.join(mydir, "testdata/test-repo-users.tar.bz2")
@@ -264,16 +276,24 @@ class TestPushlogUserQueries(unittest.Te
         testjson = loadjsonurl("http://localhost:8000/json-pushes?user=luser&user=someone&user=johndoe&startID=20")
         expectedjson = loadjsonurl("http://localhost:8000/json-pushes?startID=20")
         self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
 
     def testuserstartdatequery(self):
         """Query for a user and a startdate."""
         testjson = loadjsonurl("http://localhost:8000/json-pushes?user=luser&startdate=2008-11-21%2011:36:40")
         expectedjson = loadjsonfile("testdata/test-repo-user-luser-startdate.json")
+        self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
 
     def testuserstartdateenddatequery(self):
         """Query for a user with a startdate and an enddate."""
         testjson = loadjsonurl("http://localhost:8000/json-pushes?user=luser&startdate=2008-11-21%2011:36:40&enddate=2008-11-21%2011:37:10")
         expectedjson = loadjsonfile("testdata/test-repo-user-luser-startdate-enddate.json")
+        self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
+
+    def testchangesetsanduserquery(self):
+        """Query for multiple changesets and a user, should be the same as just querying for the one changeset, as only one changeset was pushed by this user."""
+        testjson = loadjsonurl("http://localhost:8000/json-pushes?changeset=edd2698e8172&changeset=4eb202ea0252&user=luser")
+        expectedjson = loadjsonurl("http://localhost:8000/json-pushes?changeset=edd2698e8172")
+        self.assertEqual(testjson, expectedjson, "json-pushes did not yield expected json data!")
 
 if __name__ == '__main__':
     unittest.main()
new file mode 100644
--- /dev/null
+++ b/testdata/test-repo-changeset-query.json
@@ -0,0 +1,10 @@
+{
+ "16": {
+  "date": 1227196396, 
+  "changesets": [
+   "91826025c77c6a8e5711735adaa9766dd4eac7fc", 
+   "25f2a69ac7ac2919ef35c0b937b862fbb9e7e1f7"
+  ], 
+  "user": "luser"
+ }
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testdata/test-repo-multi-changeset-query.json
@@ -0,0 +1,18 @@
+{
+ "16": {
+  "date": 1227196396, 
+  "changesets": [
+   "91826025c77c6a8e5711735adaa9766dd4eac7fc", 
+   "25f2a69ac7ac2919ef35c0b937b862fbb9e7e1f7"
+  ], 
+  "user": "luser"
+ }, 
+ "19": {
+  "date": 1227196412, 
+  "changesets": [
+   "cf831767c52b75f1c57aa41d586877f9d18d61fa", 
+   "a79451771352e444711b99134174c5daa05db9cd"
+  ], 
+  "user": "luser"
+ }
+}
\ No newline at end of file