Transitioned merge to Command-format
authorW. Trevor King <wking@drexel.edu>
Tue, 15 Dec 2009 01:13:30 +0000 (20:13 -0500)
committerW. Trevor King <wking@drexel.edu>
Tue, 15 Dec 2009 01:13:30 +0000 (20:13 -0500)
libbe/bug.py
libbe/bugdir.py
libbe/command/comment.py
libbe/command/list.py
libbe/command/merge.py
libbe/comment.py

index 6c5f9581d7d4afb9e7b23d1743dbb4f676551b97..da9a1a2dc634266e42bab195647363b7604685f7 100644 (file)
@@ -296,8 +296,7 @@ class Bug(settings_object.SavedSettingsObject):
             bugout = "%s:%s: %s" % (self.id.user(),chars,self.summary.rstrip('\n'))
         
         if show_comments == True:
-            # take advantage of the string_thread(auto_name_map=True)
-            # SIDE-EFFECT of sorting by comment time.
+            self.comment_root.sort(cmp=libbe.comment.cmp_time, reverse=True)
             comout = self.comment_root.string_thread(flatten=False)
             output = bugout + '\n' + comout.rstrip('\n')
         else :
index 7ec84569611d89dbbbb0931e78d4d8cc59cdf132..aa4d9907559b7e657e7fa70234207206e169af11 100644 (file)
@@ -359,7 +359,7 @@ if libbe.TESTING == True:
                 storage = libbe.storage.base.Storage(dir.path)
                 storage.init()
                 storage.connect()
-            BugDir.__init__(self, storage=storage, uuid='simple')
+            BugDir.__init__(self, storage=storage, uuid='abc123')
             bug_a = self.new_bug(summary='Bug A', _uuid='a')
             bug_a.creator = 'John Doe <jdoe@example.com>'
             bug_a.time = 0
index 3ec40625b6fca19a6b263a1c8941fa5c7432910e..23def57be5e6e1bd7d15d68ba243fbd9d3c4f794 100644 (file)
@@ -37,8 +37,8 @@ class Comment (libbe.command.Command):
     >>> cmd._setup_io = lambda i_enc,o_enc : None
     >>> cmd.stdout = sys.stdout
 
-    >>> cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'},
-    ...         ['/a', 'This is a comment about a'])
+    >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'},
+    ...               ['/a', 'This is a comment about a'])
     >>> bd.flush_reload()
     >>> bug = bd.bug_from_uuid('a')
     >>> bug.load_comments(load_full=False)
@@ -57,12 +57,12 @@ class Comment (libbe.command.Command):
 
     >>> if 'EDITOR' in os.environ:
     ...     del os.environ['EDITOR']
-    >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
+    >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
     Traceback (most recent call last):
     UserError: No comment supplied, and EDITOR not specified.
 
     >>> os.environ['EDITOR'] = "echo 'I like cheese' > "
-    >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
+    >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b'])
     >>> bd.flush_reload()
     >>> bug = bd.bug_from_uuid('b')
     >>> bug.load_comments(load_full=False)
@@ -139,6 +139,7 @@ class Comment (libbe.command.Command):
         for key in ['alt-id', 'author', 'content-type']:
             if params[key] != None:
                 setattr(new, key, params[key])
