From 0f87a22c20a019f49455005542d4c60216ce39d2 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 14 Dec 2009 20:13:30 -0500 Subject: [PATCH] Transitioned merge to Command-format --- libbe/bug.py | 3 +- libbe/bugdir.py | 2 +- libbe/command/comment.py | 9 ++- libbe/command/list.py | 4 +- libbe/command/merge.py | 164 ++++++++++++++++++++++----------------- libbe/comment.py | 7 +- 6 files changed, 107 insertions(+), 82 deletions(-) diff --git a/libbe/bug.py b/libbe/bug.py index 6c5f958..da9a1a2 100644 --- a/libbe/bug.py +++ b/libbe/bug.py @@ -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 : diff --git a/libbe/bugdir.py b/libbe/bugdir.py index 7ec8456..aa4d990 100644 --- a/libbe/bugdir.py +++ b/libbe/bugdir.py @@ -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 ' bug_a.time = 0 diff --git a/libbe/command/comment.py b/libbe/command/comment.py index 3ec4062..23def57 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -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 """ diff --git a/libbe/command/list.py b/libbe/command/list.py index 23dbdc0..7c3f5af 100644 --- a/libbe/command/list.py +++ b/libbe/command/list.py @@ -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() diff --git a/libbe/command/merge.py b/libbe/command/merge.py index ac09b40..4624ab7 100644 --- a/libbe/command/merge.py +++ b/libbe/command/merge.py @@ -14,41 +14,52 @@ # 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: ... Testing --------- Comment --------- - Name: a:2 + Name: abc/a/... From: ... Date: ... Testing... --------- Comment --------- - Name: a:3 + Name: abc/a/... From: ... Date: ... - Merged from bug b + Merged from bug #abc/b# --------- Comment --------- - Name: a:4 + Name: abc/a/... From: ... Date: ... 1 2 --------- Comment --------- - Name: a:5 + Name: abc/a/... From: ... Date: ... 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: ... 1 2 --------- Comment --------- - Name: b:2 + Name: abc/b/... From: ... Date: ... 1 2 3 4 --------- Comment --------- - Name: b:3 + Name: abc/b/... From: ... Date: ... - 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 diff --git a/libbe/comment.py b/libbe/comment.py index 1582632..3b8a9c7 100644 --- a/libbe/comment.py +++ b/libbe/comment.py @@ -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) -- 2.26.2