# Copyright (C) 2005 Aaron Bentley and Panometrics, Inc. # # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import bugdir import plugin import locale import os import optparse from textwrap import TextWrapper from StringIO import StringIO import utility def unique_name(bug, bugs): """ Generate short names from uuids. Picks the minimum number of characters (>=3) from the beginning of the uuid such that the short names are unique. Obviously, as the number of bugs in the database grows, these short names will cease to be unique. The complete uuid should be used for long term reference. """ chars = 3 for some_bug in bugs: if bug.uuid == some_bug.uuid: continue while (bug.uuid[:chars] == some_bug.uuid[:chars]): chars+=1 return bug.uuid[:chars] class UserError(Exception): def __init__(self, msg): Exception.__init__(self, msg) class UserErrorWrap(UserError): def __init__(self, exception): UserError.__init__(self, str(exception)) self.exception = exception def get_bug(spec, bug_dir=None): matches = [] try: if bug_dir is None: bug_dir = bugdir.tree_root('.') except bugdir.NoBugDir, e: raise UserErrorWrap(e) bugs = list(bug_dir.list()) for bug in bugs: if bug.uuid.startswith(spec): matches.append(bug) if len(matches) > 1: raise UserError("More than one bug matches %s. Please be more" " specific." % spec) if len(matches) == 1: return matches[0] matches = [] if len(matches) == 0: raise UserError("No bug matches %s" % spec) return matches[0] def bug_summary(bug, bugs, no_target=False, shortlist=False): info = [("ID", bug.uuid), ("Short name", unique_name(bug, bugs)), ("Severity", bug.severity), ("Status", bug.status), ("Assigned", bug.assigned), ("Target", bug.target), ("Creator", bug.creator), ("Created", "%s (%s)" % (utility.handy_time(bug.time),utility.time_to_str(bug.time)))] newinfo = [] for k,v in info: if v == None: newinfo.append((k,"")) else: newinfo.append((k,v)) info = newinfo if shortlist == False: longest_key_len = max([len(k) for k,v in info]) infolines = [" %*s : %s\n" % (longest_key_len,k,v) for k,v in info] return "".join(infolines) + "%s\n" % bug.summary else: return "%s: %s\n" % (unique_name(bug, bugs), bug.summary) def iter_commands(): for name, module in plugin.iter_plugins("becommands"): yield name.replace("_", "-"), module def get_command(command_name): """Retrieves the module for a user command >>> get_command("asdf") Traceback (most recent call last): UserError: Unknown command asdf >>> repr(get_command("list")).startswith("> s, "--------- Comment ---------" print >> s, "Name: %s" % name_map[comment.uuid] print >> s, "From: %s" % comment.From print >> s, "Date: %s\n" % utility.time_to_str(comment.time) print >> s, comment.body.rstrip('\n') s.seek(0) for line in s: print tw.fill(line).rstrip('\n') print_threaded_comments(children, name_map, indent=indent+" ") def bug_tree(dir=None): """Retrieve the bug tree specified by the user. If no directory is specified, the current working directory is used. :param dir: The directory to search for the bug tree in. >>> bug_tree() is not None True >>> bug_tree("/") Traceback (most recent call last): UserErrorWrap: The directory "/" has no bug directory. """ if dir is None: dir = os.getcwd() try: return bugdir.tree_root(dir) except bugdir.NoBugDir, e: raise UserErrorWrap(e) def print_command_list(): cmdlist = [] print """Bugs Everywhere - Distributed bug tracking Supported commands""" for name, module in iter_commands(): cmdlist.append((name, module.__doc__)) for name, desc in cmdlist: print "be %s\n %s" % (name, desc) def _test(): import doctest import sys doctest.testmod() if __name__ == "__main__": _test()