Tools for comparing two libbe.bug.BugDirs.
Difference tree generator for BugDirs.
Examples
>>> import copy
>>> bd = libbe.bugdir.SimpleBugDir(memory=True)
>>> bd_new = copy.deepcopy(bd)
>>> bd_new.target = '1.0'
>>> a = bd_new.bug_from_uuid('a')
>>> rep = a.comment_root.new_reply("I'm closing this bug")
>>> rep.uuid = 'acom'
>>> rep.author = 'John Doe <j@doe.com>'
>>> rep.date = 'Thu, 01 Jan 1970 00:00:00 +0000'
>>> a.status = 'closed'
>>> b = bd_new.bug_from_uuid('b')
>>> bd_new.remove_bug(b)
>>> c = bd_new.new_bug('Bug C', _uuid='c')
>>> d = Diff(bd, bd_new)
>>> r = d.report_tree()
>>> print '\n'.join(r.paths())
bugdir
bugdir/settings
bugdir/bugs
bugdir/bugs/new
bugdir/bugs/new/c
bugdir/bugs/rem
bugdir/bugs/rem/b
bugdir/bugs/mod
bugdir/bugs/mod/a
bugdir/bugs/mod/a/settings
bugdir/bugs/mod/a/comments
bugdir/bugs/mod/a/comments/new
bugdir/bugs/mod/a/comments/new/acom
bugdir/bugs/mod/a/comments/rem
bugdir/bugs/mod/a/comments/mod
>>> print r.report_string()
Changed bug directory settings:
target: None -> 1.0
New bugs:
abc/c:om: Bug C
Removed bugs:
abc/b:cm: Bug B
Modified bugs:
abc/a:cm: Bug A
Changed bug settings:
status: open -> closed
New comments:
from John Doe <j@doe.com> on Thu, 01 Jan 1970 00:00:00 +0000
I'm closing this bug...
You can also limit the report generation by providing a list of subscriptions.
>>> subscriptions = [Subscription('DIR', BUGDIR_TYPE_NEW),
... Subscription('b', BUG_TYPE_ALL)]
>>> r = d.report_tree(subscriptions)
>>> print r.report_string()
New bugs:
abc/c:om: Bug C
Removed bugs:
abc/b:cm: Bug B
While sending subscriptions to report_tree() makes the report generation more efficient (because you may not need to compare _all_ the bugs, etc.), sometimes you will have several sets of subscriptions. In that case, it’s better to run full_report() first, and then use report_tree() to avoid redundant comparisons.
>>> d.full_report()
>>> print d.report_tree([subscriptions[0]]).report_string()
New bugs:
abc/c:om: Bug C
>>> print d.report_tree([subscriptions[1]]).report_string()
Removed bugs:
abc/b:cm: Bug B
>>> bd.cleanup()
Methods
attribute_change_string(attribute_changes[, ...]) | |
bug_add_string(bug) | |
bug_attribute_change_string(attribute_changes) | |
bug_mod_string(bugs) | |
bug_rem_string(bug) | |
bug_summary_change_string(summaries) | |
bugdir_attribute_change_string(attribute_changes) | |
comment_add_string(comment) | |
comment_attribute_change_string(...) | |
comment_body_change_string(bodies) | |
comment_mod_string(comments) | |
comment_rem_string(comment) | |
full_report([diff_tree]) | Generate a full report for efficiency if you’ll be using |
report_tree([subscriptions, diff_tree, ...]) | Pretty bare to make it easy to adjust to specific cases. |
Generate a full report for efficiency if you’ll be using .report_tree() with several sets of subscriptions.
Pretty bare to make it easy to adjust to specific cases. You can pass in a DiffTree subclass via diff_tree to override the default report assembly process.
A tree holding difference data for easy report generation.
Examples
>>> bugdir = DiffTree('bugdir')
>>> bdsettings = DiffTree('settings', data='target: None -> 1.0')
>>> bugdir.append(bdsettings)
>>> bugs = DiffTree('bugs', 'bug-count: 5 -> 6')
>>> bugdir.append(bugs)
>>> new = DiffTree('new', 'new bugs: ABC, DEF')
>>> bugs.append(new)
>>> rem = DiffTree('rem', 'removed bugs: RST, UVW')
>>> bugs.append(rem)
>>> print bugdir.report_string()
target: None -> 1.0
bug-count: 5 -> 6
new bugs: ABC, DEF
removed bugs: RST, UVW
>>> print '\n'.join(bugdir.paths())
bugdir
bugdir/settings
bugdir/bugs
bugdir/bugs/new
bugdir/bugs/rem
>>> bugdir.child_by_path('/') == bugdir
True
>>> bugdir.child_by_path('/bugs') == bugs
True
>>> bugdir.child_by_path('/bugs/rem') == rem
True
>>> bugdir.child_by_path('bugdir') == bugdir
True
>>> bugdir.child_by_path('bugdir/') == bugdir
True
>>> bugdir.child_by_path('bugdir/bugs') == bugs
True
>>> bugdir.child_by_path('/bugs').masked = True
>>> print bugdir.report_string()
target: None -> 1.0
Methods
append | L.append(object) – append object to end |
branch_len() | Return the largest number of nodes from root to leaf (inclusive). |
child_by_path(path) | |
count(...) | |
data_part(depth[, indent]) | |
extend | L.extend(iterable) – extend list by appending elements from the iterable |
has_descendant(descendant[, depth_first, ...]) | Check if a node is contained in a tree. |
index((value, [start, ...) | Raises ValueError if the value is not present. |
insert | L.insert(index, object) – insert object before index |
join(root, parent, data_part) | |
make_root() | |
paths([parent_path]) | |
pop(...) | Raises IndexError if list is empty or index is out of range. |
remove | L.remove(value) – remove first occurrence of value. |
report([root, parent, depth]) | |
report_string() | |
reverse | L.reverse() – reverse IN PLACE |
sort(*args, **kwargs) | Sort the tree recursively. |
thread([flatten]) | Generate a (depth, node) tuple for every node in the tree. |
traverse([depth_first]) | Generate all the nodes in a tree, starting with the root node. |
A user subscription.
Examples
>>> subscriptions = [Subscription('XYZ', 'all'),
... Subscription('DIR', 'new'),
... Subscription('ABC', BUG_TYPE_ALL),]
>>> print sorted(subscriptions)
[<Subscription: DIR (new)>, <Subscription: ABC (all)>, <Subscription: XYZ (all)>]
Trees of subscription types to allow users to select exactly what notifications they want to subscribe to.
Methods
append | L.append(object) – append object to end |
branch_len() | Return the largest number of nodes from root to leaf (inclusive). |
count(...) | |
extend | L.extend(iterable) – extend list by appending elements from the iterable |
has_descendant(descendant[, depth_first, ...]) | Check if a node is contained in a tree. |
index((value, [start, ...) | Raises ValueError if the value is not present. |
insert | L.insert(index, object) – insert object before index |
pop(...) | Raises IndexError if list is empty or index is out of range. |
remove | L.remove(value) – remove first occurrence of value. |
reverse | L.reverse() – reverse IN PLACE |
sort(*args, **kwargs) | Sort the tree recursively. |
string_tree([indent]) | |
thread([flatten]) | Generate a (depth, node) tuple for every node in the tree. |
traverse([depth_first]) | Generate all the nodes in a tree, starting with the root node. |
Provide a simple way for non-Python interfaces to read in subscriptions.
Examples
>>> subscriptions_from_string(None)
[<Subscription: DIR (all)>]
>>> subscriptions_from_string('DIR:new,DIR:rem,ABC:all,XYZ:all')
[<Subscription: DIR (new)>, <Subscription: DIR (rem)>, <Subscription: ABC (all)>, <Subscription: XYZ (all)>]
>>> subscriptions_from_string('DIR::new')
Traceback (most recent call last):
...
ValueError: Invalid subscription "DIR::new", should be ID:TYPE