Update pushlog integration
authorGregory Szorc <gps@mozilla.com>
Thu, 25 Jul 2013 12:59:27 -0700
changeset 31 c28a3b4ed986ee887895a40e869a49078ed7edf6
parent 30 7204cbc9f33b97c753f51746f806d68984a615cb
child 32 41fba75dcfe95dc299322e97705a0ab885df6b98
push id15
push usergszorc@mozilla.com
push dateThu, 25 Jul 2013 19:59:29 +0000
Update pushlog integration
__init__.py
mozautomation/repository.py
--- a/__init__.py
+++ b/__init__.py
@@ -80,16 +80,29 @@ style checking is performed.
 To perform style checking for a single patch, run `hg critic`. By default,
 this will analyze the current working directory. If the working directory is
 clean, the tip changeset will be analyzed. By default, only changed lines are
 reported on.
 
 Static analysis is also performed automatically during qrefresh and commit
 operations. To disable this behavior, add "noautocritic = True" to the
 [mozext] section in your hgrc.
+
+Pushlog Data
+============
+
+This extension supports downloading pushlog data from Mozilla's repositories.
+Pushlog data records who pushed changesets where and when.
+
+To use this functionality, you'll need to sync pushlog data from the server to
+the local machine. This facilitates rapid data lookup and can be done by
+running `hg pushlogsync`.
+
+Once pushlog data is synced, you can use `hg changesetpushes` to look up push
+information for a specific changeset.
 """
 
 import datetime
 import errno
 import os
 import shutil
 import sys
 
@@ -123,16 +136,17 @@ from mozautomation.changetracker import 
 
 from mozautomation.repository import (
     MercurialRepository,
     RELEASE_TREES,
     REPOS,
     resolve_trees_to_official,
     resolve_trees_to_uris,
     resolve_uri_to_tree,
+    tbpl_url,
 )
 
 import bzauth
 import bz
 
 bz_available = False
 
 testedwith = '2.6.1 2.6.2 2.6.3'
@@ -338,21 +352,18 @@ def tbpl(ui, repo, tree=None, rev=None, 
     r = MercurialRepository(repo_url)
     node = repo[rev].hex()
     push = r.push_info_for_changeset(node)
 
     if not push:
         raise util.Abort("Could not find push info for changeset %s" % node)
 
     push_node = push.last_node
-    tree_official = resolve_trees_to_official([tree])[0]
-    tree_official = '-'.join(s.title() for s in tree_official.split('-'))
 
-    url = 'https://tbpl.mozilla.org/?tree=%s&rev=%s' % (tree_official,
-        push_node[0:12])
+    url = tbpl_url(tree, push_node[0:12])
 
     import webbrowser
     webbrowser.get('firefox').open(url)
 
 
 @command('critic',
     [('e', 'entire', False,
         _('Report on entire file content, not just changed parts'),
@@ -399,23 +410,26 @@ def changesetpushes(ui, repo, rev, all=F
     """
     ctx = repo[rev]
     node = ctx.hex()
 
     tracker = ChangeTracker(repo.join('changetracker.db'))
     pushes = [p for p in tracker.pushes_for_changeset(node) if all or p[0] in
         RELEASE_TREES]
     longest_tree = max(len(p[0]) for p in pushes) + 2
+    longest_user = max(len(p[3]) for p in pushes) + 2
 
     ui.write(ctx.rev(), ':', str(ctx), ' ', ctx.description(), '\n')
 
     ui.write('Tree'.ljust(longest_tree), 'Date'.ljust(19), ' Username\n')
     for tree, push_id, when, user, head_changeset in pushes:
+        tbpl = tbpl_url(tree, head_changeset[0:12])
         date = datetime.datetime.fromtimestamp(when)
-        ui.write(tree.ljust(longest_tree), date.isoformat(), ' ', user, '\n')
+        ui.write(tree.ljust(longest_tree), date.isoformat(), ' ',
+            user.ljust(longest_user), tbpl or '', '\n')
 
 
 def critic_hook(ui, repo, node=None, **opts):
     critique(ui, repo, node=node, **opts)
     return 0
 
 
 class remoterefs(dict):
--- a/mozautomation/repository.py
+++ b/mozautomation/repository.py
@@ -134,16 +134,40 @@ def resolve_uri_to_tree(uri):
             return tree
 
         if uri.startswith('%s%s' % (BASE_WRITE_URI, path)):
             return tree
 
     return None
 
 
+def tbpl_tree_name(tree):
+    """Obtain the TBPL tree name of a tree.
+
+    Returns None if the tree isn't known.
+    """
+
+    tree = resolve_trees_to_official([tree])[0]
+
+    if not tree:
+        return None
+
+    return '-'.join(s.title() for s in tree.split('-'))
+
+
+def tbpl_url(tree, rev):
+    """Obtain the TBPL url for a push."""
+    tree = tbpl_tree_name(tree)
+
+    if not tree:
+        return None
+
+    return 'https://tbpl.mozilla.org/?tree=%s&rev=%s' % (tree, rev)
+
+
 class PushInfo(object):
     """Represents an entry from the repository pushlog."""
 
     def __init__(self, push_id, d):
         self.push_id = push_id
         self.date = d['date']
         self.changesets = []