diff options
author | Chris Ball <cjb@laptop.org> | 2009-10-05 23:15:39 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2009-10-05 23:15:39 -0400 |
commit | b6a50c703369467132876f21efa8e4ffc672afae (patch) | |
tree | 905a9ae34efa2bce47d754893093b016d18d0162 /libbe/bug.py | |
parent | 6a639574fa95e50f82fa3052e5524b961295a7ab (diff) | |
parent | e35ccf95ea89b6e622202caae30d3b8cca3f2473 (diff) | |
download | bugseverywhere-b6a50c703369467132876f21efa8e4ffc672afae.tar.gz |
Large merge from W. Trevor King, including Gianluca's HTML export.
Diffstat (limited to 'libbe/bug.py')
-rw-r--r-- | libbe/bug.py | 117 |
1 files changed, 75 insertions, 42 deletions
diff --git a/libbe/bug.py b/libbe/bug.py index c1e5481..fd30ff7 100644 --- a/libbe/bug.py +++ b/libbe/bug.py @@ -15,6 +15,11 @@ # 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. + +""" +Define the Bug class for representing bugs. +""" + import os import os.path import errno @@ -33,6 +38,11 @@ import comment import utility +class DiskAccessRequired (Exception): + def __init__(self, goal): + msg = "Cannot %s without accessing the disk" % goal + Exception.__init__(self, msg) + ### Define and describe valid bug categories # Use a tuple of (category, description) tuples since we don't have # ordered dicts in Python yet http://www.python.org/dev/peps/pep-0372/ @@ -216,15 +226,15 @@ class Bug(settings_object.SavedSettingsObject): @doc_property(doc="The trunk of the comment tree") def comment_root(): return {} - def _get_rcs(self): - if hasattr(self.bugdir, "rcs"): - return self.bugdir.rcs + def _get_vcs(self): + if hasattr(self.bugdir, "vcs"): + return self.bugdir.vcs @Property - @cached_property(generator=_get_rcs) - @local_property("rcs") + @cached_property(generator=_get_vcs) + @local_property("vcs") @doc_property(doc="A revision control system instance.") - def rcs(): return {} + def vcs(): return {} def __init__(self, bugdir=None, uuid=None, from_disk=False, load_comments=False, summary=None): @@ -238,17 +248,20 @@ class Bug(settings_object.SavedSettingsObject): if uuid == None: self.uuid = uuid_gen() self.time = int(time.time()) # only save to second precision - if self.rcs != None: - self.creator = self.rcs.get_user_id() + if self.vcs != None: + self.creator = self.vcs.get_user_id() self.summary = summary def __repr__(self): return "Bug(uuid=%r)" % self.uuid - def set_sync_with_disk(self, value): - self.sync_with_disk = value - for comment in self.comments(): - comment.set_sync_with_disk(value) + def __str__(self): + return self.string(shortlist=True) + + def __cmp__(self, other): + return cmp_full(self, other) + + # serializing methods def _setting_attr_string(self, setting): value = getattr(self, setting) @@ -331,43 +344,34 @@ class Bug(settings_object.SavedSettingsObject): output = bugout return output - def __str__(self): - return self.string(shortlist=True) + # methods for saving/loading/acessing settings and properties. - def __cmp__(self, other): - return cmp_full(self, other) + def get_path(self, *args): + dir = os.path.join(self.bugdir.get_path("bugs"), self.uuid) + if len(args) == 0: + return dir + assert args[0] in ["values", "comments"], str(args) + return os.path.join(dir, *args) - def get_path(self, name=None): - my_dir = os.path.join(self.bugdir.get_path("bugs"), self.uuid) - if name is None: - return my_dir - assert name in ["values", "comments"] - return os.path.join(my_dir, name) + def set_sync_with_disk(self, value): + self.sync_with_disk = value + for comment in self.comments(): + comment.set_sync_with_disk(value) def load_settings(self): - self.settings = mapfile.map_load(self.rcs, self.get_path("values")) + if self.sync_with_disk == False: + raise DiskAccessRequired("load settings") + self.settings = mapfile.map_load(self.vcs, self.get_path("values")) self._setup_saved_settings() - def load_comments(self, load_full=True): - if load_full == True: - # Force a complete load of the whole comment tree - self.comment_root = self._get_comment_root(load_full=True) - else: - # Setup for fresh lazy-loading. Clear _comment_root, so - # _get_comment_root returns a fresh version. Turn of - # syncing temporarily so we don't write our blank comment - # tree to disk. - self.sync_with_disk = False - self.comment_root = None - self.sync_with_disk = True - def save_settings(self): + if self.sync_with_disk == False: + raise DiskAccessRequired("save settings") assert self.summary != None, "Can't save blank bug" - - self.rcs.mkdir(self.get_path()) + self.vcs.mkdir(self.get_path()) path = self.get_path("values") - mapfile.map_save(self.rcs, path, self._get_saved_settings()) - + mapfile.map_save(self.vcs, path, self._get_saved_settings()) + def save(self): """ Save any loaded contents to disk. Because of lazy loading of @@ -378,15 +382,39 @@ class Bug(settings_object.SavedSettingsObject): calling this method will just waste time (unless something else has been messing with your on-disk files). """ + sync_with_disk = self.sync_with_disk + if sync_with_disk == False: + self.set_sync_with_disk(True) self.save_settings() if len(self.comment_root) > 0: comment.saveComments(self) + if sync_with_disk == False: + self.set_sync_with_disk(False) + + def load_comments(self, load_full=True): + if self.sync_with_disk == False: + raise DiskAccessRequired("load comments") + if load_full == True: + # Force a complete load of the whole comment tree + self.comment_root = self._get_comment_root(load_full=True) + else: + # Setup for fresh lazy-loading. Clear _comment_root, so + # _get_comment_root returns a fresh version. Turn of + # syncing temporarily so we don't write our blank comment + # tree to disk. + self.sync_with_disk = False + self.comment_root = None + self.sync_with_disk = True def remove(self): + if self.sync_with_disk == False: + raise DiskAccessRequired("remove") self.comment_root.remove() path = self.get_path() - self.rcs.recursive_remove(path) + self.vcs.recursive_remove(path) + # methods for managing comments + def comments(self): for comment in self.comment_root.traverse(): yield comment @@ -489,8 +517,12 @@ def cmp_attr(bug_1, bug_2, attr, invert=False): return cmp(val_1, val_2) # alphabetical rankings (a < z) +cmp_uuid = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "uuid") cmp_creator = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "creator") cmp_assigned = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "assigned") +cmp_target = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "target") +cmp_reporter = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "reporter") +cmp_summary = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "summary") # chronological rankings (newer < older) cmp_time = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "time", invert=True) @@ -512,7 +544,8 @@ def cmp_comments(bug_1, bug_2): return 0 DEFAULT_CMP_FULL_CMP_LIST = \ - (cmp_status,cmp_severity,cmp_assigned,cmp_time,cmp_creator,cmp_comments) + (cmp_status, cmp_severity, cmp_assigned, cmp_time, cmp_creator, + cmp_reporter, cmp_target, cmp_comments, cmp_summary, cmp_uuid) class BugCompoundComparator (object): def __init__(self, cmp_list=DEFAULT_CMP_FULL_CMP_LIST): |