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/comment.py | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 libbe/command/comment.py (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py new file mode 100644 index 0000000..9919d1d --- /dev/null +++ b/libbe/command/comment.py @@ -0,0 +1,164 @@ +# 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. +"""Add a comment to a bug""" +from libbe import cmdutil, bugdir, comment, editor +import os +import sys +__desc__ = __doc__ + +def execute(args, manipulate_encodings=True, restrict_file_access=False, + dir="."): + """ + >>> import time + >>> bd = bugdir.SimpleBugDir() + >>> os.chdir(bd.root) + >>> execute(["a", "This is a comment about a"], manipulate_encodings=False) + >>> bd._clear_bugs() + >>> bug = cmdutil.bug_from_id(bd, "a") + >>> bug.load_comments(load_full=False) + >>> comment = bug.comment_root[0] + >>> print comment.body + This is a comment about a + + >>> comment.author == bd.user_id + True + >>> comment.time <= int(time.time()) + True + >>> comment.in_reply_to is None + True + + >>> if 'EDITOR' in os.environ: + ... del os.environ["EDITOR"] + >>> execute(["b"], manipulate_encodings=False) + Traceback (most recent call last): + UserError: No comment supplied, and EDITOR not specified. + + >>> os.environ["EDITOR"] = "echo 'I like cheese' > " + >>> execute(["b"], manipulate_encodings=False) + >>> bd._clear_bugs() + >>> bug = cmdutil.bug_from_id(bd, "b") + >>> bug.load_comments(load_full=False) + >>> comment = bug.comment_root[0] + >>> print comment.body + I like cheese + + >>> bd.cleanup() + """ + parser = get_parser() + options, args = parser.parse_args(args) + complete(options, args, parser) + if len(args) == 0: + raise cmdutil.UsageError("Please specify a bug or comment id.") + if len(args) > 2: + raise cmdutil.UsageError("Too many arguments.") + + shortname = args[0] + + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=manipulate_encodings, + root=dir) + bug, parent = cmdutil.bug_comment_from_id(bd, shortname) + + if len(args) == 1: # try to launch an editor for comment-body entry + try: + if parent == bug.comment_root: + parent_body = bug.summary+"\n" + else: + parent_body = parent.body + estr = "Please enter your comment above\n\n> %s\n" \ + % ("\n> ".join(parent_body.splitlines())) + body = editor.editor_string(estr) + except editor.CantFindEditor, e: + raise cmdutil.UserError, "No comment supplied, and EDITOR not specified." + if body is None: + raise cmdutil.UserError("No comment entered.") + elif args[1] == '-': # read body from stdin + binary = not (options.content_type == None + or options.content_type.startswith("text/")) + if not binary: + body = sys.stdin.read() + if not body.endswith('\n'): + body+='\n' + else: # read-in without decoding + body = sys.__stdin__.read() + else: # body = arg[1] + body = args[1] + if not body.endswith('\n'): + body+='\n' + + new = parent.new_reply(body=body, content_type=options.content_type) + if options.author != None: + new.author = options.author + if options.alt_id != None: + new.alt_id = options.alt_id + +def get_parser(): + parser = cmdutil.CmdOptionParser("be comment ID [COMMENT]") + parser.add_option("-a", "--author", metavar="AUTHOR", dest="author", + help="Set the comment author", default=None) + parser.add_option("--alt-id", metavar="ID", dest="alt_id", + help="Set an alternate comment ID", default=None) + parser.add_option("-c", "--content-type", metavar="MIME", dest="content_type", + help="Set comment content-type (e.g. text/plain)", default=None) + return parser + +longhelp=""" +To add a comment to a bug, use the bug ID as the argument. To reply +to another comment, specify the comment name (as shown in "be show" +output). COMMENT, if specified, should be either the text of your +comment or "-", in which case the text will be read from stdin. If +you do not specify a COMMENT, $EDITOR is used to launch an editor. If +COMMENT is unspecified and EDITOR is not set, no comment will be +created. +""" + +def help(): + return get_parser().help_str() + longhelp + +def complete(options, args, parser): + for option,value in cmdutil.option_value_pairs(options, parser): + if value == "--complete": + # no argument-options at the moment, so this is future-proofing + raise cmdutil.GetCompletions() + for pos,value in enumerate(args): + if value == "--complete": + if pos == 0: # fist positional argument is a bug or comment id + if len(args) >= 2: + partial = args[1].split(':')[0] # take only bugid portion + else: + partial = "" + ids = [] + try: + bd = bugdir.BugDir(from_disk=True, + manipulate_encodings=False) + bugs = [] + for uuid in bd.uuids(): + if uuid.startswith(partial): + bug = bd.bug_from_uuid(uuid) + if bug.active == True: + bugs.append(bug) + for bug in bugs: + shortname = bd.bug_shortname(bug) + ids.append(shortname) + bug.load_comments(load_full=False) + for id,comment in bug.comment_shortnames(shortname): + ids.append(id) + except bugdir.NoBugDir: + pass + raise cmdutil.GetCompletions(ids) + raise cmdutil.GetCompletions() -- cgit From 19fe0817ba7c2cd04caea3adfa82d4490288a548 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 14 Dec 2009 07:37:51 -0500 Subject: Transitioned comment to Command format --- libbe/command/comment.py | 205 ++++++++++++++++++++++------------------------- 1 file changed, 96 insertions(+), 109 deletions(-) (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py index 9919d1d..7a8f5f9 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -15,43 +15,56 @@ # 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. -"""Add a comment to a bug""" -from libbe import cmdutil, bugdir, comment, editor + import os import sys -__desc__ = __doc__ -def execute(args, manipulate_encodings=True, restrict_file_access=False, - dir="."): - """ +import libbe +import libbe.command +import libbe.command.util +import libbe.comment +import libbe.ui.util.editor +import libbe.util.id + + +class Comment (libbe.command.Command): + """Add a comment to a bug + >>> import time - >>> bd = bugdir.SimpleBugDir() - >>> os.chdir(bd.root) - >>> execute(["a", "This is a comment about a"], manipulate_encodings=False) - >>> bd._clear_bugs() - >>> bug = cmdutil.bug_from_id(bd, "a") + >>> import libbe.bugdir + >>> bd = libbe.bugdir.SimpleBugDir(memory=False) + >>> cmd = Comment() + >>> cmd._setup_io = lambda i_enc,o_enc : None + >>> cmd.stdout = sys.stdout + + >>> cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'}, + ... ['/a', 'This is a comment about a']) + >>> bd.flush_reload() + >>> bug = bd.bug_from_uuid('a') >>> bug.load_comments(load_full=False) >>> comment = bug.comment_root[0] + >>> comment.id.storage() == comment.uuid + True >>> print comment.body This is a comment about a - >>> comment.author == bd.user_id - True + >>> comment.author + u'Fran\\xe7ois' >>> comment.time <= int(time.time()) True >>> comment.in_reply_to is None True >>> if 'EDITOR' in os.environ: - ... del os.environ["EDITOR"] - >>> execute(["b"], manipulate_encodings=False) + ... del os.environ['EDITOR'] + >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) Traceback (most recent call last): UserError: No comment supplied, and EDITOR not specified. - >>> os.environ["EDITOR"] = "echo 'I like cheese' > " - >>> execute(["b"], manipulate_encodings=False) - >>> bd._clear_bugs() - >>> bug = cmdutil.bug_from_id(bd, "b") + >>> os.environ['EDITOR'] = "echo 'I like cheese' > " + >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) + >>> bd.flush_reload() + >>> bug = bd.bug_from_uuid('b') >>> bug.load_comments(load_full=False) >>> comment = bug.comment_root[0] >>> print comment.body @@ -59,65 +72,75 @@ def execute(args, manipulate_encodings=True, restrict_file_access=False, >>> bd.cleanup() """ - parser = get_parser() - options, args = parser.parse_args(args) - complete(options, args, parser) - if len(args) == 0: - raise cmdutil.UsageError("Please specify a bug or comment id.") - if len(args) > 2: - raise cmdutil.UsageError("Too many arguments.") + name = 'comment' - shortname = args[0] - - bd = bugdir.BugDir(from_disk=True, - manipulate_encodings=manipulate_encodings, - root=dir) - bug, parent = cmdutil.bug_comment_from_id(bd, shortname) - - if len(args) == 1: # try to launch an editor for comment-body entry - try: - if parent == bug.comment_root: - parent_body = bug.summary+"\n" - else: - parent_body = parent.body - estr = "Please enter your comment above\n\n> %s\n" \ - % ("\n> ".join(parent_body.splitlines())) - body = editor.editor_string(estr) - except editor.CantFindEditor, e: - raise cmdutil.UserError, "No comment supplied, and EDITOR not specified." - if body is None: - raise cmdutil.UserError("No comment entered.") - elif args[1] == '-': # read body from stdin - binary = not (options.content_type == None - or options.content_type.startswith("text/")) - if not binary: - body = sys.stdin.read() + def __init__(self, *args, **kwargs): + libbe.command.Command.__init__(self, *args, **kwargs) + self.requires_bugdir = True + self.options.extend([ + libbe.command.Option(name='author', short_name='a', + help='Set the comment author', + arg=libbe.command.Argument( + name='author', metavar='AUTHOR')), + libbe.command.Option(name='alt-id', + help='Set an alternate comment ID', + arg=libbe.command.Argument( + name='alt-id', metavar='ID')), + libbe.command.Option(name='content-type', short_name='c', + help='Set comment content-type (e.g. text/plain)', + arg=libbe.command.Argument(name='content-type', + metavar='MIME')), + ]) + self.args.extend([ + libbe.command.Argument( + name='id', metavar='ID', default=None, + completion_callback=libbe.command.util.complete_bug_comment_id), + libbe.command.Argument( + name='comment', metavar='COMMENT', default=None, + optional=True, + completion_callback=libbe.command.util.complete_assigned), + ]) + def _run(self, storage, bugdir, **params): + bug,parent = \ + libbe.command.util.bug_comment_from_user_id(bugdir, params['id']) + if params['comment'] == None: + # try to launch an editor for comment-body entry + try: + if parent == bug.comment_root: + parent_body = bug.summary+'\n' + else: + parent_body = parent.body + estr = 'Please enter your comment above\n\n> %s\n' \ + % ('\n> '.join(parent_body.splitlines())) + body = libbe.ui.util.editor.editor_string(estr) + except libbe.ui.util.editor.CantFindEditor, e: + raise libbe.command.UserError( + 'No comment supplied, and EDITOR not specified.') + if body is None: + raise libbe.command.UserError('No comment entered.') + elif params['comment'] == '-': # read body from stdin + binary = not (params['content-type'] == None + or params['content-type'].startswith("text/")) + if not binary: + body = self.stdin.read() + if not body.endswith('\n'): + body += '\n' + else: # read-in without decoding + body = sys.stdin.read() + else: # body given on command line + body = params['comment'] if not body.endswith('\n'): body+='\n' - else: # read-in without decoding - body = sys.__stdin__.read() - else: # body = arg[1] - body = args[1] - if not body.endswith('\n'): - body+='\n' - - new = parent.new_reply(body=body, content_type=options.content_type) - if options.author != None: - new.author = options.author - if options.alt_id != None: - new.alt_id = options.alt_id + if params['author'] == None: + params['author'] = params['user-id'] -def get_parser(): - parser = cmdutil.CmdOptionParser("be comment ID [COMMENT]") - parser.add_option("-a", "--author", metavar="AUTHOR", dest="author", - help="Set the comment author", default=None) - parser.add_option("--alt-id", metavar="ID", dest="alt_id", - help="Set an alternate comment ID", default=None) - parser.add_option("-c", "--content-type", metavar="MIME", dest="content_type", - help="Set comment content-type (e.g. text/plain)", default=None) - return parser + new = parent.new_reply(body=body) + for key in ['alt-id', 'author', 'content-type']: + if params[key] != None: + setattr(new, key, params[key]) -longhelp=""" + def _long_help(self): + return """ To add a comment to a bug, use the bug ID as the argument. To reply to another comment, specify the comment name (as shown in "be show" output). COMMENT, if specified, should be either the text of your @@ -126,39 +149,3 @@ you do not specify a COMMENT, $EDITOR is used to launch an editor. If COMMENT is unspecified and EDITOR is not set, no comment will be created. """ - -def help(): - return get_parser().help_str() + longhelp - -def complete(options, args, parser): - for option,value in cmdutil.option_value_pairs(options, parser): - if value == "--complete": - # no argument-options at the moment, so this is future-proofing - raise cmdutil.GetCompletions() - for pos,value in enumerate(args): - if value == "--complete": - if pos == 0: # fist positional argument is a bug or comment id - if len(args) >= 2: - partial = args[1].split(':')[0] # take only bugid portion - else: - partial = "" - ids = [] - try: - bd = bugdir.BugDir(from_disk=True, - manipulate_encodings=False) - bugs = [] - for uuid in bd.uuids(): - if uuid.startswith(partial): - bug = bd.bug_from_uuid(uuid) - if bug.active == True: - bugs.append(bug) - for bug in bugs: - shortname = bd.bug_shortname(bug) - ids.append(shortname) - bug.load_comments(load_full=False) - for id,comment in bug.comment_shortnames(shortname): - ids.append(id) - except bugdir.NoBugDir: - pass - raise cmdutil.GetCompletions(ids) - raise cmdutil.GetCompletions() -- cgit From 3e5823d0985a54dec37f103dc72fda604d12a948 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 14 Dec 2009 18:25:28 -0500 Subject: Transitioned import_xml to Command-format --- libbe/command/comment.py | 1 + 1 file changed, 1 insertion(+) (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py index 7a8f5f9..3ec4062 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -100,6 +100,7 @@ class Comment (libbe.command.Command): optional=True, completion_callback=libbe.command.util.complete_assigned), ]) + def _run(self, storage, bugdir, **params): bug,parent = \ libbe.command.util.bug_comment_from_user_id(bugdir, params['id']) -- cgit From 0f87a22c20a019f49455005542d4c60216ce39d2 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 14 Dec 2009 20:13:30 -0500 Subject: Transitioned merge to Command-format --- libbe/command/comment.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py index 3ec4062..23def57 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -37,8 +37,8 @@ class Comment (libbe.command.Command): >>> cmd._setup_io = lambda i_enc,o_enc : None >>> cmd.stdout = sys.stdout - >>> cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'}, - ... ['/a', 'This is a comment about a']) + >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'}, + ... ['/a', 'This is a comment about a']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('a') >>> bug.load_comments(load_full=False) @@ -57,12 +57,12 @@ class Comment (libbe.command.Command): >>> if 'EDITOR' in os.environ: ... del os.environ['EDITOR'] - >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) + >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) Traceback (most recent call last): UserError: No comment supplied, and EDITOR not specified. >>> os.environ['EDITOR'] = "echo 'I like cheese' > " - >>> cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) + >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('b') >>> bug.load_comments(load_full=False) @@ -139,6 +139,7 @@ class Comment (libbe.command.Command): for key in ['alt-id', 'author', 'content-type']: if params[key] != None: setattr(new, key, params[key]) + return 0 def _long_help(self): return """ -- cgit From 1b9c628529848af370adbc67b5ba298236a1b86d Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Mon, 14 Dec 2009 23:15:58 -0500 Subject: Transitioned severity to Command-format, also added Command._get_*() The old .requires_* thing was rediculous. The new ._get_*() callbacks allow the caller to provide a means for getting the expensive structures, which the command can use, or not, as required. This will also make it easier to implement the completion callbacks. The callbacks should probably have matching .set_*() methods, to avoid the current cache tweaking cmd._storage = ... etc. But that can wait for now... --- libbe/command/comment.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py index 23def57..cb0dcbb 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -34,10 +34,11 @@ class Comment (libbe.command.Command): >>> import libbe.bugdir >>> bd = libbe.bugdir.SimpleBugDir(memory=False) >>> cmd = Comment() + >>> cmd._storage = bd.storage >>> cmd._setup_io = lambda i_enc,o_enc : None >>> cmd.stdout = sys.stdout - >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Fran\\xe7ois'}, + >>> ret = cmd.run({'user-id':u'Fran\\xe7ois'}, ... ['/a', 'This is a comment about a']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('a') @@ -57,12 +58,12 @@ class Comment (libbe.command.Command): >>> if 'EDITOR' in os.environ: ... del os.environ['EDITOR'] - >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) + >>> ret = cmd.run({'user-id':u'Frank'}, ['/b']) Traceback (most recent call last): UserError: No comment supplied, and EDITOR not specified. >>> os.environ['EDITOR'] = "echo 'I like cheese' > " - >>> ret = cmd.run(bd.storage, bd, {'user-id':u'Frank'}, ['/b']) + >>> ret = cmd.run({'user-id':u'Frank'}, ['/b']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('b') >>> bug.load_comments(load_full=False) @@ -76,7 +77,6 @@ class Comment (libbe.command.Command): def __init__(self, *args, **kwargs): libbe.command.Command.__init__(self, *args, **kwargs) - self.requires_bugdir = True self.options.extend([ libbe.command.Option(name='author', short_name='a', help='Set the comment author', @@ -101,7 +101,8 @@ class Comment (libbe.command.Command): completion_callback=libbe.command.util.complete_assigned), ]) - def _run(self, storage, bugdir, **params): + def _run(self, **params): + bugdir = self._get_bugdir() bug,parent = \ libbe.command.util.bug_comment_from_user_id(bugdir, params['id']) if params['comment'] == None: @@ -133,7 +134,7 @@ class Comment (libbe.command.Command): if not body.endswith('\n'): body+='\n' if params['author'] == None: - params['author'] = params['user-id'] + params['author'] = self._get_user_id() new = parent.new_reply(body=body) for key in ['alt-id', 'author', 'content-type']: -- 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/comment.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'libbe/command/comment.py') diff --git a/libbe/command/comment.py b/libbe/command/comment.py index cb0dcbb..7b859a8 100644 --- a/libbe/command/comment.py +++ b/libbe/command/comment.py @@ -33,13 +33,14 @@ class Comment (libbe.command.Command): >>> import time >>> import libbe.bugdir >>> bd = libbe.bugdir.SimpleBugDir(memory=False) - >>> cmd = Comment() - >>> cmd._storage = bd.storage - >>> cmd._setup_io = lambda i_enc,o_enc : None - >>> cmd.stdout = sys.stdout + >>> io = libbe.command.StringInputOutput() + >>> io.stdout = sys.stdout + >>> ui = libbe.command.UserInterface(io=io) + >>> ui.storage_callbacks.set_storage(bd.storage) + >>> cmd = Comment(ui=ui) - >>> ret = cmd.run({'user-id':u'Fran\\xe7ois'}, - ... ['/a', 'This is a comment about a']) + >>> ui._user_id = u'Fran\\xe7ois' + >>> ret = ui.run(cmd, args=['/a', 'This is a comment about a']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('a') >>> bug.load_comments(load_full=False) @@ -58,12 +59,13 @@ class Comment (libbe.command.Command): >>> if 'EDITOR' in os.environ: ... del os.environ['EDITOR'] - >>> ret = cmd.run({'user-id':u'Frank'}, ['/b']) + >>> ui._user_id = u'Frank' + >>> ret = ui.run(cmd, args=['/b']) Traceback (most recent call last): UserError: No comment supplied, and EDITOR not specified. >>> os.environ['EDITOR'] = "echo 'I like cheese' > " - >>> ret = cmd.run({'user-id':u'Frank'}, ['/b']) + >>> ret = ui.run(cmd, args=['/b']) >>> bd.flush_reload() >>> bug = bd.bug_from_uuid('b') >>> bug.load_comments(load_full=False) @@ -71,6 +73,7 @@ class Comment (libbe.command.Command): >>> print comment.body I like cheese + >>> ui.cleanup() >>> bd.cleanup() """ name = 'comment' -- cgit