aboutsummaryrefslogtreecommitdiffstats
path: root/libbe/command/diff.py
diff options
context:
space:
mode:
authorGianluca Montecchi <gian@grys.it>2010-02-10 00:03:38 +0100
committerGianluca Montecchi <gian@grys.it>2010-02-10 00:03:38 +0100
commitc67a5863826771001f009e1ee90262ccb7a2e172 (patch)
tree64c7f83238685959bf40a13c876168071a085556 /libbe/command/diff.py
parenta60e599798d43ba930efc1f8e2f184d3e8262189 (diff)
parent50444209eee408dde7d240fdf59bfc9e82b714ce (diff)
downloadbugseverywhere-c67a5863826771001f009e1ee90262ccb7a2e172.tar.gz
Merged Trevor's tree
Diffstat (limited to 'libbe/command/diff.py')
-rw-r--r--libbe/command/diff.py139
1 files changed, 139 insertions, 0 deletions
diff --git a/libbe/command/diff.py b/libbe/command/diff.py
new file mode 100644
index 0000000..967ab14
--- /dev/null
+++ b/libbe/command/diff.py
@@ -0,0 +1,139 @@
+# Copyright (C) 2005-2010 Aaron Bentley and Panometrics, Inc.
+# Gianluca Montecchi <gian@grys.it>
+# W. Trevor King <wking@drexel.edu>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import libbe
+import libbe.bugdir
+import libbe.bug
+import libbe.command
+import libbe.command.util
+import libbe.storage
+
+import libbe.diff
+
+class Diff (libbe.command.Command):
+ __doc__ = """Compare bug reports with older tree
+
+ >>> import sys
+ >>> import libbe.bugdir
+ >>> bd = libbe.bugdir.SimpleBugDir(memory=False, versioned=True)
+ >>> io = libbe.command.StringInputOutput()
+ >>> io.stdout = sys.stdout
+ >>> ui = libbe.command.UserInterface(io=io)
+ >>> ui.storage_callbacks.set_storage(bd.storage)
+ >>> cmd = Diff()
+
+ >>> original = bd.storage.commit('Original status')
+ >>> bug = bd.bug_from_uuid('a')
+ >>> bug.status = 'closed'
+ >>> changed = bd.storage.commit('Closed bug a')
+ >>> ret = ui.run(cmd, args=[original])
+ Modified bugs:
+ abc/a:cm: Bug A
+ Changed bug settings:
+ status: open -> closed
+ >>> ret = ui.run(cmd, {'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original])
+ a
+ >>> bd.storage.versioned = False
+ >>> ret = ui.run(cmd, args=[original])
+ Traceback (most recent call last):
+ ...
+ UserError: This repository is not revision-controlled.
+ >>> ui.cleanup()
+ >>> bd.cleanup()
+ """ % {'bugdir_id':libbe.diff.BUGDIR_ID}
+ name = 'diff'
+
+ def __init__(self, *args, **kwargs):
+ libbe.command.Command.__init__(self, *args, **kwargs)
+ self.options.extend([
+ libbe.command.Option(name='repo', short_name='r',
+ help='Compare with repository in REPO instead'
+ ' of the current repository.',
+ arg=libbe.command.Argument(
+ name='repo', metavar='REPO',
+ completion_callback=libbe.command.util.complete_path)),
+ libbe.command.Option(name='subscribe', short_name='s',
+ help='Only print changes matching SUBSCRIPTION, '
+ 'subscription is a comma-separated list of ID:TYPE '
+ 'tuples. See `be subscribe --help` for descriptions '
+ 'of ID and TYPE.',
+ arg=libbe.command.Argument(
+ name='subscribe', metavar='SUBSCRIPTION')),
+ libbe.command.Option(name='uuids', short_name='u',
+ help='Only print the changed bug UUIDS.'),
+ ])
+ self.args.extend([
+ libbe.command.Argument(
+ name='revision', metavar='REVISION', default=None,
+ optional=True)
+ ])
+
+ def _run(self, **params):
+ try:
+ subscriptions = libbe.diff.subscriptions_from_string(
+ params['subscribe'])
+ except ValueError, e:
+ raise libbe.command.UserError(e.msg)
+ bugdir = self._get_bugdir()
+ if bugdir.storage.versioned == False:
+ raise libbe.command.UserError(
+ 'This repository is not revision-controlled.')
+ if params['repo'] == None:
+ if params['revision'] == None: # get the most recent revision
+ params['revision'] = bugdir.storage.revision_id(-1)
+ old_bd = libbe.bugdir.RevisionedBugDir(bugdir, params['revision'])
+ else:
+ old_storage = libbe.storage.get_storage(params['repo'])
+ old_storage.connect()
+ old_bd_current = libbe.bugdir.BugDir(old_storage, from_disk=True)
+ if params['revision'] == None: # use the current working state
+ old_bd = old_bd_current
+ else:
+ if old_bd_current.storage.versioned == False:
+ raise libbe.command.UserError(
+ '%s is not revision-controlled.'
+ % storage.repo)
+ old_bd = libbe.bugdir.RevisionedBugDir(old_bd_current,revision)
+ d = libbe.diff.Diff(old_bd, bugdir)
+ tree = d.report_tree(subscriptions)
+
+ if params['uuids'] == True:
+ uuids = []
+ bugs = tree.child_by_path('/bugs')
+ for bug_type in bugs:
+ uuids.extend([bug.name for bug in bug_type])
+ print >> self.stdout, '\n'.join(uuids)
+ else :
+ rep = tree.report_string()
+ if rep != None:
+ print >> self.stdout, rep
+ return 0
+
+ def _long_help(self):
+ return """
+Uses the storage backend to compare the current tree with a previous
+tree, and prints a pretty report. If REVISION is given, it is a
+specifier for the particular previous tree to use. Specifiers are
+specific to their storage backend.
+
+For Arch your specifier must be a fully-qualified revision name.
+
+Besides the standard summary output, you can use the options to output
+UUIDS for the different categories. This output can be used as the
+input to 'be show' to get an understanding of the current status.
+"""