aboutsummaryrefslogtreecommitdiffstats
path: root/becommands
diff options
context:
space:
mode:
authorChris Ball <cjb@laptop.org>2009-07-13 11:45:40 -0400
committerChris Ball <cjb@laptop.org>2009-07-13 11:45:40 -0400
commit5e249abfee7273c79640c4211607a6b4bf7b374c (patch)
treed588c5c801e142b59af53b9f9c15e3f9e1982737 /becommands
parent64f62aa2bb841c483e8cb2b663434b3ad3038f4c (diff)
parent17adbfb1c04684b986bf2c97cc4fa5197198aadc (diff)
downloadbugseverywhere-5e249abfee7273c79640c4211607a6b4bf7b374c.tar.gz
Large merge from W. Trevor King. Highlights:
be show --only-raw-body be-mbox-to-xml be-xml-to-mbox be comment --xml be --dir
Diffstat (limited to 'becommands')
-rw-r--r--becommands/assign.py7
-rw-r--r--becommands/close.py1
-rw-r--r--becommands/comment.py59
-rw-r--r--becommands/diff.py1
-rw-r--r--becommands/init.py1
-rw-r--r--becommands/list.py4
-rw-r--r--becommands/merge.py1
-rw-r--r--becommands/new.py18
-rw-r--r--becommands/open.py1
-rw-r--r--becommands/remove.py1
-rw-r--r--becommands/set.py47
-rw-r--r--becommands/severity.py1
-rw-r--r--becommands/show.py49
-rw-r--r--becommands/status.py40
-rw-r--r--becommands/tag.py2
-rw-r--r--becommands/target.py5
16 files changed, 171 insertions, 67 deletions
diff --git a/becommands/assign.py b/becommands/assign.py
index 985cfdd..e6126b8 100644
--- a/becommands/assign.py
+++ b/becommands/assign.py
@@ -2,7 +2,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,7 +17,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Assign an individual or group to fix a bug"""
-from libbe import cmdutil, bugdir, settings_object
+from libbe import cmdutil, bugdir
__desc__ = __doc__
def execute(args, test=False):
@@ -26,7 +25,7 @@ def execute(args, test=False):
>>> import os
>>> bd = bugdir.simple_bug_dir()
>>> os.chdir(bd.root)
- >>> bd.bug_from_shortname("a").assigned is settings_object.EMPTY
+ >>> bd.bug_from_shortname("a").assigned is None
True
>>> execute(["a"], test=True)
@@ -41,7 +40,7 @@ def execute(args, test=False):
>>> execute(["a","none"], test=True)
>>> bd._clear_bugs()
- >>> bd.bug_from_shortname("a").assigned is settings_object.EMPTY
+ >>> bd.bug_from_shortname("a").assigned is None
True
"""
parser = get_parser()
diff --git a/becommands/close.py b/becommands/close.py
index deaccce..ddffaa5 100644
--- a/becommands/close.py
+++ b/becommands/close.py
@@ -2,7 +2,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/comment.py b/becommands/comment.py
index 0b3a576..da82854 100644
--- a/becommands/comment.py
+++ b/becommands/comment.py
@@ -1,7 +1,6 @@
# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
# Chris Ball <cjb@laptop.org>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,9 +16,13 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Add a comment to a bug"""
-from libbe import cmdutil, bugdir, settings_object, editor
+from libbe import cmdutil, bugdir, comment, editor
import os
import sys
+try: # import core module, Python >= 2.5
+ from xml.etree import ElementTree
+except ImportError: # look for non-core module
+ from elementtree import ElementTree
__desc__ = __doc__
def execute(args, test=False):
@@ -39,7 +42,7 @@ def execute(args, test=False):
True
>>> comment.time <= int(time.time())
True
- >>> comment.in_reply_to is settings_object.EMPTY
+ >>> comment.in_reply_to is None
True
>>> if 'EDITOR' in os.environ:
@@ -108,15 +111,59 @@ def execute(args, test=False):
if not body.endswith('\n'):
body+='\n'
- comment = parent.new_reply(body=body)
- if options.content_type != None:
- comment.content_type = options.content_type
+ if options.XML == False:
+ new = parent.new_reply(body=body)
+ if options.content_type != None:
+ new.content_type = options.content_type
+ else: # import XML comment [list]
+ # read in the comments
+ str_body = body.encode("unicode_escape").replace(r'\n', '\n')
+ comment_list = ElementTree.XML(str_body)
+ if comment_list.tag not in ["bug", "comment-list"]:
+ raise comment.InvalidXML(
+ comment_list, "root element must be <bug> or <comment-list>")
+ new_comments = []
+ ids = []
+ for c in bug.comment_root.traverse():
+ ids.append(c.uuid)
+ if c.alt_id != None:
+ ids.append(c.alt_id)
+ for child in comment_list.getchildren():
+ if child.tag == "comment":
+ new = comment.Comment(bug)
+ new.from_xml(unicode(ElementTree.tostring(child)).decode("unicode_escape"))
+ if new.alt_id in ids:
+ raise cmdutil.UserError(
+ "Clashing comment alt_id: %s" % new.alt_id)
+ ids.append(new.uuid)
+ if new.alt_id != None:
+ ids.append(new.alt_id)
+ if new.in_reply_to == None:
+ new.in_reply_to = parent.uuid
+ new_comments.append(new)
+ else:
+ print >> sys.stderr, "Ignoring unknown tag %s in %s" \
+ % (child.tag, comment_list.tag)
+ try:
+ comment.list_to_root(new_comments,bug,root=parent, # link new comments
+ ignore_missing_references=options.ignore_missing_references)
+ except comment.MissingReference, e:
+ raise cmdutil.UserError(e)
+ # Protect against programmer error causing data loss:
+ kids = [c.uuid for c in parent.traverse()]
+ for nc in new_comments:
+ assert nc.uuid in kids, "%s wasn't added to %s" % (nc.uuid, parent.uuid)
bd.save()
def get_parser():
parser = cmdutil.CmdOptionParser("be comment ID [COMMENT]")
parser.add_option("-c", "--content-type", metavar="MIME", dest="content_type",
help="Set comment content-type (e.g. text/plain)", default=None)
+ parser.add_option("-x", "--xml", action="store_true", default=False,
+ dest='XML', help="Use COMMENT to specify an XML comment description rather than the comment body. The root XML element should be either <bug> or <comment-list> with one or more <comment> children. The syntax for the <comment> elements should match that generated by 'be show --xml COMMENT-ID'. Unrecognized tags are ignored. Missing tags are left at the default value. The 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 comment's <alt-id>. An exception is raised if <alt-id> conflicts with an existing comment.")
+ parser.add_option("-i", "--ignore-missing-references", action="store_true",
+ dest="ignore_missing_references",
+ help="For XML import, if any comment's <in-reply-to> refers to a non-existent comment, ignore it (instead of raising an exception).")
return parser
longhelp="""
diff --git a/becommands/diff.py b/becommands/diff.py
index 2bdea93..aa782b4 100644
--- a/becommands/diff.py
+++ b/becommands/diff.py
@@ -1,6 +1,5 @@
# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/init.py b/becommands/init.py
index 390dd15..5d9ccda 100644
--- a/becommands/init.py
+++ b/becommands/init.py
@@ -1,6 +1,5 @@
# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/list.py b/becommands/list.py
index 443704b..76614a0 100644
--- a/becommands/list.py
+++ b/becommands/list.py
@@ -2,7 +2,6 @@
# Chris Ball <cjb@laptop.org>
# Oleg Romanyshyn <oromanyshyn@panoramicfeedback.com>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -135,11 +134,12 @@ def execute(args, test=False):
return True
bugs = [b for b in bd if filter(b) ]
- if len(bugs) == 0:
+ if len(bugs) == 0 and options.xml == False:
print "No matching bugs found"
def list_bugs(cur_bugs, title=None, just_uuids=False, xml=False):
if xml == True:
+ print '<?xml version="1.0" encoding="%s" ?>' % bd.encoding
print "<bugs>"
if len(cur_bugs) > 0:
if title != None and xml == False:
diff --git a/becommands/merge.py b/becommands/merge.py
index 4bec6bf..3839774 100644
--- a/becommands/merge.py
+++ b/becommands/merge.py
@@ -1,5 +1,4 @@
# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/new.py b/becommands/new.py
index 32e070a..ceb4949 100644
--- a/becommands/new.py
+++ b/becommands/new.py
@@ -1,6 +1,5 @@
# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,7 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Create a new bug"""
-from libbe import cmdutil, bugdir, settings_object
+from libbe import cmdutil, bugdir
__desc__ = __doc__
def execute(args, test=False):
@@ -36,7 +35,7 @@ def execute(args, test=False):
True
>>> print bug.severity
minor
- >>> bug.target == settings_object.EMPTY
+ >>> bug.target == None
True
"""
parser = get_parser()
@@ -45,14 +44,18 @@ def execute(args, test=False):
if len(args) != 1:
raise cmdutil.UsageError("Please supply a summary message")
bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test)
- bug = bd.new_bug(summary=args[0])
+ if args[0] == '-': # read summary from stdin
+ summary = sys.stdin.readline()
+ else:
+ summary = args[0]
+ bug = bd.new_bug(summary=summary.strip())
if options.reporter != None:
bug.reporter = options.reporter
else:
bug.reporter = bug.creator
if options.assigned != None:
bug.assigned = options.assigned
- elif bd.default_assignee != settings_object.EMPTY:
+ elif bd.default_assignee != None:
bug.assigned = bd.default_assignee
bd.save()
print "Created bug with ID %s" % bd.bug_shortname(bug)
@@ -66,8 +69,9 @@ def get_parser():
return parser
longhelp="""
-Create a new bug, with a new ID. The summary specified on the commandline
-is a string that describes the bug briefly.
+Create a new bug, with a new ID. The summary specified on the
+commandline is a string (only one line) that describes the bug briefly
+or "-", in which case the string will be read from stdin.
"""
def help():
diff --git a/becommands/open.py b/becommands/open.py
index f9abcbb..6d13af0 100644
--- a/becommands/open.py
+++ b/becommands/open.py
@@ -2,7 +2,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/remove.py b/becommands/remove.py
index 213a8d9..e20440b 100644
--- a/becommands/remove.py
+++ b/becommands/remove.py
@@ -1,5 +1,4 @@
# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/set.py b/becommands/set.py
index e771018..fa431e9 100644
--- a/becommands/set.py
+++ b/becommands/set.py
@@ -3,7 +3,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,14 +18,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Change tree settings"""
-from libbe import cmdutil, bugdir, settings_object
+import textwrap
+from libbe import cmdutil, bugdir, rcs, settings_object
__desc__ = __doc__
def _value_string(bd, setting):
val = bd.settings.get(setting, settings_object.EMPTY)
if val == settings_object.EMPTY:
default = getattr(bd, bd._setting_name_to_attr_name(setting))
- if default != settings_object.EMPTY:
+ if default not in [None, settings_object.EMPTY]:
val = "None (%s)" % default
else:
val = None
@@ -60,7 +60,9 @@ def execute(args, test=False):
elif len(args) == 1:
print _value_string(bd, args[0])
else:
- if args[1] != "none":
+ if args[1] == "none":
+ del bd.settings[args[0]]
+ else:
if args[0] not in bd.settings_properties:
msg = "Invalid setting %s\n" % args[0]
msg += 'Allowed settings:\n '
@@ -68,14 +70,36 @@ def execute(args, test=False):
raise cmdutil.UserError(msg)
old_setting = bd.settings.get(args[0])
setattr(bd, args[0], args[1])
- else:
- del bd.settings[args[0]]
bd.save()
def get_parser():
parser = cmdutil.CmdOptionParser("be set [NAME] [VALUE]")
return parser
+def get_bugdir_settings():
+ settings = []
+ for s in bugdir.BugDir.settings_properties:
+ settings.append(s)
+ settings.sort()
+ documented_settings = []
+ for s in settings:
+ set = getattr(bugdir.BugDir, s)
+ dstr = set.__doc__.strip()
+ # per-setting comment adjustments
+ if s == "rcs_name":
+ lines = dstr.split('\n')
+ while lines[0].startswith("This property defaults to") == False:
+ lines.pop(0)
+ assert len(lines) != None, \
+ "Unexpected rcs_name docstring:\n '%s'" % dstr
+ lines.insert(
+ 0, "The name of the revision control system to use.\n")
+ dstr = '\n'.join(lines)
+ doc = textwrap.wrap(dstr, width=70, initial_indent=' ',
+ subsequent_indent=' ')
+ documented_settings.append("%s\n%s" % (s, '\n'.join(doc)))
+ return documented_settings
+
longhelp="""
Show or change per-tree settings.
@@ -83,14 +107,11 @@ If name and value are supplied, the name is set to a new value.
If no value is specified, the current value is printed.
If no arguments are provided, all names and values are listed.
-Interesting settings are:
-rcs_name
- The name of the revision control system. "Arch" and "None" are supported.
-target
- The current development goal
-
To unset a setting, set it to "none".
-"""
+
+Allowed settings are:
+
+%s""" % ('\n'.join(get_bugdir_settings()),)
def help():
return get_parser().help_str() + longhelp
diff --git a/becommands/severity.py b/becommands/severity.py
index f8a0c02..36dea6e 100644
--- a/becommands/severity.py
+++ b/becommands/severity.py
@@ -2,7 +2,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/becommands/show.py b/becommands/show.py
index ff434ab..f700caa 100644
--- a/becommands/show.py
+++ b/becommands/show.py
@@ -3,7 +3,6 @@
# Thomas Gerigk <tgerigk@gmx.de>
# Thomas Habets <thomas@habets.pp.se>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -19,6 +18,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Show a particular bug"""
+import sys
from libbe import cmdutil, bugdir
__desc__ = __doc__
@@ -40,6 +40,7 @@ def execute(args, test=False):
Bug A
<BLANKLINE>
>>> execute (["--xml", "a"], test=True) # doctest: +ELLIPSIS
+ <?xml version="1.0" encoding="..." ?>
<bug>
<uuid>a</uuid>
<short-name>a</short-name>
@@ -53,27 +54,53 @@ def execute(args, test=False):
parser = get_parser()
options, args = parser.parse_args(args)
cmdutil.default_complete(options, args, parser,
- bugid_args={0: lambda bug : bug.active==True})
+ bugid_args={-1: lambda bug : bug.active==True})
if len(args) == 0:
raise cmdutil.UsageError
bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test)
- for bugid in args:
- bug = bd.bug_from_shortname(bugid)
- if options.dumpXML:
- print bug.xml(show_comments=True)
+ for shortname in args:
+ if shortname.count(':') > 1:
+ raise cmdutil.UserError("Invalid id '%s'." % shortname)
+ elif shortname.count(':') == 1:
+ # Split shortname generated by Comment.comment_shortnames()
+ bugname = shortname.split(':')[0]
+ is_comment = True
else:
- print bug.string(show_comments=True)
- if bugid != args[-1]:
- print "" # add a blank line between bugs
+ bugname = shortname
+ is_comment = False
+ bug = bd.bug_from_shortname(bugname)
+ if is_comment == False:
+ if options.dumpXML:
+ print '<?xml version="1.0" encoding="%s" ?>' % bd.encoding
+ print bug.xml(show_comments=True)
+ else:
+ print bug.string(show_comments=True)
+ else:
+ comment = bug.comment_root.comment_from_shortname(
+ shortname, bug_shortname=bugname)
+ if options.dumpXML:
+ 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.dumpXML == False:
+ print "" # add a blank line between bugs/comments
def get_parser():
- parser = cmdutil.CmdOptionParser("be show [options] BUG-ID [BUG-ID ...]")
+ parser = cmdutil.CmdOptionParser("be show [options] ID [ID ...]")
parser.add_option("-x", "--xml", action="store_true",
dest='dumpXML', help="Dump as XML")
+ parser.add_option("--only-raw-body", action="store_true",
+ dest='only_raw_body', help="When printing only a single comment, just print it's body. This allows extraction of non-text content types.")
return parser
longhelp="""
-Show all information about a bug.
+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.
"""
def help():
diff --git a/becommands/status.py b/becommands/status.py
index d8bd4c4..882f7b3 100644
--- a/becommands/status.py
+++ b/becommands/status.py
@@ -1,5 +1,4 @@
# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -56,24 +55,39 @@ def get_parser():
def help():
- longhelp=["""
-Show or change a bug's status.
-
-If no status is specified, the current value is printed. If a status
-is specified, it will be assigned to the bug.
-
-Status levels are:
-"""]
try: # See if there are any per-tree status configurations
bd = bugdir.BugDir(from_disk=True, manipulate_encodings=False)
except bugdir.NoBugDir, e:
pass # No tree, just show the defaults
longest_status_len = max([len(s) for s in bug.status_values])
- for status in bug.status_values :
+ active_statuses = []
+ for status in bug.active_status_values :
+ description = bug.status_description[status]
+ s = "%*s : %s" % (longest_status_len, status, description)
+ active_statuses.append(s)
+ inactive_statuses = []
+ for status in bug.inactive_status_values :
description = bug.status_description[status]
- s = "%*s : %s\n" % (longest_status_len, status, description)
- longhelp.append(s)
- longhelp = ''.join(longhelp)
+ s = "%*s : %s" % (longest_status_len, status, description)
+ inactive_statuses.append(s)
+ longhelp="""
+Show or change a bug's status.
+
+If no status is specified, the current value is printed. If a status
+is specified, it will be assigned to the bug.
+
+There are two classes of statuses, active and inactive, which are only
+important for commands like "be list" that show only active bugs by
+default.
+
+Active status levels are:
+ %s
+Inactive status levels are:
+ %s
+
+You can overide the list of allowed statuses on a per-repository basis.
+See "be set --help" for more details.
+""" % ('\n '.join(active_statuses), '\n '.join(inactive_statuses))
return get_parser().help_str() + longhelp
def complete(options, args, parser):
diff --git a/becommands/tag.py b/becommands/tag.py
index ab0324e..1b20ddb 100644
--- a/becommands/tag.py
+++ b/becommands/tag.py
@@ -102,7 +102,7 @@ def execute(args, test=False):
else: # add the tag
estrs.append(tag_string)
bug.extra_strings = estrs # reassign to notice change
- bug.save()
+ bd.save()
tags = []
for estr in bug.extra_strings:
diff --git a/becommands/target.py b/becommands/target.py
index 283998a..e2283f4 100644
--- a/becommands/target.py
+++ b/becommands/target.py
@@ -4,7 +4,6 @@
# Marien Zwart <marienz@gentoo.org>
# Thomas Gerigk <tgerigk@gmx.de>
# W. Trevor King <wking@drexel.edu>
-# <abentley@panoramicfeedback.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,7 +19,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""Show or change a bug's target for fixing"""
-from libbe import cmdutil, bugdir, settings_object
+from libbe import cmdutil, bugdir
__desc__ = __doc__
def execute(args, test=False):
@@ -56,7 +55,7 @@ def execute(args, test=False):
return
bug = bd.bug_from_shortname(args[0])
if len(args) == 1:
- if bug.target is None or bug.target is settings_object.EMPTY:
+ if bug.target is None:
print "No target assigned."
else:
print bug.target