aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Bentley <abentley@panoramicfeedback.com>2005-04-14 18:07:49 +0000
committerAaron Bentley <abentley@panoramicfeedback.com>2005-04-14 18:07:49 +0000
commit16a391aaf9d3934f7297b7a8fb87184cf555882f (patch)
treeb016864fd16dcbaaba1ab09ec0a6668dddcaa60b
parent82c1e85e1845d33b8e552c9f832f91d032466036 (diff)
downloadbugseverywhere-16a391aaf9d3934f7297b7a8fb87184cf555882f.tar.gz
Added preliminary tree-diffing support
-rw-r--r--becommands/diff.py35
-rw-r--r--becommands/template21
-rw-r--r--libbe/arch.py23
-rw-r--r--libbe/bugdir.py9
-rw-r--r--libbe/diff.py52
-rw-r--r--libbe/template48
6 files changed, 182 insertions, 6 deletions
diff --git a/becommands/diff.py b/becommands/diff.py
new file mode 100644
index 0000000..bf8b66d
--- /dev/null
+++ b/becommands/diff.py
@@ -0,0 +1,35 @@
+# This is the standard command template. To use it, please fill in values for
+# Short description, long help and COMMANDSPEC
+#
+"""Compare bug reports with older tree"""
+from libbe import bugdir, diff, cmdutil
+import os
+def execute(args):
+ options, args = get_parser().parse_args(args)
+ if len(args) == 0:
+ spec = None
+ elif len(args) == 1:
+ spec = args[0]
+ else:
+ raise cmdutil.UsageError
+ tree = bugdir.tree_root(".")
+ if tree.rcs_name == "None":
+ print "This directory is not revision-controlled."
+ else:
+ diff.diff_report(diff.reference_diff(tree, spec), tree)
+
+
+def get_parser():
+ parser = cmdutil.CmdOptionParser("be diff [specifier]")
+ return parser
+
+longhelp="""
+Uses the RCS to compare the current tree with a previous tree, and prints
+a pretty report. If specifier is given, it is a specifier for the particular
+previous tree to use. Specifiers are specific to their RCS.
+
+For Arch: a fully-qualified revision name
+"""
+
+def help():
+ return get_parser().help_str() + longhelp
diff --git a/becommands/template b/becommands/template
new file mode 100644
index 0000000..3c871e6
--- /dev/null
+++ b/becommands/template
@@ -0,0 +1,21 @@
+"""Short description"""
+from libbe import bugdir, cmdutil, names
+import os
+def execute(args):
+ options, args = get_parser().parse_args(args)
+ if len(args) > 0:
+ raise cmdutil.UsageError
+
+
+def get_parser():
+ parser = cmdutil.CmdOptionParser("be list [options]")
+# parser.add_option("-w", "--wishlist", action="store_true", dest="wishlist",
+# help="List bugs with 'wishlist' severity")
+ return parser
+
+longhelp="""
+This is for the longwinded description
+"""
+
+def help():
+ return get_parser().help_str() + longhelp
diff --git a/libbe/arch.py b/libbe/arch.py
index 7e1cd1f..21a6809 100644
--- a/libbe/arch.py
+++ b/libbe/arch.py
@@ -1,4 +1,4 @@
-from popen2 import Popen4
+from popen2 import Popen3
import os
import config
client = config.get_val("arch_client")
@@ -7,17 +7,21 @@ if client is None:
config.set_val("arch_client", client)
def invoke(args):
- q=Popen4(args)
+ q=Popen3(args, True)
output = q.fromchild.read()
+ error = q.childerr.read()
status = q.wait()
if os.WIFEXITED(status):
- return os.WEXITSTATUS(status)
- raise Exception("Command failed")
+ return os.WEXITSTATUS(status), output, error
+ raise Exception("Command failed: %s" % error)
def invoke_client(*args, **kwargs):
- status = invoke((client,) + args)
+ cl_args = [client]
+ cl_args.extend(args)
+ status,output,error = invoke(cl_args)
if status not in (0,):
- raise Exception("Command failed")
+ raise Exception("Command failed: %s" % error)
+ return output
def add_id(filename):
invoke_client("add-id", filename)
@@ -35,6 +39,13 @@ def set_file_contents(path, contents):
if add:
add_id(path)
+
+def path_in_reference(bug_dir, spec):
+ if spec is not None:
+ return invoke_client("file-find", bug_dir, spec).rstrip('\n')
+ return invoke_client("file-find", bug_dir).rstrip('\n')
+
+
def unlink(path):
try:
os.unlink(path)
diff --git a/libbe/bugdir.py b/libbe/bugdir.py
index 16c1544..8583b68 100644
--- a/libbe/bugdir.py
+++ b/libbe/bugdir.py
@@ -98,10 +98,19 @@ class BugDir:
rcs = property(get_rcs)
+ def get_reference_bugdir(self, spec):
+ return BugDir(self.rcs.path_in_reference(self.dir, spec))
+
def list(self):
for uuid in self.list_uuids():
yield self.get_bug(uuid)
+ def bug_map(self):
+ bugs = {}
+ for bug in self.list():
+ bugs[bug.uuid] = bug
+ return bugs
+
def get_bug(self, uuid):
return Bug(self.bugs_path, uuid, self.rcs_name)
diff --git a/libbe/diff.py b/libbe/diff.py
new file mode 100644
index 0000000..3c348a0
--- /dev/null
+++ b/libbe/diff.py
@@ -0,0 +1,52 @@
+"""Compare two bug trees"""
+from libbe import cmdutil, bugdir
+
+def diff(old_tree, new_tree):
+ old_bug_map = old_tree.bug_map()
+ new_bug_map = new_tree.bug_map()
+ added = []
+ removed = []
+ modified = []
+ for old_bug in old_bug_map.itervalues():
+ new_bug = new_bug_map.get(old_bug.uuid)
+ if new_bug is None :
+ removed.append(old_bug)
+ else:
+ if old_bug != new_bug:
+ modified.append((old_bug, new_bug))
+ for new_bug in new_bug_map.itervalues():
+ if not old_bug_map.has_key(new_bug.uuid):
+ added.append(new_bug)
+ return (removed, modified, added)
+
+
+def reference_diff(bugdir, spec=None):
+ return diff(bugdir.get_reference_bugdir(spec), bugdir)
+
+def diff_report(diff_data, bug_dir):
+ (removed, modified, added) = diff_data
+ bugs = list(bug_dir.list())
+ def modified_cmp(left, right):
+ return bugdir.cmp_severity(left[1], right[1])
+
+ added.sort(bugdir.cmp_severity)
+ removed.sort(bugdir.cmp_severity)
+ modified.sort(modified_cmp)
+
+ if len(added) > 0:
+ print "New bug reports:"
+ for bug in added:
+ print cmdutil.bug_summary(bug, bugs, no_target=True)
+
+ if len(modified) > 0 and False:
+ print "modified bug reports:"
+ for old_bug, new_bug in modified:
+ print cmdutil.bug_summary(new_bug, bugs, no_target=True)
+
+ if len(removed) > 0:
+ print "Removed bug reports:"
+ for bug in removed:
+ print cmdutil.bug_summary(bug, bugs, no_target=True)
+
+
+
diff --git a/libbe/template b/libbe/template
new file mode 100644
index 0000000..467eee4
--- /dev/null
+++ b/libbe/template
@@ -0,0 +1,48 @@
+"""Compare two bug trees"""
+from bugdir import cmdutil
+
+def diff(old_tree, new_tree):
+ old_bug_map = old_tree.bug_map()
+ new_bug_map = new_tree.bug_map()
+ added = []
+ removed = []
+ modified = []
+ for old_bug in old_bug_map.itervalues():
+ new_bug = new_bug_map.get(bug.uuid)
+ if new_bug is None :
+ removed.append(old_bug)
+ else:
+ if old_bug != new_bug:
+ modified.append((old_bug, new_bug))
+ for new_bug in new_bug_map.itervalues():
+ if not old_bug_map.haskey(new_bug.id):
+ added.append(new_bug)
+ return (removed, modified, added)
+
+
+def reference_diff(bugdir, spec=None):
+ return diff(bugdir.reference_bugdir(), bugdir)
+
+def diff_report(diff_data, bugdir)
+ (removed, modified, added) = diff_data
+ def modified_cmp(left, right):
+ return cmp_severity(left[1], right[1])
+
+ added.sort(bugdir.cmp_severity)
+ removed.sort(bugdir.cmp_severity)
+ modified.sort(modified_cmp)
+
+ print "New bug reports:"
+ for bug in added:
+ cmdutil.bug_summary(bug, bugdir, no_target=True)
+
+ print "modified bug reports:"
+ for old_bug, new_bug in modified:
+ cmdutil.bug_summary(new_bug, bugdir, no_target=True)
+
+ print "Removed bug reports:"
+ for bug in removed:
+ cmdutil.bug_summary(bug, bugdir, no_target=True)
+
+
+