Bug 608320 - Support automatic retrieval of multiple patches
authorRick Reitmaier <rreitmai@adobe.com>
Thu, 18 Nov 2010 13:07:51 -0800
changeset 64 8b9c6e4ff2ab
parent 63 14e99b1f1ff9
child 65 12e11daf441e
push id46
push userrreitmai@adobe.com
push date2010-11-18 21:10 +0000
bugs608320
Bug 608320 - Support automatic retrieval of multiple patches
__init__.py
bz.py
bzhandler.py
--- a/__init__.py
+++ b/__init__.py
@@ -8,28 +8,30 @@ Example:
 
 Configuration section is entirely optional but potentially useful::
 
   [qimportbz]
   bugzilla = server-address (defaults to BUGZILLA environment varable or bugzilla.mozilla.org)
   joinstr = string to join flags for commit messages (default is ' ')
   patch_format = Formatting string used to create patch names automatically. Set it to empty to use the initial filename.
   msg_format = Formatting string used to create commit messages automatically
+  auto_choose_all = If multiple patches associated with a bug choose them all without prompting (default is False)
 
 Formatting strings are the standard python format strings where a dictionary is used to supply the data.
 For users of Mercurial 1.2: any % characters must be escaped since Python's configuration parser will try to interpret them.
 
-There are 6 pieces of patch metadata available for use::
+There are 7 pieces of patch metadata available for use::
 
   "bugnum" : the bug number
   "id" : the patch id (internal bugzilla number)
   "title" : the bug title
   "desc" : the patch description
   "flags" : all the flags
   "filename" : the initial patch filename
+  "bugdesc" : the bug description
 
 The default values are::
 
   patch_format = bug-%(bugnum)s.diff
   msg_format = Bug %(bugnum)s - "%(title)s" [%(flags)s]
 """
 from mercurial import commands, cmdutil, extensions, url, error
 from hgext import mq
--- a/bz.py
+++ b/bz.py
@@ -168,16 +168,17 @@ class Patch(Attachment):
   def metadata(self):
     return {
       "bugnum" : self.bug.num,
       "id" : self.id,
       "title" : self.bug.title,
       "desc" : self.desc,
       "flags" : self.joinFlags(),
       "filename" : self.filename,
+      "bugdesc" : self.bug.desc
     }
 
   @property
   def name(self):
     if self.bug.settings.patch_format:
       # Create new patch name.
       patchname = self.bug.settings.patch_format % self.metadata
     else:
@@ -235,16 +236,17 @@ class Comment(object):
 class Bug(object):
   def __init__(self, ui, data):
     self.settings = Settings(ui)
     xml = xmlfromstring(data)
     bug = xml.find("bug")
     self.num = int(bug.find('bug_id').text)
     self.title = bug.find('short_desc').text
     self.comments = [Comment(n) for n in xml.findall("bug/long_desc")]
+    self.desc = self.comments[0].text if len(self.comments)>0 else ""
     self.attachments = [Attachment.parse(self, a) for a in xml.findall("bug/attachment")]
     if bug.get("error") == "NotPermitted":
       raise PermissionError("Not allowed to access bug.  (Perhaps it is marked with a security group?)")
 
     # Add to cache so we can avoid network lookup later in this process
     cache[self.num] = self
 
   def get_patch(self, attachid):
--- a/bzhandler.py
+++ b/bzhandler.py
@@ -25,16 +25,18 @@ class ObjectResponse(object):
 class Handler(urllib2.BaseHandler):
   def __init__(self, ui, passmgr):
     self.ui = ui
     self.passmgr = passmgr
 
     self.base = ui.config('qimportbz', 'bugzilla',
                           os.environ.get('BUGZILLA', "bugzilla.mozilla.org"))
 
+    self.autoChoose = ui.config('qimportbz', 'auto_choose_all', False)
+
   # Change the request to the https for the bug XML
   def bz_open(self, req):
     num = int(req.get_host())
     if num in bz.cache:
       bug = bz.cache[num]
       # strip the /
       attachid = req.get_selector()[1:]
       if attachid:
@@ -63,18 +65,19 @@ class Handler(urllib2.BaseHandler):
       try:
         bug = bz.Bug(self.ui, data)
       # TODO: update syntax when mercurial requires Python 2.6
       except bz.PermissionError, e:
         self.ui.warn(" %s\n" % e.msg)
         return
       self.ui.status(" done\n")
 
-    if not patch and req.get_selector():
-      patch = bug.get_patch(req.get_selector())
+    attachid = req.get_selector()[1:]
+    if not patch and attachid:
+      patch = bug.get_patch(attachid)
 
     if not patch:
       patches = [p for p in bug.patches if not p.obsolete]
       if len(patches) == 0:
         patches = bug.patches
         if len(patches) == 0:
           self.ui.warn("No patches found for this bug\n")
           return
@@ -85,17 +88,18 @@ class Handler(urllib2.BaseHandler):
           if 'y' != self.ui.prompt("Only found one patch and it is obsolete. Import anyways? [Default is 'y']", default='y'):
             return
       if len(patches) == 1:
         patch = patches[0]
       elif len(patches) > 0:
         for i, p in enumerate(patches):
           flags = p.joinFlags(False)
           self.ui.write("%s: %s%s\n" % (i + 1, p.desc, "\n%s" % flags if flags else ""))
-        choicestr = self.ui.prompt("Which patches do you want to import? [Default is '1']", default="1")
+        choicestr = ' '.join([str(n) for n in xrange(1,len(patches)+1)])
+        choicestr = choicestr if self.autoChoose else self.ui.prompt("Which patches do you want to import? [Default is '1']", default="1")
         for choice in (s.strip() for t in choicestr.split(',') for s in t.split()):
           try:
             if int(choice) <= 0:
               raise IndexError()
             p = patches[int(choice) - 1]
           except (ValueError, IndexError):
             self.ui.warn("Invalid patch number = '%s'\n" % choice)
             continue