+        return 0
 
     def _long_help(self):
         return """
index 23dbdc00e68ec11d1d9a8032853821f58746390d..7c3f5afd42fedb4e654fa4312ebe3fcc62d24ca8 100644 (file)
@@ -63,9 +63,9 @@ class List (libbe.command.Command):
     >>> cmd._setup_io = lambda i_enc,o_enc : None
     >>> cmd.stdout = sys.stdout
     >>> ret = cmd.run(bd.storage, bd)
-    sim/a:om: Bug A
+    abc/a:om: Bug A
     >>> ret = cmd.run(bd.storage, bd, {'status':'closed'})
-    sim/b:cm: Bug B
+    abc/b:cm: Bug B
     >>> bd.storage.writeable
     True
     >>> bd.cleanup()
index ac09b407932315172e2d0d4205bc13f42323ff00..4624ab78f5fdadca6d9b811e06d7d449d7eda7a7 100644 (file)
 # You should have received a copy of the GNU General Public License along
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-"""Merge duplicate bugs"""
-from libbe import cmdutil, bugdir
-import os, copy
-__desc__ = __doc__
 
-def execute(args, manipulate_encodings=True, restrict_file_access=False,
-            dir="."):
-    """
-    >>> from libbe import utility
-    >>> bd = bugdir.SimpleBugDir()
-    >>> bd.set_sync_with_disk(True)
-    >>> a = bd.bug_from_shortname("a")
+import copy
+import os
+
+import libbe
+import libbe.command
+import libbe.command.util
+
+
+class Merge (libbe.command.Command):
+    """Merge duplicate bugs
+
+    >>> import sys
+    >>> import libbe.bugdir
+    >>> import libbe.comment
+    >>> bd = libbe.bugdir.SimpleBugDir(memory=False)
+    >>> cmd = Merge()
+    >>> cmd._setup_io = lambda i_enc,o_enc : None
+    >>> cmd.stdout = sys.stdout
+
+    >>> a = bd.bug_from_uuid('a')
     >>> a.comment_root.time = 0
-    >>> dummy = a.new_comment("Testing")
+    >>> dummy = a.new_comment('Testing')
     >>> dummy.time = 1
-    >>> dummy = dummy.new_reply("Testing...")
+    >>> dummy = dummy.new_reply('Testing...')
     >>> dummy.time = 2
-    >>> b = bd.bug_from_shortname("b")
-    >>> b.status = "open"
+    >>> b = bd.bug_from_uuid('b')
+    >>> b.status = 'open'
     >>> b.comment_root.time = 0
-    >>> dummy = b.new_comment("1 2")
+    >>> dummy = b.new_comment('1 2')
     >>> dummy.time = 1
-    >>> dummy = dummy.new_reply("1 2 3 4")
+    >>> dummy = dummy.new_reply('1 2 3 4')
     >>> dummy.time = 2
-    >>> os.chdir(bd.root)
-    >>> execute(["a", "b"], manipulate_encodings=False)
-    Merging bugs a and b
-    >>> bd._clear_bugs()
-    >>> a = bd.bug_from_shortname("a")
+
+    >>> ret = cmd.run(bd.storage, bd, {}, ['/a', '/b'])
+    Merged bugs #abc/a# and #abc/b#
+    >>> bd.flush_reload()
+    >>> a = bd.bug_from_uuid('a')
     >>> a.load_comments()
-    >>> mergeA = a.comment_from_shortname(":3")
+    >>> a_comments = sorted([c for c in a.comments()],
+    ...                     cmp=libbe.comment.cmp_time)
+    >>> mergeA = a_comments[0]
     >>> mergeA.time = 3
     >>> print a.string(show_comments=True) # doctest: +ELLIPSIS
               ID : a
-      Short name : a
+      Short name : abc/a
         Severity : minor
           Status : open
         Assigned : 
@@ -57,42 +68,44 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False,
          Created : ...
     Bug A
     --------- Comment ---------
-    Name: a:1
+    Name: abc/a/...
     From: ...
     Date: ...
     <BLANKLINE>
     Testing
       --------- Comment ---------
-      Name: a:2
+      Name: abc/a/...
       From: ...
       Date: ...
     <BLANKLINE>
       Testing...
     --------- Comment ---------
-    Name: a:3
+    Name: abc/a/...
     From: ...
     Date: ...
     <BLANKLINE>
-    Merged from bug b
+    Merged from bug #abc/b#
       --------- Comment ---------
-      Name: a:4
+      Name: abc/a/...
       From: ...
       Date: ...
     <BLANKLINE>
       1 2
         --------- Comment ---------
-        Name: a:5
+        Name: abc/a/...
         From: ...
         Date: ...
     <BLANKLINE>
         1 2 3 4
-    >>> b = bd.bug_from_shortname("b")
+    >>> b = bd.bug_from_uuid('b')
     >>> b.load_comments()
-    >>> mergeB = b.comment_from_shortname(":3")
+    >>> b_comments = sorted([c for c in b.comments()],
+    ...                     libbe.comment.cmp_time)
+    >>> mergeB = b_comments[0]
     >>> mergeB.time = 3
     >>> print b.string(show_comments=True) # doctest: +ELLIPSIS
               ID : b
-      Short name : b
+      Short name : abc/b
         Severity : minor
           Status : closed
         Assigned : 
@@ -101,66 +114,73 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False,
          Created : ...
     Bug B
     --------- Comment ---------
-    Name: b:1
+    Name: abc/b/...
     From: ...
     Date: ...
     <BLANKLINE>
     1 2
       --------- Comment ---------
-      Name: b:2
+      Name: abc/b/...
       From: ...
       Date: ...
     <BLANKLINE>
       1 2 3 4
     --------- Comment ---------
-    Name: b:3
+    Name: abc/b/...
     From: ...
     Date: ...
     <BLANKLINE>
-    Merged into bug a
+    Merged into bug #abc/a#
     >>> print b.status
     closed
     >>> bd.cleanup()
     """
-    parser = get_parser()
-    options, args = parser.parse_args(args)
-    cmdutil.default_complete(options, args, parser,
-                             bugid_args={0: lambda bug : bug.active==True,
-                                         1: lambda bug : bug.active==True})
+    name = 'merge'
 
