Upgraded `be show --xml` to new <be-xml> format.
authorW. Trevor King <wking@drexel.edu>
Sat, 21 Nov 2009 17:23:47 +0000 (12:23 -0500)
committerW. Trevor King <wking@drexel.edu>
Sat, 21 Nov 2009 17:23:47 +0000 (12:23 -0500)
becommands/import_xml.py
becommands/show.py
interfaces/xml/be-xml-to-mbox

index d28e97a85c7a7de07ac03d0f17309edd95d8a6d9..212c7a7c24a12309876302569fae25b525908f35 100644 (file)
@@ -172,8 +172,8 @@ The XML file should be formatted similarly to
   <be-xml>
     <version>
       <tag>1.0.0</tag>
-      <nick>be</nick>
-      <revision>446</revision>
+      <branch-nick>be</branch-nick>
+      <revno>446</revno>
       <revision-id>a@b.com-20091119214553-iqyw2cpqluww3zna</revision-id>
     <version>
     <bug>
@@ -186,10 +186,10 @@ The XML file should be formatted similarly to
     <comment>...</comment>
   </be-xml>
 where the ellipses mark output commpatible with Bug.xml() and
-Comment.xml().  Take a look at the output of `be show --xml --version`
-for some explicit examples.  Unrecognized tags are ignored.  Missing
-tags are left at the default value.  The version tag is not required,
-but is strongly recommended.
+Comment.xml().  Take a look at the output of `be show --xml` for some
+explicit examples.  Unrecognized tags are ignored.  Missing tags are
+left at the default value.  The version tag is not required, but is
+strongly recommended.
 
 The bug and comment UUIDs are always auto-generated, so if you set a
 <uuid> field, but no <alt-id> field, your <uuid> will be used as the
index 4f8c30d41025d740cf019b45f92f6930b63cf020..1211e3d73eaf9322ec011ef490913f4ffc225276 100644 (file)
@@ -17,9 +17,9 @@
 # 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.
-"""Show a particular bug"""
+"""Show a particular bug, comment, or combination of both."""
 import sys
-from libbe import cmdutil, bugdir
+from libbe import cmdutil, bugdir, comment, version, _version
 __desc__ = __doc__
 
 def execute(args, manipulate_encodings=True):
@@ -41,15 +41,23 @@ def execute(args, manipulate_encodings=True):
     <BLANKLINE>
     >>> execute (["--xml", "a"], manipulate_encodings=False) # doctest: +ELLIPSIS
     <?xml version="1.0" encoding="..." ?>
-    <bug>
-      <uuid>a</uuid>
-      <short-name>a</short-name>
-      <severity>minor</severity>
-      <status>open</status>
-      <creator>John Doe &lt;jdoe@example.com&gt;</creator>
-      <created>...</created>
-      <summary>Bug A</summary>
-    </bug>
+    <be-xml>
+      <version>
+        <tag>...</tag>
+        <branch-nick>...</branch-nick>
+        <revno>...</revno>
+        <revision-id>...</revision-id>
+      </version>
+      <bug>
+        <uuid>a</uuid>
+        <short-name>a</short-name>
+        <severity>minor</severity>
+        <status>open</status>
+        <creator>John Doe &lt;jdoe@example.com&gt;</creator>
+        <created>Thu, 01 Jan 1970 00:00:00 +0000</created>
+        <summary>Bug A</summary>
+      </bug>
+    </be-xml>
     >>> bd.cleanup()
     """
     parser = get_parser()
@@ -60,31 +68,53 @@ def execute(args, manipulate_encodings=True):
         raise cmdutil.UsageError
     bd = bugdir.BugDir(from_disk=True,
                        manipulate_encodings=manipulate_encodings)
+
+    if options.only_raw_body == True:
+        if len(args) != 1:
+            raise cmdutil.UsageError(
+                'only one ID accepted with --only-raw-body')
+        bug,comment = cmdutil.bug_comment_from_id(bd, args[0])
+        if comment == bug.comment_root:
+            raise cmdutil.UsageError(
+                "--only-raw-body requires a comment ID, not '%s'" % args[0])
+        sys.__stdout__.write(comment.body)
+        sys.exit(0)
+
+    bugs,root_comments = _sort_ids(args, options.comments)
     if options.XML:
-        print '<?xml version="1.0" encoding="%s" ?>' % bd.encoding
-    for shortname in args:
-        bugname,commname = cmdutil.parse_id(shortname)
-        if commname == None: # bug shortname
-            bug = cmdutil.bug_from_id(bd, shortname)
+        print _xml_header(bd.encoding)
+    else:
+        spaces_left = len(args) - 1
+    for bugname in bugs:
+        bug = cmdutil.bug_from_id(bd, bugname)
+        if options.XML:
+            print bug.xml(indent=2, show_comments=options.comments)
+        else:
+            print bug.string(show_comments=options.comments)
+            if spaces_left > 0:
+                spaces_left -= 1
+                print '' # add a blank line between bugs/comments
+    for bugname,comments in root_comments.items():
+        bug = cmdutil.bug_from_id(bd, bugname)
+        if options.XML:
+            print '  <bug>'
+            print '    <uuid>%s</uuid>' % bug.uuid
+        for commname in comments:
+            try:
+                comment = bug.comment_root.comment_from_shortname(commname)
+            except comment.InvalidShortname, e:
+                raise UserError(e.message)
             if options.XML:
-                print bug.xml(show_comments=options.comments)
+                print comment.xml(indent=4, shortname=bugname)
             else:
-                print bug.string(show_comments=options.comments)
-        elif options.comments == False:
-            continue
-        else: # comment shortname
-            bug,comment = cmdutil.bug_comment_from_id(shortname)
-            comment = bug.comment_root.comment_from_shortname(
-                shortname, bug_shortname=bugname)
-            if options.XML:
-                print comment.xml(shortname=shortname)
-            else:
-                if len(args) == 1 and options.only_raw_body == True:
-                    sys.__stdout__.write(comment.body)
-                else:
-                    print comment.string(shortname=shortname)
-        if shortname != args[-1] and options.XML == False:
-            print "" # add a blank line between bugs/comments
+                print comment.string(shortname=shortname)
+                if spaces_left > 0:
+                    spaces_left -= 1
+                    print '' # add a blank line between bugs/comments
+        if options.XML:
+            print '</bug>'
+    if options.XML:
+        print _xml_footer()
 
 def get_parser():
     parser = cmdutil.CmdOptionParser("be show [options] ID [ID ...]")
@@ -101,9 +131,49 @@ def get_parser():
 longhelp="""
 Show all information about the bugs or comments whose IDs are given.
 
