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/show.py | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 libbe/command/show.py (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py new file mode 100644 index 0000000..7757aaa --- /dev/null +++ b/libbe/command/show.py @@ -0,0 +1,183 @@ +# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc. +# Gianluca Montecchi +# Thomas Gerigk +# Thomas Habets +# 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. +"""Show a particular bug, comment, or combination of both.""" +import sys +from libbe import cmdutil, bugdir, comment, version, _version +__desc__ = __doc__ + +def execute(args, manipulate_encodings=True, restrict_file_access=False, + dir="."): + """ + >>> import os + >>> bd = bugdir.SimpleBugDir() + >>> os.chdir(bd.root) + >>> execute (["a",], manipulate_encodings=False) # doctest: +ELLIPSIS + ID : a + Short name : a + Severity : minor + Status : open + Assigned : + Reporter : + Creator : John Doe + Created : ... + Bug A + + >>> execute (["--xml", "a"], manipulate_encodings=False) # doctest: +ELLIPSIS + + + + ... + ... + ... + ... + + + a + a + minor + open + John Doe <jdoe@example.com> + Thu, 01 Jan 1970 00:00:00 +0000 + Bug A + + + >>> bd.cleanup() + """ + parser = get_parser() + options, args = parser.parse_args(args) + cmdutil.default_complete(options, args, parser, + bugid_args={-1: lambda bug : bug.active==True}) + if len(args) == 0: + raise cmdutil.UsageError + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=manipulate_encodings, + root=dir) + + if options.only_raw_body == True: + if len(args) != 1: + raise cmdutil.UsageError( + 'only one ID accepted with --only-raw-body') + bug,comment = cmdutil.bug_comment_from_id(bd, args[0]) + if comment == bug.comment_root: + raise cmdutil.UsageError( + "--only-raw-body requires a comment ID, not '%s'" % args[0]) + sys.__stdout__.write(comment.body) + sys.exit(0) + print output(args, bd, as_xml=options.XML, with_comments=options.comments) + +def get_parser(): + parser = cmdutil.CmdOptionParser("be show [options] ID [ID ...]") + parser.add_option("-x", "--xml", action="store_true", default=False, + dest='XML', help="Dump as XML") + parser.add_option("--only-raw-body", action="store_true", + dest='only_raw_body', + help="When printing only a single comment, just print it's body. This allows extraction of non-text content types.") + parser.add_option("-c", "--no-comments", dest="comments", + action="store_false", default=True, + help="Disable comment output. This is useful if you just want more details on a bug's current status.") + return parser + +longhelp=""" +Show all information about the bugs or comments whose IDs are given. + +Without the --xml flag set, it's probably not a good idea to mix bug +and comment IDs in a single call, but you're free to do so if you +like. With the --xml flag set, there will never be any root comments, +so mix and match away (the bug listings for directly requested +comments will be restricted to the bug uuid and the requested +comment(s)). + +Directly requested comments will be grouped by their parent bug and +placed at the end of the output, so the ordering may not match the +order of the listed IDs. +""" + +def help(): + return get_parser().help_str() + longhelp + +def _sort_ids(ids, with_comments=True): + bugs = [] + root_comments = {} + for id in ids: + bugname,commname = cmdutil.parse_id(id) + if commname == None: + bugs.append(bugname) + elif with_comments == True: + if bugname not in root_comments: + root_comments[bugname] = [commname] + else: + root_comments[bugname].append(commname) + for bugname in root_comments.keys(): + assert bugname not in bugs, \ + "specifically requested both '%s%s' and '%s'" \ + % (bugname, root_comments[bugname][0], bugname) + return (bugs, root_comments) + +def _xml_header(encoding): + lines = ['' % encoding, + '', + ' ', + ' %s' % version.version()] + for tag in ['branch-nick', 'revno', 'revision-id']: + value = _version.version_info[tag.replace('-', '_')] + lines.append(' <%s>%s' % (tag, value, tag)) + lines.append(' ') + return lines + +def _xml_footer(): + return [''] + +def output(ids, bd, as_xml=True, with_comments=True): + bugs,root_comments = _sort_ids(ids, with_comments) + lines = [] + if as_xml: + lines.extend(_xml_header(bd.encoding)) + else: + spaces_left = len(ids) - 1 + for bugname in bugs: + bug = cmdutil.bug_from_id(bd, bugname) + if as_xml: + lines.append(bug.xml(indent=2, show_comments=with_comments)) + else: + lines.append(bug.string(show_comments=with_comments)) + if spaces_left > 0: + spaces_left -= 1 + lines.append('') # add a blank line between bugs/comments + for bugname,comments in root_comments.items(): + bug = cmdutil.bug_from_id(bd, bugname) + if as_xml: + lines.extend([' ', ' %s' % bug.uuid]) + for commname in comments: + try: + comment = bug.comment_root.comment_from_shortname(commname) + except comment.InvalidShortname, e: + raise UserError(e.message) + if as_xml: + lines.append(comment.xml(indent=4, shortname=bugname)) + else: + lines.append(comment.string(shortname=bugname)) + if spaces_left > 0: + spaces_left -= 1 + lines.append('') # add a blank line between bugs/comments + if as_xml: + lines.append('') + if as_xml: + lines.extend(_xml_footer()) + return '\n'.join(lines) -- cgit From 21c3bf5ce2fcb9fdd4493b2385c6623979746829 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 15 Dec 2009 00:04:55 -0500 Subject: Transitioned show to Command-format --- libbe/command/show.py | 164 ++++++++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 71 deletions(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index 7757aaa..1a569a6 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -17,20 +17,32 @@ # 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. -"""Show a particular bug, comment, or combination of both.""" + import sys -from libbe import cmdutil, bugdir, comment, version, _version -__desc__ = __doc__ -def execute(args, manipulate_encodings=True, restrict_file_access=False, - dir="."): - """ - >>> import os - >>> bd = bugdir.SimpleBugDir() - >>> os.chdir(bd.root) - >>> execute (["a",], manipulate_encodings=False) # doctest: +ELLIPSIS +import libbe +import libbe.command +import libbe.command.util +import libbe.util.id +import libbe.version +import libbe._version + + +class Show (libbe.command.Command): + """Show a particular bug, comment, or combination of both. + + >>> import sys + >>> import libbe.bugdir + >>> bd = libbe.bugdir.SimpleBugDir(memory=False) + >>> cmd = Show() + >>> cmd._storage = bd.storage + >>> cmd._setup_io = lambda i_enc,o_enc : None + >>> cmd.stdout = sys.stdout + >>> cmd.stdout.encoding = 'ascii' + + >>> ret = cmd.run(args=['/a',]) # doctest: +ELLIPSIS ID : a - Short name : a + Short name : abc/a Severity : minor Status : open Assigned : @@ -39,7 +51,8 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False, Created : ... Bug A - >>> execute (["--xml", "a"], manipulate_encodings=False) # doctest: +ELLIPSIS + + >>> ret = cmd.run({'xml':True}, ['/a']) # doctest: +ELLIPSIS @@ -50,7 +63,7 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False, a - a + abc/a minor open John Doe <jdoe@example.com> @@ -60,42 +73,51 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False, >>> bd.cleanup() """ - parser = get_parser() - options, args = parser.parse_args(args) - cmdutil.default_complete(options, args, parser, - bugid_args={-1: lambda bug : bug.active==True}) - if len(args) == 0: - raise cmdutil.UsageError - bd = bugdir.BugDir(from_disk=True, - manipulate_encodings=manipulate_encodings, - root=dir) - - if options.only_raw_body == True: - if len(args) != 1: - raise cmdutil.UsageError( - 'only one ID accepted with --only-raw-body') - bug,comment = cmdutil.bug_comment_from_id(bd, args[0]) - if comment == bug.comment_root: - raise cmdutil.UsageError( - "--only-raw-body requires a comment ID, not '%s'" % args[0]) - sys.__stdout__.write(comment.body) - sys.exit(0) - print output(args, bd, as_xml=options.XML, with_comments=options.comments) - -def get_parser(): - parser = cmdutil.CmdOptionParser("be show [options] ID [ID ...]") - parser.add_option("-x", "--xml", action="store_true", default=False, - dest='XML', help="Dump as XML") - parser.add_option("--only-raw-body", action="store_true", - dest='only_raw_body', - help="When printing only a single comment, just print it's body. This allows extraction of non-text content types.") - parser.add_option("-c", "--no-comments", dest="comments", - action="store_false", default=True, - help="Disable comment output. This is useful if you just want more details on a bug's current status.") - return parser - -longhelp=""" + name = 'show' + + def __init__(self, *args, **kwargs): + libbe.command.Command.__init__(self, *args, **kwargs) + self.options.extend([ + libbe.command.Option(name='xml', short_name='x', + help='Dump as XML'), + libbe.command.Option(name='only-raw-body', + help="When printing only a single comment, just print it's" + " body. This allows extraction of non-text content types."), + libbe.command.Option(name='no-comments', short_name='c', + help="Disable comment output. This is useful if you just " + "want more details on a bug's current status."), + ]) + self.args.extend([ + libbe.command.Argument( + name='id', metavar='ID', default=None, + optional=True, repeatable=True, + completion_callback=libbe.command.util.complete_bug_comment_id), + ]) + + def _run(self, **params): + bugdir = self._get_bugdir() + if params['only-raw-body'] == True: + if len(params['id']) != 1: + raise libbe.command.UsageError( + 'only one ID accepted with --only-raw-body') + bug,comment = libbe.command.util.bug_comment_from_user_id( + bugdir, params['id'][0]) + if comment == bug.comment_root: + raise libbe.command.UsageError( + "--only-raw-body requires a comment ID, not '%s'" + % params['id'][0]) + sys.__stdout__.write(comment.body) + return 0 + print >> self.stdout, \ + output(bugdir, params['id'], encoding=self.stdout.encoding, + as_xml=params['xml'], + with_comments=not params['no-comments']) + return 0 + + def _long_help(self): + return """ Show all information about the bugs or comments whose IDs are given. +If no IDs are given, show the entire repository. Without the --xml flag set, it's probably not a good idea to mix bug and comment IDs in a single call, but you're free to do so if you @@ -109,24 +131,21 @@ placed at the end of the output, so the ordering may not match the order of the listed IDs. """ -def help(): - return get_parser().help_str() + longhelp - -def _sort_ids(ids, with_comments=True): +def _sort_ids(bugdir, ids, with_comments=True): bugs = [] root_comments = {} for id in ids: - bugname,commname = cmdutil.parse_id(id) - if commname == None: - bugs.append(bugname) + p = libbe.util.id.parse_user(bugdir, id) + if p['type'] == 'bug': + bugs.append(p['bug']) elif with_comments == True: - if bugname not in root_comments: - root_comments[bugname] = [commname] + if p['bug'] not in root_comments: + root_comments[p['bug']] = [p['comment']] else: - root_comments[bugname].append(commname) + root_comments[p['bug']].append(p['comment']) for bugname in root_comments.keys(): assert bugname not in bugs, \ - "specifically requested both '%s%s' and '%s'" \ + 'specifically requested both #/%s/%s# and #/%s#' \ % (bugname, root_comments[bugname][0], bugname) return (bugs, root_comments) @@ -134,9 +153,9 @@ def _xml_header(encoding): lines = ['' % encoding, '', ' ', - ' %s' % version.version()] + ' %s' % libbe.version.version()] for tag in ['branch-nick', 'revno', 'revision-id']: - value = _version.version_info[tag.replace('-', '_')] + value = libbe._version.version_info[tag.replace('-', '_')] lines.append(' <%s>%s' % (tag, value, tag)) lines.append(' ') return lines @@ -144,15 +163,18 @@ def _xml_header(encoding): def _xml_footer(): return [''] -def output(ids, bd, as_xml=True, with_comments=True): - bugs,root_comments = _sort_ids(ids, with_comments) +def output(bd, ids, encoding, as_xml=True, with_comments=True): + if len(ids) == 0: + bd.load_all_bugs() + ids = [bug.id.user() for bug in bd] + bugs,root_comments = _sort_ids(bd, ids, with_comments) lines = [] if as_xml: - lines.extend(_xml_header(bd.encoding)) + lines.extend(_xml_header(encoding)) else: spaces_left = len(ids) - 1 for bugname in bugs: - bug = cmdutil.bug_from_id(bd, bugname) + bug = bd.bug_from_uuid(bugname) if as_xml: lines.append(bug.xml(indent=2, show_comments=with_comments)) else: @@ -161,18 +183,18 @@ def output(ids, bd, as_xml=True, with_comments=True): spaces_left -= 1 lines.append('') # add a blank line between bugs/comments for bugname,comments in root_comments.items(): - bug = cmdutil.bug_from_id(bd, bugname) + bug = bd.bug_from_uuid(bugname) if as_xml: lines.extend([' ', ' %s' % bug.uuid]) for commname in comments: try: - comment = bug.comment_root.comment_from_shortname(commname) - except comment.InvalidShortname, e: - raise UserError(e.message) + comment = bug.comment_root.comment_from_uuid(commname) + except KeyError, e: + raise libbe.command.UserError(e.message) if as_xml: - lines.append(comment.xml(indent=4, shortname=bugname)) + lines.append(comment.xml(indent=4)) else: - lines.append(comment.string(shortname=bugname)) + lines.append(comment.string()) if spaces_left > 0: spaces_left -= 1 lines.append('') # add a blank line between bugs/comments -- 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/show.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index 1a569a6..1b498aa 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -45,8 +45,8 @@ class Show (libbe.command.Command): Short name : abc/a Severity : minor Status : open - Assigned : - Reporter : + Assigned : + Reporter : Creator : John Doe Created : ... Bug A -- cgit From 9a62c4beea7c89905dc487bdbe2e46fed4b83f21 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Tue, 29 Dec 2009 19:19:15 -0500 Subject: Restored post-colon spaces in doctests --- libbe/command/show.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index 1b498aa..1a569a6 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -45,8 +45,8 @@ class Show (libbe.command.Command): Short name : abc/a Severity : minor Status : open - Assigned : - Reporter : + Assigned : + Reporter : Creator : John Doe Created : ... Bug A -- 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/show.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index 1a569a6..5ab6dc7 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -34,13 +34,14 @@ class Show (libbe.command.Command): >>> import sys >>> import libbe.bugdir >>> bd = libbe.bugdir.SimpleBugDir(memory=False) - >>> cmd = Show() - >>> cmd._storage = bd.storage - >>> cmd._setup_io = lambda i_enc,o_enc : None - >>> cmd.stdout = sys.stdout - >>> cmd.stdout.encoding = 'ascii' - - >>> ret = cmd.run(args=['/a',]) # doctest: +ELLIPSIS + >>> io = libbe.command.StringInputOutput() + >>> io.stdout = sys.stdout + >>> io.stdout.encoding = 'ascii' + >>> ui = libbe.command.UserInterface(io=io) + >>> ui.storage_callbacks.set_bugdir(bd) + >>> cmd = Show(ui=ui) + + >>> ret = ui.run(cmd, args=['/a',]) # doctest: +ELLIPSIS ID : a Short name : abc/a Severity : minor @@ -52,7 +53,7 @@ class Show (libbe.command.Command): Bug A - >>> ret = cmd.run({'xml':True}, ['/a']) # doctest: +ELLIPSIS + >>> ret = ui.run(cmd, {'xml':True}, ['/a']) # doctest: +ELLIPSIS @@ -71,6 +72,7 @@ class Show (libbe.command.Command): Bug A + >>> ui.cleanup() >>> bd.cleanup() """ name = 'show' -- cgit From 4d4283ecd654f1efb058cd7f7dba6be88b70ee92 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 1 Jan 2010 08:11:08 -0500 Subject: Updated copyright information --- libbe/command/show.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index 5ab6dc7..e102391 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -1,4 +1,4 @@ -# Copyright (C) 2005-2009 Aaron Bentley and Panometrics, Inc. +# Copyright (C) 2005-2010 Aaron Bentley and Panometrics, Inc. # Gianluca Montecchi # Thomas Gerigk # Thomas Habets -- cgit From 55e43b6c6f260e3fd1bbed93fcabdb9790404904 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 29 Jan 2010 14:32:27 -0500 Subject: Fix `be show` handling for no IDs --- libbe/command/show.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbe/command/show.py') diff --git a/libbe/command/show.py b/libbe/command/show.py index e102391..ab3be73 100644 --- a/libbe/command/show.py +++ b/libbe/command/show.py @@ -166,7 +166,7 @@ def _xml_footer(): return [''] def output(bd, ids, encoding, as_xml=True, with_comments=True): - if len(ids) == 0: + if ids == None or len(ids) == 0: bd.load_all_bugs() ids = [bug.id.user() for bug in bd] bugs,root_comments = _sort_ids(bd, ids, with_comments) -- cgit