diff options
Diffstat (limited to 'libbe')
-rw-r--r-- | libbe/bug.py | 13 | ||||
-rw-r--r-- | libbe/cmdutil.py | 53 | ||||
-rw-r--r-- | libbe/upgrade.py | 60 |
3 files changed, 114 insertions, 12 deletions
diff --git a/libbe/bug.py b/libbe/bug.py index 1a190c3..06c2cc5 100644 --- a/libbe/bug.py +++ b/libbe/bug.py @@ -56,6 +56,7 @@ class DiskAccessRequired (Exception): # in order of increasing severity. (name, description) pairs severity_def = ( + ("target", "The issue is a target or milestone, not a bug."), ("wishlist","A feature that could improve usefulness, but not a bug."), ("minor","The standard bug level."), ("serious","A bug that requires workarounds."), @@ -173,10 +174,6 @@ class Bug(settings_object.SavedSettingsObject): def active(self): return self.status in active_status_values - @_versioned_property(name="target", - doc="The deadline for fixing this bug") - def target(): return {} - @_versioned_property(name="creator", doc="The user who entered the bug into the system") def creator(): return {} @@ -295,7 +292,6 @@ class Bug(settings_object.SavedSettingsObject): ('severity', self.severity), ('status', self.status), ('assigned', self.assigned), - ('target', self.target), ('reporter', self.reporter), ('creator', self.creator), ('created', timestring), @@ -352,7 +348,7 @@ class Bug(settings_object.SavedSettingsObject): if bug.tag != 'bug': raise utility.InvalidXML( \ 'bug', bug, 'root element must be <comment>') - tags=['uuid','short-name','severity','status','assigned','target', + tags=['uuid','short-name','severity','status','assigned', 'reporter', 'creator','created','summary','extra-string'] self.explicit_attrs = [] uuid = None @@ -620,7 +616,6 @@ class Bug(settings_object.SavedSettingsObject): ("Severity", self.severity), ("Status", self.status), ("Assigned", self._setting_attr_string("assigned")), - ("Target", self._setting_attr_string("target")), ("Reporter", self._setting_attr_string("reporter")), ("Creator", self._setting_attr_string("creator")), ("Created", timestring)] @@ -820,7 +815,6 @@ def cmp_attr(bug_1, bug_2, attr, invert=False): 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") cmp_extra_strings = lambda bug_1, bug_2 : cmp_attr(bug_1, bug_2, "extra_strings") @@ -846,8 +840,7 @@ def cmp_comments(bug_1, bug_2): DEFAULT_CMP_FULL_CMP_LIST = \ (cmp_status, cmp_severity, cmp_assigned, cmp_time, cmp_creator, - cmp_reporter, cmp_target, cmp_comments, cmp_summary, cmp_uuid, - cmp_extra_strings) + cmp_reporter, cmp_comments, cmp_summary, cmp_uuid, cmp_extra_strings) class BugCompoundComparator (object): def __init__(self, cmp_list=DEFAULT_CMP_FULL_CMP_LIST): diff --git a/libbe/cmdutil.py b/libbe/cmdutil.py index dcd4ca9..b892bde 100644 --- a/libbe/cmdutil.py +++ b/libbe/cmdutil.py @@ -217,6 +217,59 @@ def underlined(instring): return "%s\n%s" % (instring, "="*len(instring)) +def select_values(string, possible_values, name="unkown"): + """ + This function allows the user to select values from a list of + possible values. The default is to select all the values: + + >>> select_values(None, ['abc', 'def', 'hij']) + ['abc', 'def', 'hij'] + + The user selects values with a comma-separated limit_string. + Prepending a minus sign to such a list denotes blacklist mode: + + >>> select_values('-abc,hij', ['abc', 'def', 'hij']) + ['def'] + + Without the leading -, the selection is in whitelist mode: + + >>> select_values('abc,hij', ['abc', 'def', 'hij']) + ['abc', 'hij'] + + In either case, appropriate errors are raised if on of the + user-values is not in the list of possible values. The name + parameter lets you make the error message more clear: + + >>> select_values('-xyz,hij', ['abc', 'def', 'hij'], name="foobar") + Traceback (most recent call last): + ... + UserError: Invalid foobar xyz + ['abc', 'def', 'hij'] + >>> select_values('xyz,hij', ['abc', 'def', 'hij'], name="foobar") + Traceback (most recent call last): + ... + UserError: Invalid foobar xyz + ['abc', 'def', 'hij'] + """ + possible_values = list(possible_values) # don't alter the original + if string == None: + pass + elif string.startswith('-'): + blacklisted_values = set(string[1:].split(',')) + for value in blacklisted_values: + if value not in possible_values: + raise UserError('Invalid %s %s\n %s' + % (name, value, possible_values)) + possible_values.remove(value) + else: + whitelisted_values = string.split(',') + for value in whitelisted_values: + if value not in possible_values: + raise UserError('Invalid %s %s\n %s' + % (name, value, possible_values)) + possible_values = whitelisted_values + return possible_values + def restrict_file_access(bugdir, path): """ Check that the file at path is inside bugdir.root. This is diff --git a/libbe/upgrade.py b/libbe/upgrade.py index 785249d..dc9d54f 100644 --- a/libbe/upgrade.py +++ b/libbe/upgrade.py @@ -22,6 +22,7 @@ import os, os.path import sys import libbe +import bug import encoding import mapfile import vcs @@ -31,7 +32,8 @@ if libbe.TESTING == True: # a list of all past versions BUGDIR_DISK_VERSIONS = ["Bugs Everywhere Tree 1 0", "Bugs Everywhere Directory v1.1", - "Bugs Everywhere Directory v1.2"] + "Bugs Everywhere Directory v1.2", + "Bugs Everywhere Directory v1.3"] # the current version BUGDIR_DISK_VERSION = BUGDIR_DISK_VERSIONS[-1] @@ -142,9 +144,63 @@ class Upgrade_1_1_to_1_2 (Upgrader): settings["vcs_name"] = settings.pop("rcs_name") mapfile.map_save(self.vcs, path, settings) +class Upgrade_1_2_to_1_3 (Upgrader): + initial_version = "Bugs Everywhere Directory v1.2" + final_version = "Bugs Everywhere Directory v1.3" + def __init__(self, *args, **kwargs): + Upgrader.__init__(self, *args, **kwargs) + self._targets = {} # key: target text,value: new target bug + path = self.get_path('settings') + settings = mapfile.map_load(self.vcs, path) + if 'vcs_name' in settings: + old_vcs = self.vcs + self.vcs = vcs.vcs_by_name(settings['vcs_name']) + self.vcs.root(self.root) + self.vcs.encoding = old_vcs.encoding + + def _target_bug(self, target_text): + if target_text not in self._targets: + _bug = bug.Bug(bugdir=self, summary=target_text) + # note: we're not a bugdir, but all Bug.save() needs is + # .root, .vcs, and .get_path(), which we have. + _bug.severity = 'target' + self._targets[target_text] = _bug + return self._targets[target_text] + + def _upgrade_bugdir_mapfile(self): + path = self.get_path('settings') + settings = mapfile.map_load(self.vcs, path) + if 'target' in settings: + settings['target'] = self._target_bug(settings['target']).uuid + mapfile.map_save(self.vcs, path, settings) + + def _upgrade_bug_mapfile(self, bug_uuid): + import becommands.depend + path = self.get_path('bugs', bug_uuid, 'values') + settings = mapfile.map_load(self.vcs, path) + if 'target' in settings: + target_bug = self._target_bug(settings['target']) + _bug = bug.Bug(bugdir=self, uuid=bug_uuid, from_disk=True) + # note: we're not a bugdir, but all Bug.load_settings() + # needs is .root, .vcs, and .get_path(), which we have. + becommands.depend.add_block(target_bug, _bug) + _bug.settings.pop('target') + _bug.save() + + def _upgrade(self): + """ + Bug value field "target" -> target bugs. + Bugdir value field "target" -> pointer to current target bug. + """ + for bug_uuid in os.listdir(self.get_path('bugs')): + self._upgrade_bug_mapfile(bug_uuid) + self._upgrade_bugdir_mapfile() + for _bug in self._targets.values(): + _bug.save() upgraders = [Upgrade_1_0_to_1_1, - Upgrade_1_1_to_1_2] + Upgrade_1_1_to_1_2, + Upgrade_1_2_to_1_3] upgrade_classes = {} for upgrader in upgraders: upgrade_classes[(upgrader.initial_version,upgrader.final_version)]=upgrader |