def add_comment_interactive(self, ticket, comment=''): r""" Add a comment to ``ticket`` on trac. INPUT: - ``comment`` -- a string (default: ``''``), the default value for the comment to add. EXAMPLES:: sage: from sage.dev.test.config import DoctestConfig sage: from sage.dev.test.user_interface import DoctestUserInterface sage: from sage.dev.test.trac_interface import DoctestTracInterface sage: from sage.dev.test.trac_server import DoctestTracServer sage: config = DoctestConfig() sage: config['trac']['password'] = '******' sage: UI = DoctestUserInterface(config['UI']) sage: trac = DoctestTracInterface(config['trac'], UI, DoctestTracServer()) sage: ticket = trac.create_ticket('Summary', 'Description', {'type':'defect', 'component':'algebra'}) sage: UI.append("# empty comment") sage: trac.add_comment_interactive(ticket) Traceback (most recent call last): ... OperationCancelledError: comment creation aborted sage: UI.append("a comment") sage: trac.add_comment_interactive(ticket) """ ticket = int(ticket) attributes = self._get_attributes(ticket) from sage.dev.misc import tmp_filename filename = tmp_filename() with open(filename, "w") as f: f.write(comment) f.write("\n") f.write(COMMENT_FILE_GUIDE) self._UI.edit(filename) comment = list(open(filename).read().splitlines()) comment = [line for line in comment if not line.startswith("#")] if all([line.strip() == "" for line in comment]): from user_interface_error import OperationCancelledError raise OperationCancelledError("comment creation aborted") comment = "\n".join(comment) url = self._authenticated_server_proxy.ticket.update( ticket, comment, attributes, True) # notification e-mail sent self._UI.debug("Your comment has been recorded: %s" % url)
def add_comment_interactive(self, ticket, comment=''): r""" Add a comment to ``ticket`` on trac. INPUT: - ``comment`` -- a string (default: ``''``), the default value for the comment to add. EXAMPLES:: sage: from sage.dev.test.config import DoctestConfig sage: from sage.dev.test.user_interface import DoctestUserInterface sage: from sage.dev.test.trac_interface import DoctestTracInterface sage: from sage.dev.test.trac_server import DoctestTracServer sage: config = DoctestConfig() sage: config['trac']['password'] = '******' sage: UI = DoctestUserInterface(config['UI']) sage: trac = DoctestTracInterface(config['trac'], UI, DoctestTracServer()) sage: ticket = trac.create_ticket('Summary', 'Description', {'type':'defect', 'component':'algebra'}) sage: UI.append("# empty comment") sage: trac.add_comment_interactive(ticket) Traceback (most recent call last): ... OperationCancelledError: comment creation aborted sage: UI.append("a comment") sage: trac.add_comment_interactive(ticket) """ ticket = int(ticket) attributes = self._get_attributes(ticket) from sage.dev.misc import tmp_filename filename = tmp_filename() with open(filename, "w") as f: f.write(comment) f.write("\n") f.write(COMMENT_FILE_GUIDE) self._UI.edit(filename) comment = list(open(filename).read().splitlines()) comment = [line for line in comment if not line.startswith("#")] if all([line.strip()=="" for line in comment]): from user_interface_error import OperationCancelledError raise OperationCancelledError("comment creation aborted") comment = "\n".join(comment) url = self._authenticated_server_proxy.ticket.update(ticket, comment, attributes, True) # notification e-mail sent self._UI.debug("Your comment has been recorded: %s"%url)
def _edit_ticket_interactive(self, summary, description, attributes): r""" Helper method for :meth:`edit_ticket_interactive` and :meth:`create_ticket_interactive`. INPUT: - ``summary`` -- a string, summary of ticket - ``description`` -- a string, description of ticket - ``attributes`` -- dictionary containing field, value pairs OUTPUT: A tuple ``(summary, description, attributes)``, the updated version of input after user has edited the ticket. TESTS:: sage: from sage.dev.test.config import DoctestConfig sage: from sage.dev.test.user_interface import DoctestUserInterface sage: from sage.dev.trac_interface import TracInterface sage: config = DoctestConfig() sage: UI = DoctestUserInterface(config['UI']) sage: trac = TracInterface(config['trac'], UI) sage: UI.append("# abort") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) Traceback (most recent call last): ... OperationCancelledError: ticket edit aborted sage: UI.append("Summary: new summary\nBranch: branch2\nnew description") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) ('new summary', 'new description', {'branch': 'branch2'}) sage: UI.append("Summary: new summary\nBranch: branch2\nnew description") sage: UI.append("") sage: UI.append("Summary: new summary\nInvalid: branch2\nnew description") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) Syntax error: field "Invalid" not supported on line 2 Edit ticket file again? [Yes/no] ('new summary', 'new description', {'branch': 'branch2'}) """ from sage.dev.misc import tmp_filename filename = tmp_filename() try: with open(filename, "w") as F: F.write("Summary: %s\n" % summary.encode('utf-8')) for k, v in attributes.items(): k = ALLOWED_FIELDS.get(k.lower()) if k is not None: F.write("%s: %s\n" % (k.encode('utf-8'), v.encode('utf-8'))) if description is None or not description.strip(): description = "\nADD DESCRIPTION\n" F.write("\n" + description.encode('utf-8') + "\n") F.write(TICKET_FILE_GUIDE) while True: try: self._UI.edit(filename) ret = self._parse_ticket_file(filename) break except (RuntimeError, TicketSyntaxError) as error: pass self._UI.error("Syntax error: " + error.message) if not self._UI.confirm("Edit ticket file again?", default=True): ret = None break if ret is None: from user_interface_error import OperationCancelledError raise OperationCancelledError("ticket edit aborted") finally: os.unlink(filename) return ret
def _edit_ticket_interactive(self, summary, description, attributes): r""" Helper method for :meth:`edit_ticket_interactive` and :meth:`create_ticket_interactive`. INPUT: - ``summary`` -- a string, summary of ticket - ``description`` -- a string, description of ticket - ``attributes`` -- dictionary containing field, value pairs OUTPUT: A tuple ``(summary, description, attributes)``, the updated version of input after user has edited the ticket. TESTS:: sage: from sage.dev.test.config import DoctestConfig sage: from sage.dev.test.user_interface import DoctestUserInterface sage: from sage.dev.trac_interface import TracInterface sage: config = DoctestConfig() sage: UI = DoctestUserInterface(config['UI']) sage: trac = TracInterface(config['trac'], UI) sage: UI.append("# abort") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) Traceback (most recent call last): ... OperationCancelledError: ticket edit aborted sage: UI.append("Summary: new summary\nBranch: branch2\nnew description") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) ('new summary', 'new description', {'branch': 'branch2'}) sage: UI.append("Summary: new summary\nBranch: branch2\nnew description") sage: UI.append("") sage: UI.append("Summary: new summary\nInvalid: branch2\nnew description") sage: trac._edit_ticket_interactive('summary', 'description', {'branch':'branch1'}) Syntax error: field "Invalid" not supported on line 2 Edit ticket file again? [Yes/no] ('new summary', 'new description', {'branch': 'branch2'}) """ from sage.dev.misc import tmp_filename filename = tmp_filename() try: with open(filename, "w") as F: F.write("Summary: %s\n"%summary.encode('utf-8')) for k,v in attributes.items(): k = ALLOWED_FIELDS.get(k.lower()) if k is not None: F.write("%s: %s\n"%(k,v)) if description is None or not description.strip(): description = "\nADD DESCRIPTION\n" F.write("\n" + description.encode('utf-8') + "\n") F.write(TICKET_FILE_GUIDE) while True: try: self._UI.edit(filename) ret = self._parse_ticket_file(filename) break except (RuntimeError, TicketSyntaxError) as error: pass self._UI.error("Syntax error: " + error.message) if not self._UI.confirm("Edit ticket file again?", default=True): ret = None break if ret is None: from user_interface_error import OperationCancelledError raise OperationCancelledError("ticket edit aborted") finally: os.unlink(filename) return ret