-It's probably not a good idea to mix bug and comment IDs in a single
-call, but you're free to do so if you like.
+Without the --xml flag set, it's probably not a good idea to mix bug
+and comment IDs in a single call, but you're free to do so if you
+like.  With the --xml flag set, there will never be any root comments,
+so mix and match away (the bug listings for directly requested
+comments will be restricted to the bug uuid and the requested
+comment(s)).
+
+Directly requested comments will be grouped by their parent bug and
+placed at the end of the output, so the ordering may not match the
+order of the listed IDs.
 """
 
 def help():
     return get_parser().help_str() + longhelp
+
+def _sort_ids(ids, with_comments=True):
+    bugs = []
+    root_comments = {}
+    for id in ids:
+        bugname,commname = cmdutil.parse_id(id)
+        if commname == None:
+            bugs.append(bugname)
+        elif with_comments == True:
+            if bugname not in root_comments:
+                root_comments[bugname] = [commname]
+            else:
+                root_comments[bugname].append(commname)
+    for bugname in root_comments.keys():
+        assert bugname not in bugs, \
+            "specifically requested both '%s%s' and '%s'" \
+            % (bugname, root_comments[bugname][0], bugname)
+    return (bugs, root_comments)
+
+def _xml_header(encoding):
+    lines = ['<?xml version="1.0" encoding="%s" ?>' % encoding,
+             '<be-xml>',
+             '  <version>',
+             '    <tag>%s</tag>' % version.version()]
+    for tag in ['branch-nick', 'revno', 'revision-id']:
+        value = _version.version_info[tag.replace('-', '_')]
+        lines.append('    <%s>%s</%s>' % (tag, value, tag))
+    lines.append('  </version>')
+    return '\n'.join(lines)
+
+def _xml_footer():
+    return '</be-xml>'
index ecc6327c87291448fb844fd8e746efc0f17be887..dc4524e0012dfce6f82c2bf6c1b9689e9998da8a 100755 (executable)
@@ -86,20 +86,23 @@ class Bug (LimitedAttrDict):
               u"comments",
               u"extra-strings"]
     def print_to_mbox(self):
-        name,addr = email.utils.parseaddr(self["creator"])
-        print "From %s %s" % (addr, rfc2822_to_asctime(self["created"]))
-        print "Message-id: <%s@%s>" % (self["uuid"], DEFAULT_DOMAIN)
-        print "Date: %s" % self["created"]
-        print "From: %s" % self["creator"]
-        print "Content-Type: %s; charset=%s" % ("text/plain", DEFAULT_ENCODING)
-        print "Content-Transfer-Encoding: 8bit"
-        print "Subject: %s: %s" % (self["short-name"], self["summary"])
-        if "extra-strings" in self:
-            for estr in self["extra_strings"]:
-                print "X-Extra-String: %s" % estr
-        print ""
-        print self["summary"]
-        print ""
+        if "creator" in self:
+            # otherwise, probably a `be show` uuid-only bug to avoid
+            # root comments.
+            name,addr = email.utils.parseaddr(self["creator"])
+            print "From %s %s" % (addr, rfc2822_to_asctime(self["created"]))
+            print "Message-id: <%s@%s>" % (self["uuid"], DEFAULT_DOMAIN)
+            print "Date: %s" % self["created"]
+            print "From: %s" % self["creator"]
+            print "Content-Type: %s; charset=%s" % ("text/plain", DEFAULT_ENCODING)
+            print "Content-Transfer-Encoding: 8bit"
+            print "Subject: %s: %s" % (self["short-name"], self["summary"])
+            if "extra-strings" in self:
+                for estr in self["extra_strings"]:
+                    print "X-Extra-String: %s" % estr
+            print ""
+            print self["summary"]
+            print ""
         if "comments" in self:
             for comment in self["comments"]:
                 comment.print_to_mbox(self)