-# Copyright (C) 2009-2010 Gianluca Montecchi <gian@grys.it>
+# Copyright (C) 2009-2011 Gianluca Montecchi <gian@grys.it>
# W. Trevor King <wking@drexel.edu>
#
# This file is part of Bugs Everywhere.
BLOCKS_TAG="BLOCKS:"
BLOCKED_BY_TAG="BLOCKED-BY:"
+
+class Filter (object):
+ def __init__(self, status='all', severity='all', assigned='all',
+ target='all', extra_strings_regexps=[]):
+ self.status = status
+ self.severity = severity
+ self.assigned = assigned
+ self.target = target
+ self.extra_strings_regexps = extra_strings_regexps
+
+ def __call__(self, bugdir, bug):
+ if self.status != 'all' and not bug.status in self.status:
+ return False
+ if self.severity != 'all' and not bug.severity in self.severity:
+ return False
+ if self.assigned != 'all' and not bug.assigned in self.assigned:
+ return False
+ if self.target == 'all':
+ pass
+ else:
+ target_bug = libbe.command.target.bug_target(bugdir, bug)
+ if self.target in ['none', None]:
+ if target_bug.summary != None:
+ return False
+ else:
+ if target_bug.summary != self.target:
+ return False
+ if len(bug.extra_strings) == 0:
+ if len(self.extra_strings_regexps) > 0:
+ return False
+ elif len(self.extra_strings_regexps) > 0:
+ matched = False
+ for string in bug.extra_strings:
+ for regexp in self.extra_strings_regexps:
+ if regexp.match(string):
+ matched = True
+ break
+ if matched == True:
+ break
+ if matched == False:
+ return False
+ return True
+
+def parse_status(status):
+ if status == 'all':
+ status = libbe.bug.status_values
+ elif status == 'active':
+ status = list(libbe.bug.active_status_values)
+ elif status == 'inactive':
+ status = list(libbe.bug.inactive_status_values)
+ else:
+ status = libbe.command.util.select_values(
+ status, libbe.bug.status_values)
+ return status
+
+def parse_severity(severity, important=False):
+ if severity == 'all':
+ severity = libbe.bug.severity_values
+ elif important == True:
+ serious = libbe.bug.severity_values.index('serious')
+ severity.append(list(libbe.bug.severity_values[serious:]))
+ else:
+ severity = libbe.command.util.select_values(
+ severity, libbe.bug.severity_values)
+ return severity
+
+
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)
+ % (blocking_bug.id.user(), blocked_bug.id.user())
else:
msg = "Missing link: %s blocked by %s" \
- % (blocked_bug.uuid, blocking_bug.uuid)
+ % (blocked_bug.id.user(), blocking_bug.id.user())
Exception.__init__(self, msg)
self.blocked_bug = blocked_bug
self.blocking_bug = blocking_bug
>>> cmd = Depend(ui=ui)
>>> ret = ui.run(cmd, args=['/a', '/b'])
- a blocked by:
- b
+ abc/a blocked by:
+ abc/b
>>> ret = ui.run(cmd, args=['/a'])
- a blocked by:
- b
+ abc/a blocked by:
+ abc/b
>>> ret = ui.run(cmd, {'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
- a blocked by:
- b closed
+ abc/a blocked by:
+ abc/b closed
>>> ret = ui.run(cmd, args=['/b', '/a'])
- b blocked by:
- a
- b blocks:
- a
+ abc/b blocked by:
+ abc/a
+ abc/b blocks:
+ abc/a
>>> ret = ui.run(cmd, {'show-status':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
- a blocked by:
- b closed
- a blocks:
- b closed
+ abc/a blocked by:
+ abc/b closed
+ abc/a blocks:
+ abc/b closed
+ >>> ret = ui.run(cmd, {'show-summary':True}, ['/a']) # doctest: +NORMALIZE_WHITESPACE
+ abc/a blocked by:
+ abc/b Bug B
+ abc/a blocks:
+ abc/b Bug B
>>> ret = ui.run(cmd, {'repair':True})
>>> ret = ui.run(cmd, {'remove':True}, ['/b', '/a'])
- b blocks:
- a
+ abc/b blocks:
+ abc/a
>>> ret = ui.run(cmd, {'remove':True}, ['/a', '/b'])
>>> ui.cleanup()
>>> bd.cleanup()
help='Remove dependency (instead of adding it)'),
libbe.command.Option(name='show-status', short_name='s',
help='Show status of blocking bugs'),
+ libbe.command.Option(name='show-summary', short_name='S',
+ help='Show summary of blocking bugs'),
libbe.command.Option(name='status',
help='Only show bugs matching the STATUS specifier',
arg=libbe.command.Argument(
def _run(self, **params):
if params['repair'] == True and params['bug-id'] != None:
- raise libbe.command.UsageError(
+ raise libbe.command.UserError(
'No arguments with --repair calls.')
if params['repair'] == False and params['bug-id'] == None:
- raise libbe.command.UsageError(
+ raise libbe.command.UserError(
'Must specify either --repair or a BUG-ID')
if params['tree-depth'] != None \
and params['blocking-bug-id'] != None:
- raise libbe.command.UsageError(
+ raise libbe.command.UserError(
'Only one bug id used in tree mode.')
bugdir = self._get_bugdir()
if params['repair'] == True:
if len(fixed) > 0:
print >> self.stdout, 'Fixed the following links:'
print >> self.stdout, \
- '\n'.join(['%s |-- %s' % (blockee.uuid, blocker.uuid)
+ '\n'.join(['%s |-- %s' % (blockee.id.user(), blocker.id.user())
for blockee,blocker in fixed])
return 0
- allowed_status_values = \
- libbe.command.util.select_values(
- params['status'], libbe.bug.status_values)
- allowed_severity_values = \
- libbe.command.util.select_values(
- params['severity'], libbe.bug.severity_values)
+ status = parse_status(params['status'])
+ severity = parse_severity(params['severity'])
+ filter = Filter(status, severity)
bugA, dummy_comment = libbe.command.util.bug_comment_from_user_id(
bugdir, params['bug-id'])
if params['tree-depth'] != None:
- dtree = DependencyTree(bugdir, bugA, params['tree-depth'],
- allowed_status_values,
- allowed_severity_values)
+ dtree = DependencyTree(bugdir, bugA, params['tree-depth'], filter)
if len(dtree.blocked_by_tree()) > 0:
- print >> self.stdout, '%s blocked by:' % bugA.uuid
+ print >> self.stdout, '%s blocked by:' % bugA.id.user()
for depth,node in dtree.blocked_by_tree().thread():
if depth == 0: continue
- print >> self.stdout, \
- '%s%s' % (' '*(depth),
- node.bug.string(shortlist=True))
+ print >> self.stdout, (
+ '%s%s'
+ % (' '*(depth), self.bug_string(node.bug, params)))
if len(dtree.blocks_tree()) > 0:
- print >> self.stdout, '%s blocks:' % bugA.uuid
+ print >> self.stdout, '%s blocks:' % bugA.id.user()
for depth,node in dtree.blocks_tree().thread():
if depth == 0: continue
- print >> self.stdout, \
- '%s%s' % (' '*(depth),
- node.bug.string(shortlist=True))
+ print >> self.stdout, (
+ '%s%s'
+ % (' '*(depth), self.bug_string(node.bug, params)))
return 0
if params['blocking-bug-id'] != None:
add_block(bugA, bugB)
blocked_by = get_blocked_by(bugdir, bugA)
+
if len(blocked_by) > 0:
- print >> self.stdout, '%s blocked by:' % bugA.uuid
- if params['show-status'] == True:
- print >> self.stdout, \
- '\n'.join(['%s\t%s' % (_bug.uuid, _bug.status)
- for _bug in blocked_by])
- else:
- print >> self.stdout, \
- '\n'.join([_bug.uuid for _bug in blocked_by])
+ print >> self.stdout, '%s blocked by:' % bugA.id.user()
+ print >> self.stdout, \
+ '\n'.join([self.bug_string(_bug, params)
+ for _bug in blocked_by])
blocks = get_blocks(bugdir, bugA)
if len(blocks) > 0:
- print >> self.stdout, '%s blocks:' % bugA.uuid
- if params['show-status'] == True:
- print >> self.stdout, \
- '\n'.join(['%s\t%s' % (_bug.uuid, _bug.status)
- for _bug in blocks])
- else:
- print >> self.stdout, \
- '\n'.join([_bug.uuid for _bug in blocks])
+ print >> self.stdout, '%s blocks:' % bugA.id.user()
+ print >> self.stdout, \
+ '\n'.join([self.bug_string(_bug, params)
+ for _bug in blocks])
return 0
+ def bug_string(self, _bug, params):
+ fields = [_bug.id.user()]
+ if params['show-status'] == True:
+ fields.append(_bug.status)
+ if params['show-summary'] == True:
+ fields.append(_bug.summary)
+ return '\t'.join(fields)
+
def _long_help(self):
return """
Set a dependency with the second bug (B) blocking the first bug (A).
"""
Note: should probably be DependencyDiGraph.
"""
- def __init__(self, bugdir, root_bug, depth_limit=0,
- allowed_status_values=None,
- allowed_severity_values=None):
+ def __init__(self, bugdir, root_bug, depth_limit=0, filter=None):
self.bugdir = bugdir
self.root_bug = root_bug
self.depth_limit = depth_limit
- self.allowed_status_values = allowed_status_values
- self.allowed_severity_values = allowed_severity_values
+ self.filter = filter
def _build_tree(self, child_fn):
- root = tree.Tree()
+ root = libbe.util.tree.Tree()
root.bug = self.root_bug
root.depth = 0
stack = [root]
if self.depth_limit > 0 and node.depth == self.depth_limit:
continue
for bug in child_fn(self.bugdir, node.bug):
- if self.allowed_status_values != None \
- and not bug.status in self.allowed_status_values:
- continue
- if self.allowed_severity_values != None \
- and not bug.severity in self.allowed_severity_values:
+ if not self.filter(self.bugdir, bug):
continue
- child = tree.Tree()
+ child = libbe.util.tree.Tree()
child.bug = bug
child.depth = node.depth+1
node.append(child)