-    if len(args) < 2:
-        raise cmdutil.UsageError("Please specify two bug ids.")
-    if len(args) > 2:
-        help()
-        raise cmdutil.UsageError("Too many arguments.")
-    
-    bd = bugdir.BugDir(from_disk=True,
-                       manipulate_encodings=manipulate_encodings,
-                       root=dir)
-    bugA = cmdutil.bug_from_id(bd, args[0])
-    bugA.load_comments()
-    bugB = cmdutil.bug_from_id(bd, args[1])
-    bugB.load_comments()
-    mergeA = bugA.new_comment("Merged from bug %s" % bugB.uuid)
-    newCommTree = copy.deepcopy(bugB.comment_root)
-    for comment in newCommTree.traverse(): # all descendant comments
-        comment.bug = bugA
-        comment.save() # force onto disk under bugA
-    for comment in newCommTree: # just the child comments
-        mergeA.add_reply(comment, allow_time_inversion=True)
-    bugB.new_comment("Merged into bug %s" % bugA.uuid)
-    bugB.status = "closed"
-    print "Merging bugs %s and %s" % (bugA.uuid, bugB.uuid)
+    def __init__(self, *args, **kwargs):
+        libbe.command.Command.__init__(self, *args, **kwargs)
+        self.requires_bugdir = True
+        self.args.extend([
+                libbe.command.Argument(
+                    name='bug-id', metavar='BUG-ID', default=None,
+                    completion_callback=libbe.command.util.complete_bug_id),
+                libbe.command.Argument(
+                    name='bug-id-to-merge', metavar='BUG-ID', default=None,
+                    completion_callback=libbe.command.util.complete_bug_id),
+                ])
 
-def get_parser():
-    parser = cmdutil.CmdOptionParser("be merge BUG-ID BUG-ID")
-    return parser
+    def _run(self, storage, bugdir, **params):
+        bugA,dummy_comment = \
+            libbe.command.util.bug_comment_from_user_id(
+                bugdir, params['bug-id'])
+        bugA.load_comments()
+        bugB,dummy_comment = \
+            libbe.command.util.bug_comment_from_user_id(
+                bugdir, params['bug-id-to-merge'])
+        bugB.load_comments()
+        mergeA = bugA.new_comment('Merged from bug #%s#' % bugB.id.long_user())
+        newCommTree = copy.deepcopy(bugB.comment_root)
+        for comment in newCommTree.traverse(): # all descendant comments
+            comment.bug = bugA
+            # uuids must be unique in storage
+            if comment.alt_id == None:
+                comment.storage = None
+                comment.alt_id = comment.uuid
+                comment.storage = storage
+            comment.uuid = libbe.util.id.uuid_gen() 
+            comment.save() # force onto disk under bugA
 
-longhelp="""
+        for comment in newCommTree: # just the child comments
+            mergeA.add_reply(comment, allow_time_inversion=True)
+        bugB.new_comment('Merged into bug #%s#' % bugA.id.long_user())
+        bugB.status = 'closed'
+        print >> self.stdout, 'Merged bugs #%s# and #%s#' \
+            % (bugA.id.user(), bugB.id.user())
+        return 0
+
+    def _long_help(self):
+        return """
 The second bug (B) is merged into the first (A).  This adds merge
 comments to both bugs, closes B, and appends B's comment tree to A's
 merge comment.
 """
-
-def help():
-    return get_parser().help_str() + longhelp
index 15826325902d399588a09778e628b510b468ca52..3b8a9c7fed1c895e5badd21fa479d0650e1e4f4b 100644 (file)
@@ -155,6 +155,8 @@ class Comment(Tree, settings_object.SavedSettingsObject):
                 decode=self.content_type.startswith("text/"))
     def _set_comment_body(self, old=None, new=None, force=False):
         assert self.uuid != INVALID_UUID, self
+        if self.bug != None and self.bug.bugdir != None:
+            new = libbe.util.id.short_to_long_user([self.bug.bugdir], new)
         if (self.storage != None and self.storage.writeable == True) \
                 or force==True:
             assert new != None, "Can't save empty comment"
@@ -460,7 +462,10 @@ class Comment(Tree, settings_object.SavedSettingsObject):
         lines.append("Date: %s" % self.date)
         lines.append("")
         if self.content_type.startswith("text/"):
-            lines.extend((self.body or "").splitlines())
+            body = (self.body or "")
+            if self.bug != None and self.bug.bugdir != None:
+                body = libbe.util.id.long_to_short_user([self.bug.bugdir], body)
+            lines.extend(body.splitlines())
         else:
             lines.append("Content type %s not printable.  Try XML output instead" % self.content_type)