aboutsummaryrefslogtreecommitdiffstats
path: root/becommands
diff options
context:
space:
mode:
authorChris Ball <cjb@laptop.org>2010-06-20 19:19:06 -0400
committerChris Ball <cjb@laptop.org>2010-06-20 19:19:06 -0400
commit0df4bd7ae194bb07f36a2a69a0549037de01cb52 (patch)
treeea9128bbbedd8df9b1d6c737f704260874680a6b /becommands
parent429e33fb4c7be8daa791fb744a14024ef27a72c2 (diff)
parenta2a51929a848ffa6db92ec7218994461ecccb50a (diff)
downloadbugseverywhere-0df4bd7ae194bb07f36a2a69a0549037de01cb52.tar.gz
Merge with Trevor.
Diffstat (limited to 'becommands')
-rw-r--r--becommands/__init__.py0
-rw-r--r--becommands/assign.py87
-rw-r--r--becommands/close.py60
-rw-r--r--becommands/comment.py228
-rw-r--r--becommands/commit.py78
-rw-r--r--becommands/depend.py339
-rw-r--r--becommands/diff.py120
-rw-r--r--becommands/help.py68
-rw-r--r--becommands/html.py588
-rw-r--r--becommands/init.py100
-rw-r--r--becommands/list.py248
-rw-r--r--becommands/merge.py165
-rw-r--r--becommands/new.py80
-rw-r--r--becommands/open.py58
-rw-r--r--becommands/remove.py62
-rw-r--r--becommands/set.py130
-rw-r--r--becommands/severity.py103
-rw-r--r--becommands/show.py116
-rw-r--r--becommands/status.py115
-rw-r--r--becommands/subscribe.py390
-rw-r--r--becommands/tag.py134
-rw-r--r--becommands/target.py95
22 files changed, 0 insertions, 3364 deletions
diff --git a/becommands/__init__.py b/becommands/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/becommands/__init__.py
+++ /dev/null
diff --git a/becommands/assign.py b/becommands/assign.py
deleted file mode 100644
index 794f028..0000000
--- a/becommands/assign.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Assign an individual or group to fix a bug"""
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> bd.bug_from_shortname("a").assigned is None
- True
-
- >>> execute(["a"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> bd.bug_from_shortname("a").assigned == bd.user_id
- True
-
- >>> execute(["a", "someone"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> print bd.bug_from_shortname("a").assigned
- someone
-
- >>> execute(["a","none"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> bd.bug_from_shortname("a").assigned is None
- True
- >>> 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})
- assert(len(args) in (0, 1, 2))
- if len(args) == 0:
- raise cmdutil.UsageError("Please specify a bug id.")
- if len(args) > 2:
- help()
- raise cmdutil.UsageError("Too many arguments.")
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- bug = bd.bug_from_shortname(args[0])
- if len(args) == 1:
- bug.assigned = bd.user_id
- elif len(args) == 2:
- if args[1] == "none":
- bug.assigned = None
- else:
- bug.assigned = args[1]
- bd.save()
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be assign BUG-ID [ASSIGNEE]")
- return parser
-
-longhelp = """
-Assign a person to fix a bug.
-
-By default, the bug is self-assigned. If an assignee is specified, the bug
-will be assigned to that person.
-
-Assignees should be the person's Bugs Everywhere identity, the string that
-appears in Creator fields.
-
-To un-assign a bug, specify "none" for the assignee.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/close.py b/becommands/close.py
deleted file mode 100644
index 0532ed2..0000000
--- a/becommands/close.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Close a bug"""
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> from libbe import bugdir
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> print bd.bug_from_shortname("a").status
- open
- >>> execute(["a"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> print bd.bug_from_shortname("a").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})
- if len(args) == 0:
- raise cmdutil.UsageError("Please specify a bug id.")
- if len(args) > 1:
- raise cmdutil.UsageError("Too many arguments.")
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- bug.status = "closed"
- bd.save()
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be close BUG-ID")
- return parser
-
-longhelp="""
-Close the bug identified by BUG-ID.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/comment.py b/becommands/comment.py
deleted file mode 100644
index 9a614b2..0000000
--- a/becommands/comment.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Add a comment to a bug"""
-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, manipulate_encodings=True):
- """
- >>> import time
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["a", "This is a comment about a"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> bug = cmdutil.bug_from_shortname(bd, "a")
- >>> bug.load_comments(load_full=False)
- >>> comment = bug.comment_root[0]
- >>> print comment.body
- This is a comment about a
- <BLANKLINE>
- >>> comment.author == bd.user_id
- True
- >>> comment.time <= int(time.time())
- True
- >>> comment.in_reply_to is None
- True
-
- >>> if 'EDITOR' in os.environ:
- ... del os.environ["EDITOR"]
- >>> execute(["b"], manipulate_encodings=False)
- Traceback (most recent call last):
- UserError: No comment supplied, and EDITOR not specified.
-
- >>> os.environ["EDITOR"] = "echo 'I like cheese' > "
- >>> execute(["b"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> bug = cmdutil.bug_from_shortname(bd, "b")
- >>> bug.load_comments(load_full=False)
- >>> comment = bug.comment_root[0]
- >>> print comment.body
- I like cheese
- <BLANKLINE>
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) == 0:
- raise cmdutil.UsageError("Please specify a bug or comment id.")
- if len(args) > 2:
- raise cmdutil.UsageError("Too many arguments.")
-
- shortname = args[0]
- 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_reply = True
- else:
- bugname = shortname
- is_reply = False
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, bugname)
- bug.load_comments(load_full=False)
- if is_reply:
- parent = bug.comment_root.comment_from_shortname(shortname,
- bug_shortname=bugname)
- else:
- parent = bug.comment_root
-
- if len(args) == 1: # try to launch an editor for comment-body entry
- try:
- if parent == bug.comment_root:
- parent_body = bug.summary+"\n"
- else:
- parent_body = parent.body
- estr = "Please enter your comment above\n\n> %s\n" \
- % ("\n> ".join(parent_body.splitlines()))
- body = editor.editor_string(estr)
- except editor.CantFindEditor, e:
- raise cmdutil.UserError, "No comment supplied, and EDITOR not specified."
- if body is None:
- raise cmdutil.UserError("No comment entered.")
- elif args[1] == '-': # read body from stdin
- binary = not (options.content_type == None
- or options.content_type.startswith("text/"))
- if not binary:
- body = sys.stdin.read()
- if not body.endswith('\n'):
- body+='\n'
- else: # read-in without decoding
- body = sys.__stdin__.read()
- else: # body = arg[1]
- body = args[1]
- if not body.endswith('\n'):
- body+='\n'
-
- if options.XML == False:
- new = parent.new_reply(body=body)
- if options.author != None:
- new.author = options.author
- if options.alt_id != None:
- new.alt_id = options.alt_id
- 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)
- nc.save()
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be comment ID [COMMENT]")
- parser.add_option("-a", "--author", metavar="AUTHOR", dest="author",
- help="Set the comment author", default=None)
- parser.add_option("--alt-id", metavar="ID", dest="alt_id",
- help="Set an alternate comment ID", default=None)
- 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="""
-To add a comment to a bug, use the bug ID as the argument. To reply
-to another comment, specify the comment name (as shown in "be show"
-output). COMMENT, if specified, should be either the text of your
-comment or "-", in which case the text will be read from stdin. If
-you do not specify a COMMENT, $EDITOR is used to launch an editor. If
-COMMENT is unspecified and EDITOR is not set, no comment will be
-created.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option,value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- for pos,value in enumerate(args):
- if value == "--complete":
- if pos == 0: # fist positional argument is a bug or comment id
- if len(args) >= 2:
- partial = args[1].split(':')[0] # take only bugid portion
- else:
- partial = ""
- ids = []
- try:
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=False)
- bugs = []
- for uuid in bd.list_uuids():
- if uuid.startswith(partial):
- bug = bd.bug_from_uuid(uuid)
- if bug.active == True:
- bugs.append(bug)
- for bug in bugs:
- shortname = bd.bug_shortname(bug)
- ids.append(shortname)
- bug.load_comments(load_full=False)
- for id,comment in bug.comment_shortnames(shortname):
- ids.append(id)
- except bugdir.NoBugDir:
- pass
- raise cmdutil.GetCompletions(ids)
- raise cmdutil.GetCompletions()
diff --git a/becommands/commit.py b/becommands/commit.py
deleted file mode 100644
index dc70e7e..0000000
--- a/becommands/commit.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Commit the currently pending changes to the repository"""
-from libbe import cmdutil, bugdir, editor, vcs
-import sys
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os, time
- >>> from libbe import bug
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> full_path = "testfile"
- >>> test_contents = "A test file"
- >>> bd.vcs.set_file_contents(full_path, test_contents)
- >>> execute(["Added %s." % (full_path)], manipulate_encodings=False) # doctest: +ELLIPSIS
- Committed ...
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser)
- if len(args) != 1:
- raise cmdutil.UsageError("Please supply a commit message")
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if args[0] == '-': # read summary from stdin
- assert options.body != "EDITOR", \
- "Cannot spawn and editor when the summary is using stdin."
- summary = sys.stdin.readline()
- else:
- summary = args[0]
- if options.body == None:
- body = None
- elif options.body == "EDITOR":
- body = editor.editor_string("Please enter your commit message above")
- else:
- body = bd.vcs.get_file_contents(options.body, allow_no_vcs=True)
- try:
- revision = bd.vcs.commit(summary, body=body,
- allow_empty=options.allow_empty)
- except vcs.EmptyCommit, e:
- print e
- return 1
- else:
- print "Committed %s" % revision
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be commit COMMENT")
- parser.add_option("-b", "--body", metavar="FILE", dest="body",
- help='Provide a detailed body for the commit message. In the special case that FILE == "EDITOR", spawn an editor to enter the body text (in which case you cannot use stdin for the summary)', default=None)
- parser.add_option("-a", "--allow-empty", dest="allow_empty",
- help="Allow empty commits",
- default=False, action="store_true")
- return parser
-
-longhelp="""
-Commit the current repository status. The summary specified on the
-commandline is a string (only one line) that describes the commit
-briefly or "-", in which case the string will be read from stdin.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/depend.py b/becommands/depend.py
deleted file mode 100644
index f72b8ba..0000000
--- a/becommands/depend.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Add/remove bug dependencies"""
-from libbe import cmdutil, bugdir, tree
-import os, copy
-__desc__ = __doc__
-
-BLOCKS_TAG="BLOCKS:"
-BLOCKED_BY_TAG="BLOCKED-BY:"
-
-class BrokenLink (Exception):
- def __init__(self, blocked_bug, blocking_bug, blocks=True):
- if blocks == True:
- msg = "Missing link: %s blocks %s" \
- % (blocking_bug.uuid, blocked_bug.uuid)
- else:
- msg = "Missing link: %s blocked by %s" \
- % (blocked_bug.uuid, blocking_bug.uuid)
- Exception.__init__(self, msg)
- self.blocked_bug = blocked_bug
- self.blocking_bug = blocking_bug
-
-
-def execute(args, manipulate_encodings=True):
- """
- >>> from libbe import utility
- >>> bd = bugdir.SimpleBugDir()
- >>> bd.save()
- >>> os.chdir(bd.root)
- >>> execute(["a", "b"], manipulate_encodings=False)
- a blocked by:
- b
- >>> execute(["a"], manipulate_encodings=False)
- a blocked by:
- b
- >>> execute(["--show-status", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- a blocked by:
- b closed
- >>> execute(["b", "a"], manipulate_encodings=False)
- b blocked by:
- a
- b blocks:
- a
- >>> execute(["--show-status", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- a blocked by:
- b closed
- a blocks:
- b closed
- >>> execute(["-r", "b", "a"], manipulate_encodings=False)
- b blocks:
- a
- >>> execute(["-r", "a", "b"], manipulate_encodings=False)
- >>> 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})
-
- if options.repair == True:
- if len(args) > 0:
- raise cmdutil.UsageError("No arguments with --repair calls.")
- elif len(args) < 1:
- raise cmdutil.UsageError("Please a bug id.")
- elif len(args) > 2:
- help()
- raise cmdutil.UsageError("Too many arguments.")
- elif len(args) == 2 and options.tree_depth != None:
- raise cmdutil.UsageError("Only one bug id used in tree mode.")
-
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if options.repair == True:
- good,fixed,broken = check_dependencies(bd, repair_broken_links=True)
- assert len(broken) == 0, broken
- if len(fixed) > 0:
- print "Fixed the following links:"
- print "\n".join(["%s |-- %s" % (blockee.uuid, blocker.uuid)
- for blockee,blocker in fixed])
- return 0
-
- bugA = cmdutil.bug_from_shortname(bd, args[0])
-
- if options.tree_depth != None:
- dtree = DependencyTree(bd, bugA, options.tree_depth)
- if len(dtree.blocked_by_tree()) > 0:
- print "%s blocked by:" % bugA.uuid
- for depth,node in dtree.blocked_by_tree().thread():
- if depth == 0: continue
- print "%s%s" % (" "*(depth), node.bug.string(shortlist=True))
- if len(dtree.blocks_tree()) > 0:
- print "%s blocks:" % bugA.uuid
- for depth,node in dtree.blocks_tree().thread():
- if depth == 0: continue
- print "%s%s" % (" "*(depth), node.bug.string(shortlist=True))
- return 0
-
- if len(args) == 2:
- bugB = cmdutil.bug_from_shortname(bd, args[1])
- if options.remove == True:
- remove_block(bugA, bugB)
- else: # add the dependency
- add_block(bugA, bugB)
-
- blocked_by = get_blocked_by(bd, bugA)
- if len(blocked_by) > 0:
- print "%s blocked by:" % bugA.uuid
- if options.show_status == True:
- print '\n'.join(["%s\t%s" % (bug.uuid, bug.status)
- for bug in blocked_by])
- else:
- print '\n'.join([bug.uuid for bug in blocked_by])
- blocks = get_blocks(bd, bugA)
- if len(blocks) > 0:
- print "%s blocks:" % bugA.uuid
- if options.show_status == True:
- print '\n'.join(["%s\t%s" % (bug.uuid, bug.status)
- for bug in blocks])
- else:
- print '\n'.join([bug.uuid for bug in blocks])
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be depend BUG-ID [BUG-ID]\nor: be depend --repair")
- parser.add_option("-r", "--remove", action="store_true",
- dest="remove", default=False,
- help="Remove dependency (instead of adding it)")
- parser.add_option("-s", "--show-status", action="store_true",
- dest="show_status", default=False,
- help="Show status of blocking bugs")
- parser.add_option("-t", "--tree-depth", metavar="DEPTH", default=None,
- type="int", dest="tree_depth",
- help="Print dependency tree rooted at BUG-ID with DEPTH levels of both blockers and blockees. Set DEPTH <= 0 to disable the depth limit.")
- parser.add_option("--repair", action="store_true",
- dest="repair", default=False,
- help="Check for and repair one-way links")
- return parser
-
-longhelp="""
-Set a dependency with the second bug (B) blocking the first bug (A).
-If bug B is not specified, just print a list of bugs blocking (A).
-
-To search for bugs blocked by a particular bug, try
- $ be list --extra-strings BLOCKED-BY:<your-bug-uuid>
-
-In repair mode, add the missing direction to any one-way links.
-
-The "|--" symbol in the repair-mode output is inspired by the
-"negative feedback" arrow common in biochemistry. See, for example
- http://www.nature.com/nature/journal/v456/n7223/images/nature07513-f5.0.jpg
-"""
-
-def help():
- return get_parser().help_str() + longhelp
-
-# internal helper functions
-
-def _generate_blocks_string(blocked_bug):
- return "%s%s" % (BLOCKS_TAG, blocked_bug.uuid)
-
-def _generate_blocked_by_string(blocking_bug):
- return "%s%s" % (BLOCKED_BY_TAG, blocking_bug.uuid)
-
-def _parse_blocks_string(string):
- assert string.startswith(BLOCKS_TAG)
- return string[len(BLOCKS_TAG):]
-
-def _parse_blocked_by_string(string):
- assert string.startswith(BLOCKED_BY_TAG)
- return string[len(BLOCKED_BY_TAG):]
-
-def _add_remove_extra_string(bug, string, add):
- estrs = bug.extra_strings
- if add == True:
- estrs.append(string)
- else: # remove the string
- estrs.remove(string)
- bug.extra_strings = estrs # reassign to notice change
-
-def _get_blocks(bug):
- uuids = []
- for line in bug.extra_strings:
- if line.startswith(BLOCKS_TAG):
- uuids.append(_parse_blocks_string(line))
- return uuids
-
-def _get_blocked_by(bug):
- uuids = []
- for line in bug.extra_strings:
- if line.startswith(BLOCKED_BY_TAG):
- uuids.append(_parse_blocked_by_string(line))
- return uuids
-
-def _repair_one_way_link(blocked_bug, blocking_bug, blocks=None):
- if blocks == True: # add blocks link
- blocks_string = _generate_blocks_string(blocked_bug)
- _add_remove_extra_string(blocking_bug, blocks_string, add=True)
- else: # add blocked by link
- blocked_by_string = _generate_blocked_by_string(blocking_bug)
- _add_remove_extra_string(blocked_bug, blocked_by_string, add=True)
-
-# functions exposed to other modules
-
-def add_block(blocked_bug, blocking_bug):
- blocked_by_string = _generate_blocked_by_string(blocking_bug)
- _add_remove_extra_string(blocked_bug, blocked_by_string, add=True)
- blocks_string = _generate_blocks_string(blocked_bug)
- _add_remove_extra_string(blocking_bug, blocks_string, add=True)
-
-def remove_block(blocked_bug, blocking_bug):
- blocked_by_string = _generate_blocked_by_string(blocking_bug)
- _add_remove_extra_string(blocked_bug, blocked_by_string, add=False)
- blocks_string = _generate_blocks_string(blocked_bug)
- _add_remove_extra_string(blocking_bug, blocks_string, add=False)
-
-def get_blocks(bugdir, bug):
- """
- Return a list of bugs that the given bug blocks.
- """
- blocks = []
- for uuid in _get_blocks(bug):
- blocks.append(bugdir.bug_from_uuid(uuid))
- return blocks
-
-def get_blocked_by(bugdir, bug):
- """
- Return a list of bugs blocking the given bug blocks.
- """
- blocked_by = []
- for uuid in _get_blocked_by(bug):
- blocked_by.append(bugdir.bug_from_uuid(uuid))
- return blocked_by
-
-def check_dependencies(bugdir, repair_broken_links=False):
- """
- Check that links are bi-directional for all bugs in bugdir.
-
- >>> bd = bugdir.SimpleBugDir(sync_with_disk=False)
- >>> a = bd.bug_from_uuid("a")
- >>> b = bd.bug_from_uuid("b")
- >>> blocked_by_string = _generate_blocked_by_string(b)
- >>> _add_remove_extra_string(a, blocked_by_string, add=True)
- >>> good,repaired,broken = check_dependencies(bd, repair_broken_links=False)
- >>> good
- []
- >>> repaired
- []
- >>> broken
- [(Bug(uuid='a'), Bug(uuid='b'))]
- >>> _get_blocks(b)
- []
- >>> good,repaired,broken = check_dependencies(bd, repair_broken_links=True)
- >>> _get_blocks(b)
- ['a']
- >>> good
- []
- >>> repaired
- [(Bug(uuid='a'), Bug(uuid='b'))]
- >>> broken
- []
- """
- if bugdir.sync_with_disk == True:
- bugdir.load_all_bugs()
- good_links = []
- fixed_links = []
- broken_links = []
- for bug in bugdir:
- for blocker in get_blocked_by(bugdir, bug):
- blocks = get_blocks(bugdir, blocker)
- if (bug, blocks) in good_links+fixed_links+broken_links:
- continue # already checked that link
- if bug not in blocks:
- if repair_broken_links == True:
- _repair_one_way_link(bug, blocker, blocks=True)
- fixed_links.append((bug, blocker))
- else:
- broken_links.append((bug, blocker))
- else:
- good_links.append((bug, blocker))
- for blockee in get_blocks(bugdir, bug):
- blocked_by = get_blocked_by(bugdir, blockee)
- if (blockee, bug) in good_links+fixed_links+broken_links:
- continue # already checked that link
- if bug not in blocked_by:
- if repair_broken_links == True:
- _repair_one_way_link(blockee, bug, blocks=False)
- fixed_links.append((blockee, bug))
- else:
- broken_links.append((blockee, bug))
- else:
- good_links.append((blockee, bug))
- return (good_links, fixed_links, broken_links)
-
-class DependencyTree (object):
- """
- Note: should probably be DependencyDiGraph.
- """
- def __init__(self, bugdir, root_bug, depth_limit=0):
- self.bugdir = bugdir
- self.root_bug = root_bug
- self.depth_limit = depth_limit
- def _build_tree(self, child_fn):
- root = tree.Tree()
- root.bug = self.root_bug
- root.depth = 0
- stack = [root]
- while len(stack) > 0:
- node = stack.pop()
- if self.depth_limit > 0 and node.depth == self.depth_limit:
- continue
- for bug in child_fn(self.bugdir, node.bug):
- child = tree.Tree()
- child.bug = bug
- child.depth = node.depth+1
- node.append(child)
- stack.append(child)
- return root
- def blocks_tree(self):
- if not hasattr(self, "_blocks_tree"):
- self._blocks_tree = self._build_tree(get_blocks)
- return self._blocks_tree
- def blocked_by_tree(self):
- if not hasattr(self, "_blocked_by_tree"):
- self._blocked_by_tree = self._build_tree(get_blocked_by)
- return self._blocked_by_tree
diff --git a/becommands/diff.py b/becommands/diff.py
deleted file mode 100644
index b6ac5b0..0000000
--- a/becommands/diff.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-
-"""Compare bug reports with older tree"""
-from libbe import cmdutil, bugdir, diff
-import os
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> bd.set_sync_with_disk(True)
- >>> original = bd.vcs.commit("Original status")
- >>> bug = bd.bug_from_uuid("a")
- >>> bug.status = "closed"
- >>> changed = bd.vcs.commit("Closed bug a")
- >>> os.chdir(bd.root)
- >>> if bd.vcs.versioned == True:
- ... execute([original], manipulate_encodings=False)
- ... else:
- ... print "Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed"
- Modified bugs:
- a:cm: Bug A
- Changed bug settings:
- status: open -> closed
- >>> if bd.vcs.versioned == True:
- ... execute(["--modified", original], manipulate_encodings=False)
- ... else:
- ... print "a"
- a
- >>> if bd.vcs.versioned == False:
- ... execute([original], manipulate_encodings=False)
- ... else:
- ... print "This directory is not revision-controlled."
- This directory is not revision-controlled.
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser)
- if len(args) == 0:
- revision = None
- if len(args) == 1:
- revision = args[0]
- if len(args) > 1:
- raise cmdutil.UsageError("Too many arguments.")
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if bd.vcs.versioned == False:
- print "This directory is not revision-controlled."
- else:
- if revision == None: # get the most recent revision
- revision = bd.vcs.revision_id(-1)
- old_bd = bd.duplicate_bugdir(revision)
- d = diff.Diff(old_bd, bd)
- tree = d.report_tree()
-
- uuids = []
- if options.all == True:
- options.new = options.modified = options.removed = True
- if options.new == True:
- uuids.extend([c.name for c in tree.child_by_path("/bugs/new")])
- if options.modified == True:
- uuids.extend([c.name for c in tree.child_by_path("/bugs/mod")])
- if options.removed == True:
- uuids.extend([c.name for c in tree.child_by_path("/bugs/rem")])
- if (options.new or options.modified or options.removed) == True:
- print "\n".join(uuids)
- else :
- rep = tree.report_string()
- if rep != None:
- print rep
- bd.remove_duplicate_bugdir()
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be diff [options] REVISION")
- # boolean options
- bools = (("n", "new", "Print UUIDS for new bugs"),
- ("m", "modified", "Print UUIDS for modified bugs"),
- ("r", "removed", "Print UUIDS for removed bugs"),
- ("a", "all", "Print UUIDS for all changed bugs"))
- for s in bools:
- attr = s[1].replace('-','_')
- short = "-%c" % s[0]
- long = "--%s" % s[1]
- help = s[2]
- parser.add_option(short, long, action="store_true",
- default=False, dest=attr, help=help)
- return parser
-
-longhelp="""
-Uses the VCS to compare the current tree with a previous tree, and
-prints a pretty report. If REVISION is given, it is a specifier for
-the particular previous tree to use. Specifiers are specific to their
-VCS.
-
-For Arch your specifier must be a fully-qualified revision name.
-
-Besides the standard summary output, you can use the options to output
-UUIDS for the different categories. This output can be used as the
-input to 'be show' to get and understanding of the current status.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/help.py b/becommands/help.py
deleted file mode 100644
index a8f346a..0000000
--- a/becommands/help.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2006-2009 Aaron Bentley and Panometrics, Inc.
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Print help for given subcommand"""
-from libbe import cmdutil, utility
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=False):
- """
- Print help of specified command (the manipulate_encodings argument
- is ignored).
-
- >>> execute(["help"])
- Usage: be help [COMMAND]
- <BLANKLINE>
- Options:
- -h, --help Print a help message
- --complete Print a list of available completions
- <BLANKLINE>
- Print help for specified command or list of all commands.
- <BLANKLINE>
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) > 1:
- raise cmdutil.UsageError("Too many arguments.")
- if len(args) == 0:
- print cmdutil.help()
- else:
- try:
- print cmdutil.help(args[0])
- except AttributeError:
- print "No help available"
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be help [COMMAND]")
- return parser
-
-longhelp="""
-Print help for specified command or list of all commands.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option, value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- if "--complete" in args:
- cmds = [command for command,module in cmdutil.iter_commands()]
- raise cmdutil.GetCompletions(cmds)
diff --git a/becommands/html.py b/becommands/html.py
deleted file mode 100644
index 908c714..0000000
--- a/becommands/html.py
+++ /dev/null
@@ -1,588 +0,0 @@
-# Copyright (C) 2009 Gianluca Montecchi <gian@grys.it>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Generate a static HTML dump of the current repository status"""
-from libbe import cmdutil, bugdir, bug
-#from html_data import *
-import codecs, os, re, string, time
-import xml.sax.saxutils, htmlentitydefs
-
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute([], manipulate_encodings=False)
- Creating the html output in html_export
- >>> os.path.exists("./html_export")
- True
- >>> os.path.exists("./html_export/index.html")
- True
- >>> os.path.exists("./html_export/index_inactive.html")
- True
- >>> os.path.exists("./html_export/bugs")
- True
- >>> os.path.exists("./html_export/bugs/a.html")
- True
- >>> os.path.exists("./html_export/bugs/b.html")
- True
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- cmdutil.default_complete(options, args, parser,
- bugid_args={0: lambda bug : bug.active==False})
-
- if len(args) == 0:
- out_dir = options.outdir
- print "Creating the html output in %s"%out_dir
- else:
- out_dir = args[0]
- if len(args) > 0:
- raise cmdutil.UsageError, "Too many arguments."
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bd.load_all_bugs()
- status_list = bug.status_values
- severity_list = bug.severity_values
- st = {}
- se = {}
- stime = {}
- bugs_active = []
- bugs_inactive = []
- for s in status_list:
- st[s] = 0
- for b in sorted(bd, reverse=True):
- stime[b.uuid] = b.time
- if b.active == True:
- bugs_active.append(b)
- else:
- bugs_inactive.append(b)
- st[b.status] += 1
- ordered_bug_list = sorted([(value,key) for (key,value) in stime.items()])
- ordered_bug_list_in = sorted([(value,key) for (key,value) in stime.items()])
- #open_bug_list = sorted([(value,key) for (key,value) in bugs.items()])
-
- html_gen = BEHTMLGen(bd)
- html_gen.create_index_file(out_dir, st, bugs_active, ordered_bug_list, "active", bd.encoding)
- html_gen.create_index_file(out_dir, st, bugs_inactive, ordered_bug_list, "inactive", bd.encoding)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be open OUTPUT_DIR")
- parser.add_option("-o", "--output", metavar="export_dir", dest="outdir",
- help="Set the output path, default is ./html_export", default="html_export")
- return parser
-
-longhelp="""
-Generate a set of html pages representing the current state of the bug
-directory.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option, value in cmdutil.option_value_pairs(options, parser):
- if "--complete" in args:
- raise cmdutil.GetCompletions() # no positional arguments for list
-
-
-def escape(string):
- if string == None:
- return ""
- chars = []
- for char in xml.sax.saxutils.escape(string):
- codepoint = ord(char)
- if codepoint in htmlentitydefs.codepoint2name:
- char = "&%s;" % htmlentitydefs.codepoint2name[codepoint]
- chars.append(char)
- return "".join(chars)
-
-class BEHTMLGen():
- def __init__(self, bd):
- self.index_value = ""
- self.bd = bd
-
- self.css_file = """
- body {
- font-family: "lucida grande", "sans serif";
- color: #333;
- width: auto;
- margin: auto;
- }
-
-
- div.main {
- padding: 20px;
- margin: auto;
- padding-top: 0;
- margin-top: 1em;
- background-color: #fcfcfc;
- }
-
- .comment {
- padding: 20px;
- margin: auto;
- padding-top: 20px;
- margin-top: 0;
- }
-
- .commentF {
- padding: 0px;
- margin: auto;
- padding-top: 0px;
- paddin-bottom: 20px;
- margin-top: 0;
- }
-
- tb {
- border = 1;
- }
-
- .wishlist-row {
- background-color: #B4FF9B;
- width: auto;
- }
-
- .minor-row {
- background-color: #FCFF98;
- width: auto;
- }
-
-
- .serious-row {
- background-color: #FFB648;
- width: auto;
- }
-
- .critical-row {
- background-color: #FF752A;
- width: auto;
- }
-
- .fatal-row {
- background-color: #FF3300;
- width: auto;
- }
-
- .person {
- font-family: courier;
- }
-
- a, a:visited {
- background: inherit;
- text-decoration: none;
- }
-
- a {
- color: #003d41;
- }
-
- a:visited {
- color: #553d41;
- }
-
- ul {
- list-style-type: none;
- padding: 0;
- }
-
- p {
- width: auto;
- }
-
- .inline-status-image {
- position: relative;
- top: 0.2em;
- }
-
- .dimmed {
- color: #bbb;
- }
-
- table {
- border-style: 10px solid #313131;
- border-spacing: 0;
- width: auto;
- }
-
- table.log {
- }
-
- td {
- border-width: 0;
- border-style: none;
- padding-right: 0.5em;
- padding-left: 0.5em;
- width: auto;
- }
-
- .td_sel {
- background-color: #afafaf;
- border: 1px solid #afafaf;
- font-weight:bold;
- padding-right: 1em;
- padding-left: 1em;
-
- }
-
- .td_nsel {
- border: 0px;
- padding-right: 1em;
- padding-left: 1em;
- }
-
- tr {
- vertical-align: top;
- width: auto;
- }
-
- h1 {
- padding: 0.5em;
- background-color: #305275;
- margin-top: 0;
- margin-bottom: 0;
- color: #fff;
- margin-left: -20px;
- margin-right: -20px;
- }
-
- wid {
- text-transform: uppercase;
- font-size: smaller;
- margin-top: 1em;
- margin-left: -0.5em;
- /*background: #fffbce;*/
- /*background: #628a0d;*/
- padding: 5px;
- color: #305275;
- }
-
- .attrname {
- text-align: right;
- font-size: smaller;
- }
-
- .attrval {
- color: #222;
- }
-
- .issue-closed-fixed {
- background-image: "green-check.png";
- }
-
- .issue-closed-wontfix {
- background-image: "red-check.png";
- }
-
- .issue-closed-reorg {
- background-image: "blue-check.png";
- }
-
- .inline-issue-link {
- text-decoration: underline;
- }
-
- img {
- border: 0;
- }
-
-
- div.footer {
- font-size: small;
- padding-left: 20px;
- padding-right: 20px;
- padding-top: 5px;
- padding-bottom: 5px;
- margin: auto;
- background: #305275;
- color: #fffee7;
- }
-
- .footer a {
- color: #508d91;
- }
-
-
- .header {
- font-family: "lucida grande", "sans serif";
- font-size: smaller;
- background-color: #a9a9a9;
- text-align: left;
-
- padding-right: 0.5em;
- padding-left: 0.5em;
-
- }
-
-
- .selected-cell {
- background-color: #e9e9e2;
- }
-
- .plain-cell {
- background-color: #f9f9f9;
- }
-
-
- .logcomment {
- padding-left: 4em;
- font-size: smaller;
- }
-
- .id {
- font-family: courier;
- }
-
- .table_bug {
- background-color: #afafaf;
- border: 2px solid #afafaf;
- }
-
- .message {
- }
-
- .progress-meter-done {
- background-color: #03af00;
- }
-
- .progress-meter-undone {
- background-color: #ddd;
- }
-
- .progress-meter {
- }
-
- """
-
- self.index_first = """
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <title>BugsEverywhere Issue Tracker</title>
- <meta http-equiv="Content-Type" content="text/html; charset=%s" />
- <link rel="stylesheet" href="style.css" type="text/css" />
- </head>
- <body>
-
-
- <div class="main">
- <h1>BugsEverywhere Bug List</h1>
- <p></p>
- <table>
-
- <tr>
- <td class="%%s"><a href="index.html">Active Bugs</a></td>
- <td class="%%s"><a href="index_inactive.html">Inactive Bugs</a></td>
- </tr>
-
- </table>
- <table class="table_bug">
- <tbody>
- """ % self.bd.encoding
-
- self.bug_line ="""
- <tr class="%s-row">
- <td ><a href="bugs/%s.html">%s</a></td>
- <td ><a href="bugs/%s.html">%s</a></td>
- <td><a href="bugs/%s.html">%s</a></td>
- <td><a href="bugs/%s.html">%s</a></td>
- <td><a href="bugs/%s.html">%s</a></td>
- </tr>
- """
-
- self.detail_first = """
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <title>BugsEverywhere Issue Tracker</title>
- <meta http-equiv="Content-Type" content="text/html; charset=%s" />
- <link rel="stylesheet" href="../style.css" type="text/css" />
- </head>
- <body>
-
-
- <div class="main">
- <h1>BugsEverywhere Bug List</h1>
- <h5><a href="%%s">Back to Index</a></h5>
- <h2>Bug: _bug_id_</h2>
- <table >
- <tbody>
- """ % self.bd.encoding
-
-
-
- self.detail_line ="""
- <tr>
- <td align="right">%s</td><td>%s</td>
- </tr>
- """
-
- self.index_last = """
- </tbody>
- </table>
-
- </div>
-
- <div class="footer">Generated by <a href="http://www.bugseverywhere.org/">BugsEverywhere</a> on %s</div>
-
- </body>
- </html>
- """
-
- self.comment_section = """
- """
-
- self.begin_comment_section ="""
- <tr>
- <td align="right">Comments:
- </td>
- <td>
- """
-
-
- self.end_comment_section ="""
- </td>
- </tr>
- """
-
- self.detail_last = """
- </tbody>
- </table>
- </div>
- <h5><a href="%s">Back to Index</a></h5>
- <div class="footer">Generated by <a href="http://www.bugseverywhere.org/">BugsEverywhere</a>.</div>
- </body>
- </html>
- """
-
-
- def create_index_file(self, out_dir_path, summary, bugs, ordered_bug, fileid, encoding):
- try:
- os.stat(out_dir_path)
- except:
- try:
- os.mkdir(out_dir_path)
- except:
- raise cmdutil.UsageError, "Cannot create output directory."
- try:
- FO = codecs.open(out_dir_path+"/style.css", "w", encoding)
- FO.write(self.css_file)
- FO.close()
- except:
- raise cmdutil.UsageError, "Cannot create the style.css file."
-
- try:
- os.mkdir(out_dir_path+"/bugs")
- except:
- pass
-
- try:
- if fileid == "active":
- FO = codecs.open(out_dir_path+"/index.html", "w", encoding)
- FO.write(self.index_first%('td_sel','td_nsel'))
- if fileid == "inactive":
- FO = codecs.open(out_dir_path+"/index_inactive.html", "w", encoding)
- FO.write(self.index_first%('td_nsel','td_sel'))
- except:
- raise cmdutil.UsageError, "Cannot create the index.html file."
-
- c = 0
- t = len(bugs) - 1
- for l in range(t, -1, -1):
- line = self.bug_line%(escape(bugs[l].severity),
- escape(bugs[l].uuid), escape(bugs[l].uuid[0:3]),
- escape(bugs[l].uuid), escape(bugs[l].status),
- escape(bugs[l].uuid), escape(bugs[l].severity),
- escape(bugs[l].uuid), escape(bugs[l].summary),
- escape(bugs[l].uuid), escape(bugs[l].time_string)
- )
- FO.write(line)
- c += 1
- self.create_detail_file(bugs[l], out_dir_path, fileid, encoding)
- when = time.ctime()
- FO.write(self.index_last%when)
-
-
- def create_detail_file(self, bug, out_dir_path, fileid, encoding):
- f = "%s.html"%bug.uuid
- p = out_dir_path+"/bugs/"+f
- try:
- FD = codecs.open(p, "w", encoding)
- except:
- raise cmdutil.UsageError, "Cannot create the detail html file."
-
- detail_first_ = re.sub('_bug_id_', bug.uuid[0:3], self.detail_first)
- if fileid == "active":
- FD.write(detail_first_%"../index.html")
- if fileid == "inactive":
- FD.write(detail_first_%"../index_inactive.html")
-
-
-
- bug_ = self.bd.bug_from_shortname(bug.uuid)
- bug_.load_comments(load_full=True)
-
- FD.write(self.detail_line%("ID : ", bug.uuid))
- FD.write(self.detail_line%("Short name : ", escape(bug.uuid[0:3])))
- FD.write(self.detail_line%("Severity : ", escape(bug.severity)))
- FD.write(self.detail_line%("Status : ", escape(bug.status)))
- FD.write(self.detail_line%("Assigned : ", escape(bug.assigned)))
- FD.write(self.detail_line%("Target : ", escape(bug.target)))
- FD.write(self.detail_line%("Reporter : ", escape(bug.reporter)))
- FD.write(self.detail_line%("Creator : ", escape(bug.creator)))
- FD.write(self.detail_line%("Created : ", escape(bug.time_string)))
- FD.write(self.detail_line%("Summary : ", escape(bug.summary)))
- FD.write("<tr><td colspan=\"2\"><hr /></td></tr>")
- FD.write(self.begin_comment_section)
- tr = []
- b = ''
- level = 0
- stack = []
- for depth,comment in bug_.comment_root.thread(flatten=False):
- while len(stack) > depth:
- stack.pop(-1) # pop non-parents off the stack
- FD.write("</div>\n") # close non-parent <div class="comment...
- assert len(stack) == depth
- stack.append(comment)
- lines = ["--------- Comment ---------",
- "Name: %s" % comment.uuid,
- "From: %s" % escape(comment.author),
- "Date: %s" % escape(comment.date),
- ""]
- lines.extend(escape(comment.body).splitlines())
- if depth == 0:
- FD.write('<div class="commentF">')
- else:
- FD.write('<div class="comment">')
- FD.write("<br />\n".join(lines)+"<br />\n")
- while len(stack) > 0:
- stack.pop(-1)
- FD.write("</div>\n") # close every remaining <div class="comment...
- FD.write(self.end_comment_section)
- if fileid == "active":
- FD.write(self.detail_last%"../index.html")
- if fileid == "inactive":
- FD.write(self.detail_last%"../index_inactive.html")
- FD.close()
-
-
diff --git a/becommands/init.py b/becommands/init.py
deleted file mode 100644
index a6098ba..0000000
--- a/becommands/init.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Assign the root directory for bug tracking"""
-import os.path
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> from libbe import utility, vcs
- >>> import os
- >>> dir = utility.Dir()
- >>> try:
- ... bugdir.BugDir(dir.path)
- ... except bugdir.NoBugDir, e:
- ... True
- True
- >>> execute(['--root', dir.path], manipulate_encodings=False)
- No revision control detected.
- Directory initialized.
- >>> dir.cleanup()
-
- >>> dir = utility.Dir()
- >>> os.chdir(dir.path)
- >>> vcs = vcs.installed_vcs()
- >>> vcs.init('.')
- >>> print vcs.name
- Arch
- >>> execute([], manipulate_encodings=False)
- Using Arch for revision control.
- Directory initialized.
- >>> vcs.cleanup()
-
- >>> try:
- ... execute(['--root', '.'], manipulate_encodings=False)
- ... except cmdutil.UserError, e:
- ... str(e).startswith("Directory already initialized: ")
- True
- >>> execute(['--root', '/highly-unlikely-to-exist'], manipulate_encodings=False)
- Traceback (most recent call last):
- UserError: No such directory: /highly-unlikely-to-exist
- >>> os.chdir('/')
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser)
- if len(args) > 0:
- raise cmdutil.UsageError
- try:
- bd = bugdir.BugDir(options.root_dir, from_disk=False,
- sink_to_existing_root=False,
- assert_new_BugDir=True,
- manipulate_encodings=manipulate_encodings)
- except bugdir.NoRootEntry:
- raise cmdutil.UserError("No such directory: %s" % options.root_dir)
- except bugdir.AlreadyInitialized:
- raise cmdutil.UserError("Directory already initialized: %s" % options.root_dir)
- bd.save()
- if bd.vcs.name is not "None":
- print "Using %s for revision control." % bd.vcs.name
- else:
- print "No revision control detected."
- print "Directory initialized."
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be init")
- parser.add_option("-r", "--root", metavar="DIR", dest="root_dir",
- help="Set root dir to something other than the current directory.",
- default=".")
- return parser
-
-longhelp="""
-This command initializes Bugs Everywhere support for the specified directory
-and all its subdirectories. It will auto-detect any supported revision control
-system. You can use "be set vcs_name" to change the vcs being used.
-
-The directory defaults to your current working directory.
-
-It is usually a good idea to put the Bugs Everywhere root at the source code
-root, but you can put it anywhere. If you root Bugs Everywhere in a
-subdirectory, then only bugs created in that subdirectory (and its children)
-will appear there.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/list.py b/becommands/list.py
deleted file mode 100644
index 12e1e29..0000000
--- a/becommands/list.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# Oleg Romanyshyn <oromanyshyn@panoramicfeedback.com>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""List bugs"""
-from libbe import cmdutil, bugdir, bug
-import os
-import re
-__desc__ = __doc__
-
-# get a list of * for cmp_*() comparing two bugs.
-AVAILABLE_CMPS = [fn[4:] for fn in dir(bug) if fn[:4] == 'cmp_']
-AVAILABLE_CMPS.remove("attr") # a cmp_* template.
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute([], manipulate_encodings=False)
- a:om: Bug A
- >>> execute(["--status", "all"], manipulate_encodings=False)
- a:om: Bug A
- b:cm: Bug B
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) > 0:
- raise cmdutil.UsageError("Too many arguments.")
- cmp_list = []
- if options.sort_by != None:
- for cmp in options.sort_by.split(','):
- if cmp not in AVAILABLE_CMPS:
- raise cmdutil.UserError(
- "Invalid sort on '%s'.\nValid sorts:\n %s"
- % (cmp, '\n '.join(AVAILABLE_CMPS)))
- cmp_list.append(eval('bug.cmp_%s' % cmp))
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bd.load_all_bugs()
- # select status
- if options.status != None:
- if options.status == "all":
- status = bug.status_values
- else:
- status = options.status.split(',')
- else:
- status = []
- if options.active == True:
- status.extend(list(bug.active_status_values))
- if options.unconfirmed == True:
- status.append("unconfirmed")
- if options.open == True:
- status.append("opened")
- if options.test == True:
- status.append("test")
- if status == []: # set the default value
- status = bug.active_status_values
- # select severity
- if options.severity != None:
- if options.severity == "all":
- severity = bug.severity_values
- else:
- severity = options.severity.split(',')
- else:
- severity = []
- if options.wishlist == True:
- severity.extend("wishlist")
- if options.important == True:
- serious = bug.severity_values.index("serious")
- severity.append(list(bug.severity_values[serious:]))
- if severity == []: # set the default value
- severity = bug.severity_values
- # select assigned
- if options.assigned != None:
- if options.assigned == "all":
- assigned = "all"
- else:
- assigned = options.assigned.split(',')
- else:
- assigned = []
- if options.mine == True:
- assigned.extend('-')
- if assigned == []: # set the default value
- assigned = "all"
- for i in range(len(assigned)):
- if assigned[i] == '-':
- assigned[i] = bd.user_id
- # select target
- if options.target != None:
- if options.target == "all":
- target = "all"
- else:
- target = options.target.split(',')
- else:
- target = []
- if options.cur_target == True:
- target.append(bd.target)
- if target == []: # set the default value
- target = "all"
- if options.extra_strings != None:
- extra_string_regexps = [re.compile(x) for x in options.extra_strings.split(',')]
-
- def filter(bug):
- if status != "all" and not bug.status in status:
- return False
- if severity != "all" and not bug.severity in severity:
- return False
- if assigned != "all" and not bug.assigned in assigned:
- return False
- if target != "all" and not bug.target in target:
- return False
- if options.extra_strings != None:
- if len(bug.extra_strings) == 0 and len(extra_string_regexps) > 0:
- return False
- for string in bug.extra_strings:
- for regexp in extra_string_regexps:
- if not regexp.match(string):
- return False
- return True
-
- bugs = [b for b in bd if filter(b) ]
- 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:
- print cmdutil.underlined(title)
- for bg in cur_bugs:
- if xml == True:
- print bg.xml(show_comments=True)
- elif just_uuids:
- print bg.uuid
- else:
- print bg.string(shortlist=True)
- if xml == True:
- print "</bugs>"
-
- # sort bugs
- cmp_list.extend(bug.DEFAULT_CMP_FULL_CMP_LIST)
- cmp_fn = bug.BugCompoundComparator(cmp_list=cmp_list)
- bugs.sort(cmp_fn)
-
- # print list of bugs
- list_bugs(bugs, just_uuids=options.uuids, xml=options.xml)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be list [options]")
- parser.add_option("-s", "--status", metavar="STATUS", dest="status",
- help="List bugs matching STATUS", default=None)
- parser.add_option("-v", "--severity", metavar="SEVERITY", dest="severity",
- help="List bugs matching SEVERITY", default=None)
- parser.add_option("-a", "--assigned", metavar="ASSIGNED", dest="assigned",
- help="List bugs matching ASSIGNED", default=None)
- parser.add_option("-t", "--target", metavar="TARGET", dest="target",
- help="List bugs matching TARGET", default=None)
- parser.add_option("-e", "--extra-strings", metavar="STRINGS", dest="extra_strings",
- help="List bugs matching _all_ extra strings in comma-seperated list STRINGS. e.g. --extra-strings TAG:working,TAG:xml", default=None)
- parser.add_option("-S", "--sort", metavar="SORT-BY", dest="sort_by",
- help="Adjust bug-sort criteria with comma-separated list SORT-BY. e.g. \"--sort creator,time\". Available criteria: %s" % ','.join(AVAILABLE_CMPS), default=None)
- # boolean options. All but uuids and xml are special cases of long forms
- bools = (("u", "uuids", "Only print the bug UUIDS"),
- ("w", "wishlist", "List bugs with 'wishlist' severity"),
- ("i", "important", "List bugs with >= 'serious' severity"),
- ("A", "active", "List all active bugs"),
- ("U", "unconfirmed", "List unconfirmed bugs"),
- ("o", "open", "List open bugs"),
- ("T", "test", "List bugs in testing"),
- ("m", "mine", "List bugs assigned to you"),
- ("c", "cur-target", "List bugs for the current target"),
- ("x", "xml", "Dump as XML"))
- for s in bools:
- attr = s[1].replace('-','_')
- short = "-%c" % s[0]
- long = "--%s" % s[1]
- help = s[2]
- parser.add_option(short, long, action="store_true",
- dest=attr, help=help)
- return parser
-
-
-def help():
- longhelp="""
-This command lists bugs. Normally it prints a short string like
- 576:om: Allow attachments
-Where
- 576 the bug id
- o the bug status is 'open' (first letter)
- m the bug severity is 'minor' (first letter)
- Allo... the bug summary string
-
-You can optionally (-u) print only the bug ids.
-
-There are several criteria that you can filter by:
- * status
- * severity
- * assigned (who the bug is assigned to)
- * target (bugfix deadline)
-Allowed values for each criterion may be given in a comma seperated
-list. The special string "all" may be used with any of these options
-to match all values of the criterion.
-
-status
- %s
-severity
- %s
-assigned
- free form, with the string '-' being a shortcut for yourself.
-target
- free form
-
-In addition, there are some shortcut options that set boolean flags.
-The boolean options are ignored if the matching string option is used.
-""" % (','.join(bug.status_values),
- ','.join(bug.severity_values))
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option, value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- if option == "status":
- raise cmdutil.GetCompletions(bug.status_values)
- elif option == "severity":
- raise cmdutil.GetCompletions(bug.severity_values)
- raise cmdutil.GetCompletions()
- if "--complete" in args:
- raise cmdutil.GetCompletions() # no positional arguments for list
diff --git a/becommands/merge.py b/becommands/merge.py
deleted file mode 100644
index f212b01..0000000
--- a/becommands/merge.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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):
- """
- >>> from libbe import utility
- >>> bd = bugdir.SimpleBugDir()
- >>> bd.set_sync_with_disk(True)
- >>> a = bd.bug_from_shortname("a")
- >>> a.comment_root.time = 0
- >>> dummy = a.new_comment("Testing")
- >>> dummy.time = 1
- >>> dummy = dummy.new_reply("Testing...")
- >>> dummy.time = 2
- >>> b = bd.bug_from_shortname("b")
- >>> b.status = "open"
- >>> b.comment_root.time = 0
- >>> dummy = b.new_comment("1 2")
- >>> dummy.time = 1
- >>> 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")
- >>> a.load_comments()
- >>> mergeA = a.comment_from_shortname(":3")
- >>> mergeA.time = 3
- >>> print a.string(show_comments=True) # doctest: +ELLIPSIS
- ID : a
- Short name : a
- Severity : minor
- Status : open
- Assigned :
- Target :
- Reporter :
- Creator : John Doe <jdoe@example.com>
- Created : ...
- Bug A
- --------- Comment ---------
- Name: a:1
- From: ...
- Date: ...
- <BLANKLINE>
- Testing
- --------- Comment ---------
- Name: a:2
- From: ...
- Date: ...
- <BLANKLINE>
- Testing...
- --------- Comment ---------
- Name: a:3
- From: ...
- Date: ...
- <BLANKLINE>
- Merged from bug b
- --------- Comment ---------
- Name: a:4
- From: ...
- Date: ...
- <BLANKLINE>
- 1 2
- --------- Comment ---------
- Name: a:5
- From: ...
- Date: ...
- <BLANKLINE>
- 1 2 3 4
- >>> b = bd.bug_from_shortname("b")
- >>> b.load_comments()
- >>> mergeB = b.comment_from_shortname(":3")
- >>> mergeB.time = 3
- >>> print b.string(show_comments=True) # doctest: +ELLIPSIS
- ID : b
- Short name : b
- Severity : minor
- Status : closed
- Assigned :
- Target :
- Reporter :
- Creator : Jane Doe <jdoe@example.com>
- Created : ...
- Bug B
- --------- Comment ---------
- Name: b:1
- From: ...
- Date: ...
- <BLANKLINE>
- 1 2
- --------- Comment ---------
- Name: b:2
- From: ...
- Date: ...
- <BLANKLINE>
- 1 2 3 4
- --------- Comment ---------
- Name: b:3
- From: ...
- Date: ...
- <BLANKLINE>
- Merged into bug 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})
-
- 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)
- bugA = cmdutil.bug_from_shortname(bd, args[0])
- bugA.load_comments()
- bugB = cmdutil.bug_from_shortname(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 get_parser():
- parser = cmdutil.CmdOptionParser("be merge BUG-ID BUG-ID")
- return parser
-
-longhelp="""
-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/becommands/new.py b/becommands/new.py
deleted file mode 100644
index a8ee2ec..0000000
--- a/becommands/new.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Create a new bug"""
-from libbe import cmdutil, bugdir
-import sys
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os, time
- >>> from libbe import bug
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> bug.uuid_gen = lambda: "X"
- >>> execute (["this is a test",], manipulate_encodings=False)
- Created bug with ID X
- >>> bd._clear_bugs()
- >>> bug = bd.bug_from_uuid("X")
- >>> print bug.summary
- this is a test
- >>> bug.time <= int(time.time())
- True
- >>> print bug.severity
- minor
- >>> bug.target == None
- True
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser)
- if len(args) != 1:
- raise cmdutil.UsageError("Please supply a summary message")
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- 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 != None:
- bug.assigned = bd.default_assignee
- print "Created bug with ID %s" % bd.bug_shortname(bug)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be new SUMMARY")
- parser.add_option("-r", "--reporter", metavar="REPORTER", dest="reporter",
- help="The user who reported the bug", default=None)
- parser.add_option("-a", "--assigned", metavar="ASSIGNED", dest="assigned",
- help="The developer in charge of the bug", default=None)
- return parser
-
-longhelp="""
-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():
- return get_parser().help_str() + longhelp
diff --git a/becommands/open.py b/becommands/open.py
deleted file mode 100644
index 0c6bf05..0000000
--- a/becommands/open.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Re-open a bug"""
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> print bd.bug_from_shortname("b").status
- closed
- >>> execute(["b"], manipulate_encodings=False)
- >>> bd._clear_bugs()
- >>> print bd.bug_from_shortname("b").status
- open
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser,
- bugid_args={0: lambda bug : bug.active==False})
- if len(args) == 0:
- raise cmdutil.UsageError, "Please specify a bug id."
- if len(args) > 1:
- raise cmdutil.UsageError, "Too many arguments."
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- bug.status = "open"
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be open BUG-ID")
- return parser
-
-longhelp="""
-Mark a bug as 'open'.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/remove.py b/becommands/remove.py
deleted file mode 100644
index 8d85033..0000000
--- a/becommands/remove.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Remove (delete) a bug and its comments"""
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> from libbe import mapfile
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> print bd.bug_from_shortname("b").status
- closed
- >>> execute (["b"], manipulate_encodings=False)
- Removed bug b
- >>> bd._clear_bugs()
- >>> try:
- ... bd.bug_from_shortname("b")
- ... except bugdir.NoBugMatches:
- ... print "Bug not found"
- Bug not found
- >>> 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})
- if len(args) != 1:
- raise cmdutil.UsageError, "Please specify a bug id."
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- bd.remove_bug(bug)
- print "Removed bug %s" % bug.uuid
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be remove BUG-ID")
- return parser
-
-longhelp="""
-Remove (delete) an existing bug. Use with caution: if you're not using a
-revision control system, there may be no way to recover the lost information.
-You should use this command, for example, to get rid of blank or otherwise
-mangled bugs.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/set.py b/becommands/set.py
deleted file mode 100644
index f7e68d3..0000000
--- a/becommands/set.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Change tree settings"""
-import textwrap
-from libbe import cmdutil, bugdir, vcs, 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 not in [None, settings_object.EMPTY]:
- val = "None (%s)" % default
- else:
- val = None
- return str(val)
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["target"], manipulate_encodings=False)
- None
- >>> execute(["target", "tomorrow"], manipulate_encodings=False)
- >>> execute(["target"], manipulate_encodings=False)
- tomorrow
- >>> execute(["target", "none"], manipulate_encodings=False)
- >>> execute(["target"], manipulate_encodings=False)
- None
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) > 2:
- raise cmdutil.UsageError, "Too many arguments"
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if len(args) == 0:
- keys = bd.settings_properties
- keys.sort()
- for key in keys:
- print "%16s: %s" % (key, _value_string(bd, key))
- elif len(args) == 1:
- print _value_string(bd, args[0])
- else:
- if args[1] == "none":
- setattr(bd, args[0], settings_object.EMPTY)
- else:
- if args[0] not in bd.settings_properties:
- msg = "Invalid setting %s\n" % args[0]
- msg += 'Allowed settings:\n '
- msg += '\n '.join(bd.settings_properties)
- raise cmdutil.UserError(msg)
- old_setting = bd.settings.get(args[0])
- setattr(bd, args[0], args[1])
-
-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 == "vcs_name":
- lines = dstr.split('\n')
- while lines[0].startswith("This property defaults to") == False:
- lines.pop(0)
- assert len(lines) != None, \
- "Unexpected vcs_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.
-
-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.
-
-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
-
-def complete(options, args, parser):
- for option, value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- for pos,value in enumerate(args):
- if value == "--complete":
- if pos == 0: # first positional argument is a setting name
- props = bugdir.BugDir.settings_properties
- raise cmdutil.GetCompletions(props)
- raise cmdutil.GetCompletions() # no positional arguments for list
diff --git a/becommands/severity.py b/becommands/severity.py
deleted file mode 100644
index 660586e..0000000
--- a/becommands/severity.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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 or change a bug's severity level"""
-from libbe import cmdutil, bugdir, bug
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["a"], manipulate_encodings=False)
- minor
- >>> execute(["a", "wishlist"], manipulate_encodings=False)
- >>> execute(["a"], manipulate_encodings=False)
- wishlist
- >>> execute(["a", "none"], manipulate_encodings=False)
- Traceback (most recent call last):
- UserError: Invalid severity level: none
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) not in (1,2):
- raise cmdutil.UsageError
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- if len(args) == 1:
- print bug.severity
- elif len(args) == 2:
- try:
- bug.severity = args[1]
- except ValueError, e:
- if e.name != "severity":
- raise e
- raise cmdutil.UserError ("Invalid severity level: %s" % e.value)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be severity BUG-ID [SEVERITY]")
- return parser
-
-def help():
- longhelp=["""
-Show or change a bug's severity level.
-
-If no severity is specified, the current value is printed. If a severity level
-is specified, it will be assigned to the bug.
-
-Severity levels are:
-"""]
- try: # See if there are any per-tree severity configurations
- bd = bugdir.BugDir(from_disk=True, manipulate_encodings=False)
- except bugdir.NoBugDir, e:
- pass # No tree, just show the defaults
- longest_severity_len = max([len(s) for s in bug.severity_values])
- for severity in bug.severity_values :
- description = bug.severity_description[severity]
- s = "%*s : %s\n" % (longest_severity_len, severity, description)
- longhelp.append(s)
- longhelp = ''.join(longhelp)
- return get_parser().help_str() + longhelp
-
-def complete(options, args, parser):
- for option,value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- for pos,value in enumerate(args):
- if value == "--complete":
- try: # See if there are any per-tree severity configurations
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=False)
- except bugdir.NoBugDir:
- bd = None
- if pos == 0: # fist positional argument is a bug id
- ids = []
- if bd != None:
- bd.load_all_bugs()
- filter = lambda bg : bg.active==True
- bugs = [bg for bg in bd if filter(bg)==True]
- ids = [bd.bug_shortname(bg) for bg in bugs]
- raise cmdutil.GetCompletions(ids)
- elif pos == 1: # second positional argument is a severity
- raise cmdutil.GetCompletions(bug.severity_values)
- raise cmdutil.GetCompletions()
diff --git a/becommands/show.py b/becommands/show.py
deleted file mode 100644
index 50bd6eb..0000000
--- a/becommands/show.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# Thomas Habets <thomas@habets.pp.se>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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"""
-import sys
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute (["a",], manipulate_encodings=False) # doctest: +ELLIPSIS
- ID : a
- Short name : a
- Severity : minor
- Status : open
- Assigned :
- Target :
- Reporter :
- Creator : John Doe <jdoe@example.com>
- Created : ...
- Bug A
- <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>
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- cmdutil.default_complete(options, args, parser,
- bugid_args={-1: lambda bug : bug.active==True})
- if len(args) == 0:
- raise cmdutil.UsageError
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if options.XML:
- print '<?xml version="1.0" encoding="%s" ?>' % bd.encoding
- 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:
- bugname = shortname
- is_comment = False
- if is_comment == True and options.comments == False:
- continue
- bug = cmdutil.bug_from_shortname(bd, bugname)
- if is_comment == False:
- if options.XML:
- print bug.xml(show_comments=options.comments)
- else:
- print bug.string(show_comments=options.comments)
- else:
- 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
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be show [options] ID [ID ...]")
- parser.add_option("-x", "--xml", action="store_true", default=False,
- dest='XML', 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.")
- parser.add_option("-c", "--no-comments", dest="comments",
- action="store_false", default=True,
- help="Disable comment output. This is useful if you just want more details on a bug's current status.")
- return 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.
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/status.py b/becommands/status.py
deleted file mode 100644
index f315003..0000000
--- a/becommands/status.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (C) 2008-2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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 or change a bug's status"""
-from libbe import cmdutil, bugdir, bug
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["a"], manipulate_encodings=False)
- open
- >>> execute(["a", "closed"], manipulate_encodings=False)
- >>> execute(["a"], manipulate_encodings=False)
- closed
- >>> execute(["a", "none"], manipulate_encodings=False)
- Traceback (most recent call last):
- UserError: Invalid status: none
- >>> bd.cleanup()
- """
- parser = get_parser()
- options, args = parser.parse_args(args)
- complete(options, args, parser)
- if len(args) not in (1,2):
- raise cmdutil.UsageError
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- bug = cmdutil.bug_from_shortname(bd, args[0])
- if len(args) == 1:
- print bug.status
- else:
- try:
- bug.status = args[1]
- except ValueError, e:
- if e.name != "status":
- raise
- raise cmdutil.UserError ("Invalid status: %s" % e.value)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be status BUG-ID [STATUS]")
- return parser
-
-
-def help():
- 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])
- 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" % (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):
- for option,value in cmdutil.option_value_pairs(options, parser):
- if value == "--complete":
- # no argument-options at the moment, so this is future-proofing
- raise cmdutil.GetCompletions()
- for pos,value in enumerate(args):
- if value == "--complete":
- try: # See if there are any per-tree status configurations
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=False)
- except bugdir.NoBugDir:
- bd = None
- if pos == 0: # fist positional argument is a bug id
- ids = []
- if bd != None:
- bd.load_all_bugs()
- ids = [bd.bug_shortname(bg) for bg in bd]
- raise cmdutil.GetCompletions(ids)
- elif pos == 1: # second positional argument is a status
- raise cmdutil.GetCompletions(bug.status_values)
- raise cmdutil.GetCompletions()
diff --git a/becommands/subscribe.py b/becommands/subscribe.py
deleted file mode 100644
index 0a23057..0000000
--- a/becommands/subscribe.py
+++ /dev/null
@@ -1,390 +0,0 @@
-# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""(Un)subscribe to change notification"""
-from libbe import cmdutil, bugdir, tree
-import os, copy
-__desc__ = __doc__
-
-TAG="SUBSCRIBE:"
-
-class SubscriptionType (tree.Tree):
- """
- Trees of subscription types to allow users to select exactly what
- notifications they want to subscribe to.
- """
- def __init__(self, type_name, *args, **kwargs):
- tree.Tree.__init__(self, *args, **kwargs)
- self.type = type_name
- def __str__(self):
- return self.type
- def __repr__(self):
- return "<SubscriptionType: %s>" % str(self)
- def string_tree(self, indent=0):
- lines = []
- for depth,node in self.thread():
- lines.append("%s%s" % (" "*(indent+2*depth), node))
- return "\n".join(lines)
-
-BUGDIR_TYPE_NEW = SubscriptionType("new")
-BUGDIR_TYPE_ALL = SubscriptionType("all", [BUGDIR_TYPE_NEW])
-
-# same name as BUGDIR_TYPE_ALL for consistency
-BUG_TYPE_ALL = SubscriptionType(str(BUGDIR_TYPE_ALL))
-
-INVALID_TYPE = SubscriptionType("INVALID")
-
-class InvalidType (ValueError):
- def __init__(self, type_name, type_root):
- msg = "Invalid type %s for tree:\n%s" \
- % (type_name, type_root.string_tree(4))
- ValueError.__init__(self, msg)
- self.type_name = type_name
- self.type_root = type_root
-
-
-def execute(args, manipulate_encodings=True):
- """
- >>> bd = bugdir.SimpleBugDir()
- >>> bd.set_sync_with_disk(True)
- >>> os.chdir(bd.root)
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- []
- >>> execute(["-s","John Doe <j@doe.com>", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- John Doe <j@doe.com> all *
- >>> bd._clear_bugs() # resync our copy of bug
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- ['SUBSCRIBE:John Doe <j@doe.com>\\tall\\t*']
- >>> execute(["-s","Jane Doe <J@doe.com>", "-S", "a.com,b.net", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- Jane Doe <J@doe.com> all a.com,b.net
- John Doe <j@doe.com> all *
- >>> execute(["-s","Jane Doe <J@doe.com>", "-S", "a.edu", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- Jane Doe <J@doe.com> all a.com,a.edu,b.net
- John Doe <j@doe.com> all *
- >>> execute(["-u", "-s","Jane Doe <J@doe.com>", "-S", "a.com", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- Jane Doe <J@doe.com> all a.edu,b.net
- John Doe <j@doe.com> all *
- >>> execute(["-s","Jane Doe <J@doe.com>", "-S", "*", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- Jane Doe <J@doe.com> all *
- John Doe <j@doe.com> all *
- >>> execute(["-u", "-s","Jane Doe <J@doe.com>", "a"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for a:
- John Doe <j@doe.com> all *
- >>> execute(["-u", "-s","John Doe <j@doe.com>", "a"], manipulate_encodings=False)
- >>> execute(["-s","Jane Doe <J@doe.com>", "-t", "new", "DIR"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for bug directory:
- Jane Doe <J@doe.com> new *
- >>> execute(["-s","Jane Doe <J@doe.com>", "DIR"], manipulate_encodings=False) # doctest: +NORMALIZE_WHITESPACE
- Subscriptions for bug directory:
- Jane Doe <J@doe.com> all *
- >>> 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})
-
- if len(args) > 1:
- help()
- raise cmdutil.UsageError("Too many arguments.")
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
-
- subscriber = options.subscriber
- if subscriber == None:
- subscriber = bd.user_id
- if options.unsubscribe == True:
- if options.servers == None:
- options.servers = "INVALID"
- if options.types == None:
- options.types = "INVALID"
- else:
- if options.servers == None:
- options.servers = "*"
- if options.types == None:
- options.types = "all"
- servers = options.servers.split(",")
- types = options.types.split(",")
-
- if len(args) == 0 or args[0] == "DIR": # directory-wide subscriptions
- type_root = BUGDIR_TYPE_ALL
- entity = bd
- entity_name = "bug directory"
- else: # bug-specific subscriptions
- type_root = BUG_TYPE_ALL
- bug = bd.bug_from_shortname(args[0])
- entity = bug
- entity_name = bug.uuid
- if options.list_all == True:
- entity_name = "anything in the bug directory"
-
- types = [type_from_name(name, type_root, default=INVALID_TYPE,
- default_ok=options.unsubscribe)
- for name in types]
- estrs = entity.extra_strings
- if options.list == True or options.list_all == True:
- pass
- else: # alter subscriptions
- if options.unsubscribe == True:
- estrs = unsubscribe(estrs, subscriber, types, servers, type_root)
- else: # add the tag
- estrs = subscribe(estrs, subscriber, types, servers, type_root)
- entity.extra_strings = estrs # reassign to notice change
-
- if options.list_all == True:
- bd.load_all_bugs()
- subscriptions = get_bugdir_subscribers(bd, servers[0])
- else:
- subscriptions = []
- for estr in entity.extra_strings:
- if estr.startswith(TAG):
- subscriptions.append(estr[len(TAG):])
-
- if len(subscriptions) > 0:
- print "Subscriptions for %s:" % entity_name
- print '\n'.join(subscriptions)
-
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be subscribe ID")
- parser.add_option("-u", "--unsubscribe", action="store_true",
- dest="unsubscribe", default=False,
- help="Unsubscribe instead of subscribing.")
- parser.add_option("-a", "--list-all", action="store_true",
- dest="list_all", default=False,
- help="List all subscribers (no ID argument, read only action).")
- parser.add_option("-l", "--list", action="store_true",
- dest="list", default=False,
- help="List subscribers (read only action).")
- parser.add_option("-s", "--subscriber", dest="subscriber",
- metavar="SUBSCRIBER",
- help="Email address of the subscriber (defaults to bugdir.user_id).")
- parser.add_option("-S", "--servers", dest="servers", metavar="SERVERS",
- help="Servers from which you want notification.")
- parser.add_option("-t", "--type", dest="types", metavar="TYPES",
- help="Types of changes you wish to be notified about.")
- return parser
-
-longhelp="""
-ID can be either a bug id, or blank/"DIR", in which case it refers to the
-whole bug directory.
-
-SERVERS specifies the servers from which you would like to receive
-notification. Multiple severs may be specified in a comma-separated
-list, or you can use "*" to match all servers (the default). If you
-have not selected a server, it should politely refrain from notifying
-you of changes, although there is no way to guarantee this behavior.
-
-Available TYPES:
- For bugs:
-%s
- For DIR :
-%s
-
-For unsubscription, any listed SERVERS and TYPES are removed from your
-subscription. Either the catch-all server "*" or type "%s" will
-remove SUBSCRIBER entirely from the specified ID.
-
-This command is intended for use primarily by public interfaces, since
-if you're just hacking away on your private repository, you'll known
-what's changed ;). This command just (un)sets the appropriate
-subscriptions, and leaves it up to each interface to perform the
-notification.
-""" % (BUG_TYPE_ALL.string_tree(6), BUGDIR_TYPE_ALL.string_tree(6),
- BUGDIR_TYPE_ALL)
-
-def help():
- return get_parser().help_str() + longhelp
-
-# internal helper functions
-
-def _generate_string(subscriber, types, servers):
- types = sorted([str(t) for t in types])
- servers = sorted(servers)
- return "%s%s\t%s\t%s" % (TAG,subscriber,",".join(types),",".join(servers))
-
-def _parse_string(string, type_root):
- assert string.startswith(TAG), string
- string = string[len(TAG):]
- subscriber,types,servers = string.split("\t")
- types = [type_from_name(name, type_root) for name in types.split(",")]
- return (subscriber,types,servers.split(","))
-
-def _get_subscriber(extra_strings, subscriber, type_root):
- for i,string in enumerate(extra_strings):
- if string.startswith(TAG):
- s,ts,srvs = _parse_string(string, type_root)
- if s == subscriber:
- return i,s,ts,srvs # match!
- return None # no match
-
-# functions exposed to other modules
-
-def type_from_name(name, type_root, default=None, default_ok=False):
- if name == str(type_root):
- return type_root
- for t in type_root.traverse():
- if name == str(t):
- return t
- if default_ok:
- return default
- raise InvalidType(name, type_root)
-
-def subscribe(extra_strings, subscriber, types, servers, type_root):
- args = _get_subscriber(extra_strings, subscriber, type_root)
- if args == None: # no match
- extra_strings.append(_generate_string(subscriber, types, servers))
- return extra_strings
- # Alter matched string
- i,s,ts,srvs = args
- for t in types:
- if t not in ts:
- ts.append(t)
- # remove descendant types
- all_ts = copy.copy(ts)
- for t in all_ts:
- for tt in all_ts:
- if tt in ts and t.has_descendant(tt):
- ts.remove(tt)
- if "*" in servers+srvs:
- srvs = ["*"]
- else:
- srvs = list(set(servers+srvs))
- extra_strings[i] = _generate_string(subscriber, ts, srvs)
- return extra_strings
-
-def unsubscribe(extra_strings, subscriber, types, servers, type_root):
- args = _get_subscriber(extra_strings, subscriber, type_root)
- if args == None: # no match
- return extra_strings # pass
- # Remove matched string
- i,s,ts,srvs = args
- all_ts = copy.copy(ts)
- for t in types:
- for tt in all_ts:
- if tt in ts and t.has_descendant(tt):
- ts.remove(tt)
- if "*" in servers+srvs:
- srvs = []
- else:
- for srv in servers:
- if srv in srvs:
- srvs.remove(srv)
- if len(ts) == 0 or len(srvs) == 0:
- extra_strings.pop(i)
- else:
- extra_strings[i] = _generate_string(subscriber, ts, srvs)
- return extra_strings
-
-def get_subscribers(extra_strings, type, server, type_root,
- match_ancestor_types=False,
- match_descendant_types=False):
- """
- Set match_ancestor_types=True if you want to find eveyone who
- cares about your particular type.
-
- Set match_descendant_types=True if you want to find subscribers
- who may only care about some subset of your type. This is useful
- for generating lists of all the subscribers in a given set of
- extra_strings.
-
- >>> def sgs(*args, **kwargs):
- ... return sorted(get_subscribers(*args, **kwargs))
- >>> es = []
- >>> es = subscribe(es, "John Doe <j@doe.com>", [BUGDIR_TYPE_ALL], ["a.com"], BUGDIR_TYPE_ALL)
- >>> es = subscribe(es, "Jane Doe <J@doe.com>", [BUGDIR_TYPE_NEW], ["*"], BUGDIR_TYPE_ALL)
- >>> sgs(es, BUGDIR_TYPE_ALL, "a.com", BUGDIR_TYPE_ALL)
- ['John Doe <j@doe.com>']
- >>> sgs(es, BUGDIR_TYPE_ALL, "a.com", BUGDIR_TYPE_ALL, match_descendant_types=True)
- ['Jane Doe <J@doe.com>', 'John Doe <j@doe.com>']
- >>> sgs(es, BUGDIR_TYPE_ALL, "b.net", BUGDIR_TYPE_ALL, match_descendant_types=True)
- ['Jane Doe <J@doe.com>']
- >>> sgs(es, BUGDIR_TYPE_NEW, "a.com", BUGDIR_TYPE_ALL)
- ['Jane Doe <J@doe.com>']
- >>> sgs(es, BUGDIR_TYPE_NEW, "a.com", BUGDIR_TYPE_ALL, match_ancestor_types=True)
- ['Jane Doe <J@doe.com>', 'John Doe <j@doe.com>']
- """
- for string in extra_strings:
- if not string.startswith(TAG):
- continue
- subscriber,types,servers = _parse_string(string, type_root)
- type_match = False
- if type in types:
- type_match = True
- if type_match == False and match_ancestor_types == True:
- for t in types:
- if t.has_descendant(type):
- type_match = True
- break
- if type_match == False and match_descendant_types == True:
- for t in types:
- if type.has_descendant(t):
- type_match = True
- break
- server_match = False
- if server in servers or servers == ["*"] or server == "*":
- server_match = True
- if type_match == True and server_match == True:
- yield subscriber
-
-def get_bugdir_subscribers(bugdir, server):
- """
- I have a bugdir. Who cares about it, and what do they care about?
- Returns a dict of dicts:
- subscribers[user][id] = types
- where id is either a bug.uuid (in the case of a bug subscription)
- or "DIR" (in the case of a bugdir subscription).
-
- Only checks bugs that are currently in memory, so you might want
- to call bugdir.load_all_bugs() first.
-
- >>> bd = bugdir.SimpleBugDir(sync_with_disk=False)
- >>> a = bd.bug_from_shortname("a")
- >>> bd.extra_strings = subscribe(bd.extra_strings, "John Doe <j@doe.com>", [BUGDIR_TYPE_ALL], ["a.com"], BUGDIR_TYPE_ALL)
- >>> bd.extra_strings = subscribe(bd.extra_strings, "Jane Doe <J@doe.com>", [BUGDIR_TYPE_NEW], ["*"], BUGDIR_TYPE_ALL)
- >>> a.extra_strings = subscribe(a.extra_strings, "John Doe <j@doe.com>", [BUG_TYPE_ALL], ["a.com"], BUG_TYPE_ALL)
- >>> subscribers = get_bugdir_subscribers(bd, "a.com")
- >>> subscribers["Jane Doe <J@doe.com>"]["DIR"]
- [<SubscriptionType: new>]
- >>> subscribers["John Doe <j@doe.com>"]["DIR"]
- [<SubscriptionType: all>]
- >>> subscribers["John Doe <j@doe.com>"]["a"]
- [<SubscriptionType: all>]
- >>> get_bugdir_subscribers(bd, "b.net")
- {'Jane Doe <J@doe.com>': {'DIR': [<SubscriptionType: new>]}}
- >>> bd.cleanup()
- """
- subscribers = {}
- for sub in get_subscribers(bugdir.extra_strings, BUGDIR_TYPE_ALL, server,
- BUGDIR_TYPE_ALL, match_descendant_types=True):
- i,s,ts,srvs = _get_subscriber(bugdir.extra_strings,sub,BUGDIR_TYPE_ALL)
- subscribers[sub] = {"DIR":ts}
- for bug in bugdir:
- for sub in get_subscribers(bug.extra_strings, BUG_TYPE_ALL, server,
- BUG_TYPE_ALL, match_descendant_types=True):
- i,s,ts,srvs = _get_subscriber(bug.extra_strings,sub,BUG_TYPE_ALL)
- if sub in subscribers:
- subscribers[sub][bug.uuid] = ts
- else:
- subscribers[sub] = {bug.uuid:ts}
- return subscribers
diff --git a/becommands/tag.py b/becommands/tag.py
deleted file mode 100644
index ecd853f..0000000
--- a/becommands/tag.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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.
-"""Tag a bug, or search bugs for tags"""
-from libbe import cmdutil, bugdir
-import os, copy
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> from libbe import utility
- >>> bd = bugdir.SimpleBugDir()
- >>> bd.set_sync_with_disk(True)
- >>> os.chdir(bd.root)
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- []
- >>> execute(["a", "GUI"], manipulate_encodings=False)
- Tags for a:
- GUI
- >>> bd._clear_bugs() # resync our copy of bug
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- ['TAG:GUI']
- >>> execute(["a", "later"], manipulate_encodings=False)
- Tags for a:
- GUI
- later
- >>> execute(["a"], manipulate_encodings=False)
- Tags for a:
- GUI
- later
- >>> execute(["--list"], manipulate_encodings=False)
- GUI
- later
- >>> execute(["a", "Alphabetically first"], manipulate_encodings=False)
- Tags for a:
- Alphabetically first
- GUI
- later
- >>> bd._clear_bugs() # resync our copy of bug
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- ['TAG:Alphabetically first', 'TAG:GUI', 'TAG:later']
- >>> a.extra_strings = []
- >>> print a.extra_strings
- []
- >>> execute(["a"], manipulate_encodings=False)
- >>> bd._clear_bugs() # resync our copy of bug
- >>> a = bd.bug_from_shortname("a")
- >>> print a.extra_strings
- []
- >>> execute(["a", "Alphabetically first"], manipulate_encodings=False)
- Tags for a:
- Alphabetically first
- >>> execute(["--remove", "a", "Alphabetically first"], manipulate_encodings=False)
- >>> 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})
-
- if len(args) == 0 and options.list == False:
- raise cmdutil.UsageError("Please specify a bug id.")
- elif len(args) > 2 or (len(args) > 0 and options.list == True):
- help()
- raise cmdutil.UsageError("Too many arguments.")
-
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if options.list:
- bd.load_all_bugs()
- tags = []
- for bug in bd:
- for estr in bug.extra_strings:
- if estr.startswith("TAG:"):
- tag = estr[4:]
- if tag not in tags:
- tags.append(tag)
- tags.sort()
- if len(tags) > 0:
- print '\n'.join(tags)
- return
- bug = cmdutil.bug_from_shortname(bd, args[0])
- if len(args) == 2:
- given_tag = args[1]
- estrs = bug.extra_strings
- tag_string = "TAG:%s" % given_tag
- if options.remove == True:
- estrs.remove(tag_string)
- else: # add the tag
- estrs.append(tag_string)
- bug.extra_strings = estrs # reassign to notice change
-
- tags = []
- for estr in bug.extra_strings:
- if estr.startswith("TAG:"):
- tags.append(estr[4:])
-
- if len(tags) > 0:
- print "Tags for %s:" % bug.uuid
- print '\n'.join(tags)
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be tag BUG-ID [TAG]\nor: be tag --list")
- parser.add_option("-r", "--remove", action="store_true", dest="remove",
- help="Remove TAG (instead of adding it)")
- parser.add_option("-l", "--list", action="store_true", dest="list",
- help="List all available tags and exit")
- return parser
-
-longhelp="""
-If TAG is given, add TAG to BUG-ID. If it is not specified, just
-print the tags for BUG-ID.
-
-To search for bugs with a particular tag, try
- $ be list --extra-strings TAG:<your-tag>
-"""
-
-def help():
- return get_parser().help_str() + longhelp
diff --git a/becommands/target.py b/becommands/target.py
deleted file mode 100644
index 7e41451..0000000
--- a/becommands/target.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc.
-# Chris Ball <cjb@laptop.org>
-# Gianluca Montecchi <gian@grys.it>
-# Marien Zwart <marienz@gentoo.org>
-# Thomas Gerigk <tgerigk@gmx.de>
-# W. Trevor King <wking@drexel.edu>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# 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 or change a bug's target for fixing"""
-from libbe import cmdutil, bugdir
-__desc__ = __doc__
-
-def execute(args, manipulate_encodings=True):
- """
- >>> import os
- >>> bd = bugdir.SimpleBugDir()
- >>> os.chdir(bd.root)
- >>> execute(["a"], manipulate_encodings=False)
- No target assigned.
- >>> execute(["a", "tomorrow"], manipulate_encodings=False)
- >>> execute(["a"], manipulate_encodings=False)
- tomorrow
- >>> execute(["--list"], manipulate_encodings=False)
- tomorrow
- >>> execute(["a", "none"], manipulate_encodings=False)
- >>> execute(["a"], manipulate_encodings=False)
- No target assigned.
- >>> 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})
-
- if len(args) not in (1, 2):
- if not (options.list == True and len(args) == 0):
- raise cmdutil.UsageError
- bd = bugdir.BugDir(from_disk=True,
- manipulate_encodings=manipulate_encodings)
- if options.list:
- ts = set([bd.bug_from_uuid(bug).target for bug in bd.list_uuids()])
- for target in sorted(ts):
- if target and isinstance(target,str):
- print target
- return
- bug = cmdutil.bug_from_shortname(bd, args[0])
- if len(args) == 1:
- if bug.target is None:
- print "No target assigned."
- else:
- print bug.target
- else:
- assert len(args) == 2
- if args[1] == "none":
- bug.target = None
- else:
- bug.target = args[1]
-
-def get_parser():
- parser = cmdutil.CmdOptionParser("be target BUG-ID [TARGET]\nor: be target --list")
- parser.add_option("-l", "--list", action="store_true", dest="list",
- help="List all available targets and exit")
- return parser
-
-longhelp="""
-Show or change a bug's target for fixing.
-
-If no target is specified, the current value is printed. If a target
-is specified, it will be assigned to the bug.
-
-Targets are freeform; any text may be specified. They will generally be
-milestone names or release numbers.
-
-The value "none" can be used to unset the target.
-
-In the alternative `be target --list` form print a list of all
-currently specified targets. Note that bug status
-(i.e. opened/closed) is ignored. If you want to list all bugs
-matching a current target, see `be list --target TARGET'.
-"""
-
-def help():
- return get_parser().help_str() + longhelp