libbe.diff

Tools for comparing two BugDirs.

class libbe.diff.Diff(old_bugdir, new_bugdir)

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.
attribute_change_string(attribute_changes, indent=0)
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(attribute_changes)
comment_body_change_string(bodies)
comment_mod_string(comments)
comment_rem_string(comment)
full_report(diff_tree=<class 'libbe.diff.DiffTree'>)

Generate a full report for efficiency if you’ll be using .report_tree() with several sets of subscriptions.

report_tree(subscriptions=None, diff_tree=<class 'libbe.diff.DiffTree'>, allow_cached=True)

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.

class libbe.diff.DiffTree(name, data=None, data_part_fn=<type 'str'>, requires_children=False, masked=False)

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.
child_by_path(path)
data_part(depth, indent=True)
join(root, parent, data_part)
make_root()
paths(parent_path=None)
report(root=None, parent=None, depth=0)
report_string()
exception libbe.diff.InvalidType(type_name, type_root)
class libbe.diff.Subscription(id, subscription_type, **kwargs)

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)>]
class libbe.diff.SubscriptionType(type_name, *args, **kwargs)

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.
string_tree(indent=0)
libbe.diff.subscriptions_from_string(string=None, subscription_sep=', ', id_sep=':')

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
libbe.diff.type_from_name(name, type_root, default=None, default_ok=False)

This Page