From 49a7771336ce09f6d42c7699ef32aecea0e83182 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 7 Dec 2009 20:07:55 -0500 Subject: Initial directory restructuring to clarify dependencies --- libbe/command/diff.py | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 libbe/command/diff.py (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py new file mode 100644 index 0000000..c5c34f9 --- /dev/null +++ b/libbe/command/diff.py @@ -0,0 +1,133 @@ +# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc. +# Gianluca Montecchi +# W. Trevor King +# +# 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. + +"""Compare bug reports with older tree""" +from libbe import cmdutil, bugdir, diff +import os +__desc__ = __doc__ + +def execute(args, manipulate_encodings=True, restrict_file_access=False, + dir="."): + """ + >>> import os + >>> bd = bugdir.SimpleBugDir() + >>> bd.set_sync_with_disk(True) + >>> original = bd.vcs.commit("Original status") + >>> bug = bd.bug_from_uuid("a") + >>> bug.status = "closed" + >>> changed = bd.vcs.commit("Closed bug a") + >>> os.chdir(bd.root) + >>> if bd.vcs.versioned == True: + ... execute([original], manipulate_encodings=False) + ... else: + ... print "Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed" + Modified bugs: + a:cm: Bug A + Changed bug settings: + status: open -> closed + >>> if bd.vcs.versioned == True: + ... execute(["--subscribe", "%(bugdir_id)s:mod", "--uuids", original], + ... manipulate_encodings=False) + ... else: + ... print "a" + a + >>> if bd.vcs.versioned == False: + ... execute([original], manipulate_encodings=False) + ... else: + ... raise cmdutil.UsageError('This directory is not revision-controlled.') + Traceback (most recent call last): + ... + UsageError: This directory is not revision-controlled. + >>> bd.cleanup() + """ % {'bugdir_id':diff.BUGDIR_ID} + parser = get_parser() + options, args = parser.parse_args(args) + cmdutil.default_complete(options, args, parser) + if len(args) == 0: + revision = None + if len(args) == 1: + revision = args[0] + if len(args) > 1: + raise cmdutil.UsageError('Too many arguments.') + try: + subscriptions = diff.subscriptions_from_string( + options.subscribe) + except ValueError, e: + raise cmdutil.UsageError(e.msg) + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=manipulate_encodings, + root=dir) + if bd.vcs.versioned == False: + raise cmdutil.UsageError('This directory is not revision-controlled.') + if options.dir == None: + if revision == None: # get the most recent revision + revision = bd.vcs.revision_id(-1) + old_bd = bd.duplicate_bugdir(revision) + else: + old_bd_current = bugdir.BugDir(root=os.path.abspath(options.dir), + from_disk=True, + manipulate_encodings=False) + if revision == None: # use the current working state + old_bd = old_bd_current + else: + if old_bd_current.vcs.versioned == False: + raise cmdutil.UsageError('%s is not revision-controlled.' + % options.dir) + old_bd = old_bd_current.duplicate_bugdir(revision) + d = diff.Diff(old_bd, bd) + tree = d.report_tree(subscriptions) + + if options.uuids == True: + uuids = [] + bugs = tree.child_by_path('/bugs') + for bug_type in bugs: + uuids.extend([bug.name for bug in bug_type]) + print '\n'.join(uuids) + else : + rep = tree.report_string() + if rep != None: + print rep + bd.remove_duplicate_bugdir() + if options.dir != None and revision != None: + old_bd_current.remove_duplicate_bugdir() + +def get_parser(): + parser = cmdutil.CmdOptionParser("be diff [options] REVISION") + parser.add_option("-d", "--dir", dest="dir", metavar="DIR", + help="Compare with repository in DIR instead of the current directory.") + parser.add_option("-s", "--subscribe", dest="subscribe", metavar="SUBSCRIPTION", + help="Only print changes matching SUBSCRIPTION, subscription is a comma-separ\ated list of ID:TYPE tuples. See `be subscribe --help` for descriptions of ID and TYPE.") + parser.add_option("-u", "--uuids", action="store_true", dest="uuids", + help="Only print the bug UUIDS.", default=False) + return parser + +longhelp=""" +Uses the VCS 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 +VCS. + +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. +""" + +def help(): + return get_parser().help_str() + longhelp -- cgit From 66343859b94ab7417bd4560ccc1c023d9ba6d1d2 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 01:07:18 -0500 Subject: Transitioned diff and subscribe to Command-format" They don't work yet, since I still need to fix up libbe.diff and replace BugDir.duplicate_bugdir() with something based on the new Storage backend. --- libbe/command/diff.py | 183 ++++++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 86 deletions(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index c5c34f9..de8cf67 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -16,107 +16,121 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -"""Compare bug reports with older tree""" -from libbe import cmdutil, bugdir, diff -import os -__desc__ = __doc__ +import libbe +import libbe.bug +import libbe.command +import libbe.command.util +import libbe.storage -def execute(args, manipulate_encodings=True, restrict_file_access=False, - dir="."): - """ - >>> import os - >>> bd = bugdir.SimpleBugDir() - >>> bd.set_sync_with_disk(True) - >>> original = bd.vcs.commit("Original status") - >>> bug = bd.bug_from_uuid("a") - >>> bug.status = "closed" - >>> changed = bd.vcs.commit("Closed bug a") - >>> os.chdir(bd.root) +import libbe.diff + +class Diff (libbe.command.Command): + """Compare bug reports with older tree + + >>> import sys + >>> import libbe.bugdir + >>> bd = libbe.bugdir.SimpleBugDir(memory=False) + >>> cmd = Subscribe() + >>> cmd._storage = bd.storage + >>> cmd._setup_io = lambda i_enc,o_enc : None + >>> cmd.stdout = sys.stdout + + >>> original = bd.storage.commit('Original status') + >>> bug = bd.bug_from_uuid('a') + >>> bug.status = 'closed' + >>> changed = bd.vcs.commit('Closed bug a') >>> if bd.vcs.versioned == True: - ... execute([original], manipulate_encodings=False) + ... ret = cmd.run(args=[original]) ... else: - ... print "Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed" + ... print 'Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed' Modified bugs: a:cm: Bug A Changed bug settings: status: open -> closed >>> if bd.vcs.versioned == True: - ... execute(["--subscribe", "%(bugdir_id)s:mod", "--uuids", original], - ... manipulate_encodings=False) + ... ret = cmd.run({'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) ... else: - ... print "a" + ... print 'a' a >>> if bd.vcs.versioned == False: - ... execute([original], manipulate_encodings=False) + ... ret = cmd.run(args=[original]) ... else: - ... raise cmdutil.UsageError('This directory is not revision-controlled.') + ... raise libbe.command.UserError('This repository not revision-controlled.') Traceback (most recent call last): ... - UsageError: This directory is not revision-controlled. + UserError: This repository is not revision-controlled. >>> bd.cleanup() - """ % {'bugdir_id':diff.BUGDIR_ID} - parser = get_parser() - options, args = parser.parse_args(args) - cmdutil.default_complete(options, args, parser) - if len(args) == 0: - revision = None - if len(args) == 1: - revision = args[0] - if len(args) > 1: - raise cmdutil.UsageError('Too many arguments.') - try: - subscriptions = diff.subscriptions_from_string( - options.subscribe) - except ValueError, e: - raise cmdutil.UsageError(e.msg) - bd = bugdir.BugDir(from_disk=True, - manipulate_encodings=manipulate_encodings, - root=dir) - if bd.vcs.versioned == False: - raise cmdutil.UsageError('This directory is not revision-controlled.') - if options.dir == None: - if revision == None: # get the most recent revision - revision = bd.vcs.revision_id(-1) - old_bd = bd.duplicate_bugdir(revision) - else: - old_bd_current = bugdir.BugDir(root=os.path.abspath(options.dir), - from_disk=True, - manipulate_encodings=False) - if revision == None: # use the current working state - old_bd = old_bd_current - else: - if old_bd_current.vcs.versioned == False: - raise cmdutil.UsageError('%s is not revision-controlled.' - % options.dir) - old_bd = old_bd_current.duplicate_bugdir(revision) - d = diff.Diff(old_bd, bd) - tree = d.report_tree(subscriptions) + """ % {'bugdir_id':libbe.diff.BUGDIR_ID} + name = 'diff' - if options.uuids == True: - uuids = [] - bugs = tree.child_by_path('/bugs') - for bug_type in bugs: - uuids.extend([bug.name for bug in bug_type]) - print '\n'.join(uuids) - else : - rep = tree.report_string() - if rep != None: - print rep - bd.remove_duplicate_bugdir() - if options.dir != None and revision != None: - old_bd_current.remove_duplicate_bugdir() + 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-separ\ated 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 get_parser(): - parser = cmdutil.CmdOptionParser("be diff [options] REVISION") - parser.add_option("-d", "--dir", dest="dir", metavar="DIR", - help="Compare with repository in DIR instead of the current directory.") - parser.add_option("-s", "--subscribe", dest="subscribe", metavar="SUBSCRIPTION", - help="Only print changes matching SUBSCRIPTION, subscription is a comma-separ\ated list of ID:TYPE tuples. See `be subscribe --help` for descriptions of ID and TYPE.") - parser.add_option("-u", "--uuids", action="store_true", dest="uuids", - help="Only print the bug UUIDS.", default=False) - return parser + 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 = bugdir.duplicate_bugdir(params['revision']) # TODO + else: + old_storage = libbe.storage.get_storage(params['repo']) + old_storage.connect() + old_bd_current = 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 = old_bd_current.duplicate_bugdir(revision) # TODO + d = libbe.diff.Diff(old_bd, bugir) + 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 -longhelp=""" + def _long_help(self): + return """ Uses the VCS 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 @@ -128,6 +142,3 @@ 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. """ - -def help(): - return get_parser().help_str() + longhelp -- cgit From 4370270929db62a32d168ae221ecc70a2d80269e Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 02:38:51 -0500 Subject: Transitioned target to Command-format --- libbe/command/diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index de8cf67..05242db 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -25,7 +25,7 @@ import libbe.storage import libbe.diff class Diff (libbe.command.Command): - """Compare bug reports with older tree + __doc__ = """Compare bug reports with older tree >>> import sys >>> import libbe.bugdir -- cgit From 58bedebfddbb8e1fc8f0a441163526feaecb753b Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 03:31:48 -0500 Subject: Transition to Command-format complete. Well, except for going through and updating the _long_help() strings. $ python test.py libbe.command succeeds for everything except Diff and Subscribe, which is expected since I haven't fixed up libbe.diff yet. --- libbe/command/diff.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index 05242db..6a7c36b 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -30,7 +30,7 @@ class Diff (libbe.command.Command): >>> import sys >>> import libbe.bugdir >>> bd = libbe.bugdir.SimpleBugDir(memory=False) - >>> cmd = Subscribe() + >>> cmd = Diff() >>> cmd._storage = bd.storage >>> cmd._setup_io = lambda i_enc,o_enc : None >>> cmd.stdout = sys.stdout @@ -38,8 +38,8 @@ class Diff (libbe.command.Command): >>> original = bd.storage.commit('Original status') >>> bug = bd.bug_from_uuid('a') >>> bug.status = 'closed' - >>> changed = bd.vcs.commit('Closed bug a') - >>> if bd.vcs.versioned == True: + >>> changed = bd.storage.commit('Closed bug a') + >>> if bd.storage.versioned == True: ... ret = cmd.run(args=[original]) ... else: ... print 'Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed' @@ -47,12 +47,12 @@ class Diff (libbe.command.Command): a:cm: Bug A Changed bug settings: status: open -> closed - >>> if bd.vcs.versioned == True: + >>> if bd.storage.versioned == True: ... ret = cmd.run({'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) ... else: ... print 'a' a - >>> if bd.vcs.versioned == False: + >>> if bd.storage.versioned == False: ... ret = cmd.run(args=[original]) ... else: ... raise libbe.command.UserError('This repository not revision-controlled.') @@ -131,10 +131,10 @@ class Diff (libbe.command.Command): def _long_help(self): return """ -Uses the VCS 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 -VCS. +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. -- cgit From 380889988b6d7881c4e0b5968053f85676d27211 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 04:32:19 -0500 Subject: Fixed libbe.command.subscribe --- libbe/command/diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index 6a7c36b..c8b5777 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -74,7 +74,7 @@ class Diff (libbe.command.Command): 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-separ\ated list of ID:TYPE ' + 'subscription is a comma-separated list of ID:TYPE ' 'tuples. See `be subscribe --help` for descriptions ' 'of ID and TYPE.', arg=libbe.command.Argument( -- cgit From 89b7a1411e4658e831f5d635534b24355dbb941d Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 06:44:20 -0500 Subject: Fixed libbe.command.diff + ugly BugDir.duplicate_bugdir implementation duplicate_bugdir() works, but for the vcs backends, it could require shelling out for _every_ file read. This could, and probably will, be horribly slow. Still it works ;). I'm not sure what a better implementation would be. The old implementation checked out the entire earlier state into a temporary directory pros: single shell out, simple upgrade implementation cons: wouldn't work well for HTTP backens I think a good solution would run along the lines of the currently commented out code in duplicate_bugdir(), where a VersionedStorage.changed_since(revision) call would give you a list of changed files. diff could work off of that directly, without the need to generate a whole duplicate bugdir. I'm stuck on how to handle upgrades though... Also removed trailing whitespace from all python files. --- libbe/command/diff.py | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index c8b5777..d945f96 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -29,7 +29,7 @@ class Diff (libbe.command.Command): >>> import sys >>> import libbe.bugdir - >>> bd = libbe.bugdir.SimpleBugDir(memory=False) + >>> bd = libbe.bugdir.SimpleBugDir(memory=False, versioned=True) >>> cmd = Diff() >>> cmd._storage = bd.storage >>> cmd._setup_io = lambda i_enc,o_enc : None @@ -39,23 +39,15 @@ class Diff (libbe.command.Command): >>> bug = bd.bug_from_uuid('a') >>> bug.status = 'closed' >>> changed = bd.storage.commit('Closed bug a') - >>> if bd.storage.versioned == True: - ... ret = cmd.run(args=[original]) - ... else: - ... print 'Modified bugs:\\n a:cm: Bug A\\n Changed bug settings:\\n status: open -> closed' + >>> ret = cmd.run(args=[original]) Modified bugs: - a:cm: Bug A + abc/a:cm: Bug A Changed bug settings: status: open -> closed - >>> if bd.storage.versioned == True: - ... ret = cmd.run({'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) - ... else: - ... print 'a' + >>> ret = cmd.run({'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) a - >>> if bd.storage.versioned == False: - ... ret = cmd.run(args=[original]) - ... else: - ... raise libbe.command.UserError('This repository not revision-controlled.') + >>> bd.storage.versioned = False + >>> ret = cmd.run(args=[original]) Traceback (most recent call last): ... UserError: This repository is not revision-controlled. @@ -101,7 +93,7 @@ class Diff (libbe.command.Command): if params['repo'] == None: if params['revision'] == None: # get the most recent revision params['revision'] = bugdir.storage.revision_id(-1) - old_bd = bugdir.duplicate_bugdir(params['revision']) # TODO + old_bd = bugdir.duplicate_bugdir(params['revision']) else: old_storage = libbe.storage.get_storage(params['repo']) old_storage.connect() @@ -113,8 +105,8 @@ class Diff (libbe.command.Command): raise libbe.command.UserError( '%s is not revision-controlled.' % storage.repo) - old_bd = old_bd_current.duplicate_bugdir(revision) # TODO - d = libbe.diff.Diff(old_bd, bugir) + old_bd = old_bd_current.duplicate_bugdir(revision) + d = libbe.diff.Diff(old_bd, bugdir) tree = d.report_tree(subscriptions) if params['uuids'] == True: -- cgit From cfae8a8302f06a84196700138d7ddbb25e91ea31 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 31 Dec 2009 14:32:39 -0500 Subject: Added UserInterface and other improved abstractions for command handling --- libbe/command/diff.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'libbe/command/diff.py') diff --git a/libbe/command/diff.py b/libbe/command/diff.py index d945f96..ebfe8fe 100644 --- a/libbe/command/diff.py +++ b/libbe/command/diff.py @@ -30,27 +30,29 @@ class Diff (libbe.command.Command): >>> 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() - >>> cmd._storage = bd.storage - >>> cmd._setup_io = lambda i_enc,o_enc : None - >>> cmd.stdout = sys.stdout >>> original = bd.storage.commit('Original status') >>> bug = bd.bug_from_uuid('a') >>> bug.status = 'closed' >>> changed = bd.storage.commit('Closed bug a') - >>> ret = cmd.run(args=[original]) + >>> ret = ui.run(cmd, args=[original]) Modified bugs: abc/a:cm: Bug A Changed bug settings: status: open -> closed - >>> ret = cmd.run({'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) + >>> ret = ui.run(cmd, {'subscribe':'%(bugdir_id)s:mod', 'uuids':True}, [original]) a >>> bd.storage.versioned = False - >>> ret = cmd.run(args=[original]) + >>> 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' -- cgit