示例#1
0
文件: cli.py 项目: farcaller/pybugz
	def __init__(self, base, user = None, password = None, forget = False,
			columns = 0, encoding = '', skip_auth = False,
			quiet = False, httpuser = None, httppassword = None ):

		self.quiet = quiet
		self.columns = columns or terminal_width()
		
		cp = ConfigParser()
		cp.read(os.path.expanduser('~/.pybugz'))
		defrepo = cp.get('Settings', 'default')
		
		if not base:
		    base = cp.get(defrepo, 'url')
		
		if not user:
			user = cp.get(defrepo, 'user')
			password = cp.get(defrepo, 'password')
		
		Bugz.__init__(self, base, user, password, forget, skip_auth, httpuser, httppassword)

		self.log("Using %s " % self.base)

		if not encoding:
			try:
				self.enc = locale.getdefaultlocale()[1]
			except:
				self.enc = 'utf-8'

			if not self.enc:
				self.enc = 'utf-8'
		else:
			self.enc = encoding
示例#2
0
文件: cli.py 项目: anall/pybugz_dw
	def search(self, *args, **kwds):
		"""Performs a search on the bugzilla database with the keywords given on the title (or the body if specified).
		"""
		search_term = ' '.join(args).strip()
		show_url = kwds['show_url']
		del kwds['show_url']
		search_opts = sorted([(opt, val) for opt, val in kwds.items()
			if val != None and opt != 'order'])

		if not (search_term or search_opts):
			raise BugzError('Please give search terms or options.')

		if search_term:
			log_msg = 'Searching for \'%s\' ' % search_term
		else:
			log_msg = 'Searching for bugs '

		if search_opts:
			self.log(log_msg + 'with the following options:')
			for opt, val in search_opts:
				self.log('   %-20s = %s' % (opt, val))
		else:
			self.log(log_msg)

		result = Bugz.search(self, search_term, **kwds)

		if result == None:
			raise RuntimeError('Failed to perform search')

		if len(result) == 0:
			self.log('No bugs found.')
			return

		self.listbugs(result, show_url)
示例#3
0
文件: cli.py 项目: bhdn/pybugz
	def attach(self, bugid, filename, content_type = 'text/plain', description = None):
		""" Attach a file to a bug given a filename. """
		if not os.path.exists(filename):
			raise BugzError('File not found: %s' % filename)
		if not description:
			description = block_edit('Enter description (optional)')
		result = Bugz.attach(self, bugid, filename, description, filename,
				content_type)
示例#4
0
文件: cli.py 项目: infrabit/pybugz
	def namedcmd(self, command, show_status=False, show_url=False):
		"""Run a command stored in Bugzilla by name."""
		log_msg = 'Running namedcmd \'%s\''%command
		result = Bugz.namedcmd(self, command)
		if result is None:
			raise RuntimeError('Failed to run command\nWrong namedcmd perhaps?')

		if len(result) == 0:
			self.log('No result from command')
			return

		self.listbugs(result, show_url, show_status)
示例#5
0
文件: cli.py 项目: infrabit/pybugz
	def __init__(self, base, user = None, password =None, forget = False,
			columns = 0, encoding = '', skip_auth = False,
			quiet = False, httpuser = None, httppassword = None ):

		self.quiet = quiet
		self.columns = columns or terminal_width()

		Bugz.__init__(self, base, user, password, forget, skip_auth, httpuser, httppassword)

		self.log("Using %s " % self.base)

		if not encoding:
			try:
				self.enc = locale.getdefaultlocale()[1]
			except:
				self.enc = 'utf-8'

			if not self.enc:
				self.enc = 'utf-8'
		else:
			self.enc = encoding
示例#6
0
文件: cli.py 项目: infrabit/pybugz
	def attach(self, bugid, filename, content_type = 'text/plain', patch = False, description = None):
		""" Attach a file to a bug given a filename. """
		if not os.path.exists(filename):
			raise BugzError('File not found: %s' % filename)
		if not description:
			description = block_edit('Enter description (optional)')
		result = Bugz.attach(self, bugid, filename, description, filename,
				content_type, patch)
		if result == True:
			self.log("'%s' has been attached to bug %s" % (filename, bugid))
		else:
			reason = ""
			if result and result != False:
				reason = "\nreason: %s" % result
			raise RuntimeError("Failed to attach '%s' to bug %s%s" % (filename,
				bugid, reason))
示例#7
0
文件: cli.py 项目: infrabit/pybugz
	def attachment(self, attachid, view = False):
		""" Download or view an attachment given the id."""
		self.log('Getting attachment %s' % attachid)

		result = Bugz.attachment(self, attachid)
		if not result:
			raise RuntimeError('Unable to get attachment')

		action = {True:'Viewing', False:'Saving'}
		self.log('%s attachment: "%s"' % (action[view], result['filename']))
		safe_filename = os.path.basename(re.sub(r'\.\.', '',
												result['filename']))

		if view:
			print result['fd'].read()
		else:
			if os.path.exists(result['filename']):
				raise RuntimeError('Filename already exists')

			open(safe_filename, 'wb').write(result['fd'].read())
示例#8
0
文件: cli.py 项目: apepper/pybugz
    def attachment(self, attachid, view=False):
        """ Download or view an attachment given the id."""
        self.log('Getting attachment %s' % attachid)

        result = Bugz.attachment(self, attachid)
        if not result:
            raise RuntimeError('Unable to get attachment')

        action = {True: 'Viewing', False: 'Saving'}
        self.log('%s attachment: "%s"' % (action[view], result['filename']))
        safe_filename = os.path.basename(
            re.sub(r'\.\.', '', result['filename']))

        if view:
            print result['fd'].read()
        else:
            if os.path.exists(result['filename']):
                raise RuntimeError('Filename already exists')

            open(safe_filename, 'wb').write(result['fd'].read())
示例#9
0
文件: cli.py 项目: apepper/pybugz
 def attach(self,
            bugid,
            filename,
            content_type='text/plain',
            patch=False,
            description=None):
     """ Attach a file to a bug given a filename. """
     if not os.path.exists(filename):
         raise BugzError('File not found: %s' % filename)
     if not description:
         description = block_edit('Enter description (optional)')
     result = Bugz.attach(self, bugid, filename, description, filename,
                          content_type, patch)
     if result == True:
         self.log("'%s' has been attached to bug %s" % (filename, bugid))
     else:
         reason = ""
         if result and result != False:
             reason = "\nreason: %s" % result
         raise RuntimeError("Failed to attach '%s' to bug %s%s" %
                            (filename, bugid, reason))
示例#10
0
文件: cli.py 项目: apepper/pybugz
    def search(self, **kwds):
        """Performs a search on the bugzilla database with the keywords given on the title (or the body if specified).
		"""
        search_term = ' '.join(kwds['terms']).strip()
        del kwds['terms']
        show_status = kwds['show_status']
        del kwds['show_status']
        show_url = kwds['show_url']
        del kwds['show_url']
        show_only_bug_id = kwds['show_only_bug_id']
        del kwds['show_only_bug_id']
        search_opts = sorted([(opt, val) for opt, val in kwds.items()
                              if val != None and opt != 'order'])

        if not (search_term or search_opts):
            raise BugzError('Please give search terms or options.')

        if search_term:
            log_msg = 'Searching for \'%s\' ' % search_term
        else:
            log_msg = 'Searching for bugs '

        if search_opts:
            self.log(log_msg + 'with the following options:')
            for opt, val in search_opts:
                self.log('   %-20s = %s' % (opt, val))
        else:
            self.log(log_msg)

        result = Bugz.search(self, search_term, **kwds)

        if result == None:
            raise RuntimeError('Failed to perform search')

        if len(result) == 0:
            self.log('No bugs found.')
            return

        self.listbugs(result, show_url, show_status, show_only_bug_id)
示例#11
0
文件: cli.py 项目: infrabit/pybugz
	def get(self, bugid, comments = True, attachments = True):
		""" Fetch bug details given the bug id """
		self.log('Getting bug %s ..' % bugid)

		result = Bugz.get(self, bugid)

		if result is None:
			raise RuntimeError('Bug %s not found' % bugid)

		# Print out all the fields below by extract the text
		# directly from the tag, and just ignore if we don't
		# see the tag.
		FIELDS = (
			('short_desc', 'Title'),
			('assigned_to', 'Assignee'),
			('creation_ts', 'Reported'),
			('delta_ts', 'Updated'),
			('bug_status', 'Status'),
			('resolution', 'Resolution'),
			('bug_file_loc', 'URL'),
			('bug_severity', 'Severity'),
			('priority', 'Priority'),
			('reporter', 'Reporter'),
		)

		MORE_FIELDS = (
			('product', 'Product'),
			('component', 'Component'),
			('status_whiteboard', 'Whiteboard'),
			('keywords', 'Keywords'),
		)

		for field, name in FIELDS + MORE_FIELDS:
			try:
				value = result.find('.//%s' % field).text
				if value is None:
						continue
			except AttributeError:
				continue
			print '%-12s: %s' % (name, value.encode(self.enc))

		# Print out the cc'ed people
		cced = result.findall('.//cc')
		for cc in cced:
			print '%-12s: %s' %  ('CC', cc.text)

		# print out depends
		dependson = ', '.join([d.text for d in result.findall('.//dependson')])
		blocked = ', '.join([d.text for d in result.findall('.//blocked')])
		if dependson:
			print '%-12s: %s' % ('DependsOn', dependson)
		if blocked:
			print '%-12s: %s' % ('Blocked', blocked)

		bug_comments = result.findall('.//long_desc')
		bug_attachments = result.findall('.//attachment')

		print '%-12s: %d' % ('Comments', len(bug_comments))
		print '%-12s: %d' % ('Attachments', len(bug_attachments))
		print

		if attachments:
			for attachment in bug_attachments:
				aid = attachment.find('.//attachid').text
				desc = attachment.find('.//desc').text
				when = attachment.find('.//date').text
				print '[Attachment] [%s] [%s]' % (aid, desc.encode(self.enc))

		if comments:
			i = 0
			wrapper = textwrap.TextWrapper(width = self.columns)
			for comment in bug_comments:
				try:
					who = comment.find('.//who').text.encode(self.enc)
				except AttributeError:
					# Novell doesn't use 'who' on xml
					who = ""
				when = comment.find('.//bug_when').text.encode(self.enc)
				what =  comment.find('.//thetext').text
				print '\n[Comment #%d] %s : %s'  % (i, who, when)
				print '-' * (self.columns - 1)

				if what is None:
					what = ''

				# print wrapped version
				for line in what.split('\n'):
					if len(line) < self.columns:
						print line.encode(self.enc)
					else:
						for shortline in wrapper.wrap(line):
							print shortline.encode(self.enc)
				i += 1
			print
示例#12
0
文件: cli.py 项目: infrabit/pybugz
		if 'comment_editor' in kwds:
			if kwds['comment_editor']:
				kwds['comment'] = block_edit('Enter comment:')
			del kwds['comment_editor']

		if kwds['fixed']:
			kwds['status'] = 'RESOLVED'
			kwds['resolution'] = 'FIXED'
		del kwds['fixed']

		if kwds['invalid']:
			kwds['status'] = 'RESOLVED'
			kwds['resolution'] = 'INVALID'
		del kwds['invalid']
		result = Bugz.modify(self, bugid, **kwds)
		if not result:
			raise RuntimeError('Failed to modify bug')
		else:
			self.log('Modified bug %s with the following fields:' % bugid)
			for field, value in result:
				self.log('  %-12s: %s' % (field, value))

	def attachment(self, attachid, view = False):
		""" Download or view an attachment given the id."""
		self.log('Getting attachment %s' % attachid)

		result = Bugz.attachment(self, attachid)
		if not result:
			raise RuntimeError('Unable to get attachment')
示例#13
0
	def get(self, bugid, comments = True, attachments = True):
		""" Fetch bug details given the bug id """
		self.log('Getting bug %s ..' % bugid)

		result = Bugz.get(self, bugid)

		if result == None:
			raise RuntimeError('Bug %s not found' % bugid)

		# Print out all the fields below by extract the text
		# directly from the tag, and just ignore if we don't
		# see the tag.
		FIELDS = (
			('short_desc', 'Title'),
			('assigned_to', 'Assignee'),
			('creation_ts', 'Reported'),
			('delta_ts', 'Updated'),
			('bug_status', 'Status'),
			('resolution', 'Resolution'),
			('bug_file_loc', 'URL'),
			('bug_severity', 'Severity'),
			('priority', 'Priority'),
			('reporter', 'Reporter'),
		)

		MORE_FIELDS = (
			('product', 'Product'),
			('component', 'Component'),
			('status_whiteboard', 'Whiteboard'),
			('keywords', 'Keywords'),
		)

		for field, name in FIELDS + MORE_FIELDS:
			try:
				value = result.find('//%s' % field).text
			except AttributeError:
				continue
			print '%-12s: %s' % (name, value.encode(self.enc))

		# Print out the cc'ed people
		cced = result.findall('.//cc')
		for cc in cced:
			print '%-12s: %s' %  ('CC', cc.text)

		# print out depends
		dependson = ', '.join([d.text for d in result.findall('.//dependson')])
		blocked = ', '.join([d.text for d in result.findall('.//blocked')])
		if dependson:
			print '%-12s: %s' % ('DependsOn', dependson)
		if blocked:
			print '%-12s: %s' % ('Blocked', blocked)

		bug_comments = result.findall('//long_desc')
		bug_attachments = result.findall('//attachment')

		print '%-12s: %d' % ('Comments', len(bug_comments))
		print '%-12s: %d' % ('Attachments', len(bug_attachments))
		print '%-12s: %s' % ('URL', '%s?id=%s' % (urljoin(self.base,
													config.urls['show']),
													bugid))
		print

		if attachments:
			for attachment in bug_attachments:
				aid = attachment.find('.//attachid').text
				desc = attachment.find('.//desc').text
				when = attachment.find('.//date').text
				print '[Attachment] [%s] [%s]' % (aid, desc.encode(self.enc))

		if comments:
			i = 0
			wrapper = textwrap.TextWrapper(width = self.columns)
			for comment in bug_comments:
				try:
					who = comment.find('.//who').text.encode(self.enc)
				except AttributeError:
					# Novell doesn't use 'who' on xml
					who = ""
				when = comment.find('.//bug_when').text.encode(self.enc)
				what =  comment.find('.//thetext').text
				print '\n[Comment #%d] %s : %s'  % (i, who, when)
				print '-' * (self.columns - 1)

				if what is None:
					what = ''

				# print wrapped version
				for line in what.split('\n'):
					if len(line) < self.columns:
						print line.encode(self.enc)
					else:
						for shortline in wrapper.wrap(line):
							print shortline.encode(self.enc)
				i += 1
			print
示例#14
0
class PrettyBugz(Bugz):
	options = {
		'base': make_option('-b', '--base', type='string',
							default = 'https://bugs.gentoo.org/',
							help = 'Base URL of Bugzilla'),
		'user': make_option('-u', '--user', type='string',
							help = 'Username for commands requiring authentication'),
		'password': make_option('-p', '--password', type='string',
							help = 'Password for commands requiring authentication'),
		'httpuser': make_option('-H', '--httpuser', type='string',
							help = 'Username for basic http auth'),
		'httppassword': make_option('-P', '--httppassword', type='string',
							help = 'Password for basic http auth'),
		'forget': make_option('-f', '--forget', action='store_true',
							help = 'Forget login after execution'),
		'columns': make_option('--columns', type='int', default = 0,
							help = 'Maximum number of columns output should use'),
		'encoding': make_option('--encoding',
							help = 'Output encoding (default: utf-8).'),
		'skip_auth': make_option('--skip-auth', action='store_true',
							default = False, help = 'Skip Authentication.'),
		'quiet': make_option('-q', '--quiet', action='store_true',
							default = False, help = 'Quiet mode'),
	}

	def __init__(self, base, user = None, password =None, forget = False,
			columns = 0, encoding = '', skip_auth = False,
			quiet = False, httpuser = None, httppassword = None ):

		self.quiet = quiet
		self.columns = columns or terminal_width()

		Bugz.__init__(self, base, user, password, forget, skip_auth, httpuser, httppassword)

		self.log("Using %s " % self.base)

		if not encoding:
			try:
				self.enc = locale.getdefaultlocale()[1]
			except:
				self.enc = 'utf-8'

			if not self.enc:
				self.enc = 'utf-8'
		else:
			self.enc = encoding

	def log(self, status_msg, newline = True):
		if not self.quiet:
			if newline:
				print ' * %s' % status_msg
			else:
				print ' * %s' % status_msg,

	def warn(self, warn_msg):
		if not self.quiet:
			print ' ! Warning: %s' % warn_msg

	def get_input(self, prompt):
		return raw_input(prompt)

	def search(self, *args, **kwds):
		"""Performs a search on the bugzilla database with the keywords given on the title (or the body if specified).
		"""
		search_term = ' '.join(args).strip()
		show_status = kwds['show_status']
		del kwds['show_status']
		show_url = kwds['show_url']
		del kwds['show_url']
		search_opts = sorted([(opt, val) for opt, val in kwds.items()
			if val != None and opt != 'order'])

		if not (search_term or search_opts):
			raise BugzError('Please give search terms or options.')

		if search_term:
			log_msg = 'Searching for \'%s\' ' % search_term
		else:
			log_msg = 'Searching for bugs '

		if search_opts:
			self.log(log_msg + 'with the following options:')
			for opt, val in search_opts:
				self.log('   %-20s = %s' % (opt, val))
		else:
			self.log(log_msg)

		result = Bugz.search(self, search_term, **kwds)

		if result == None:
			raise RuntimeError('Failed to perform search')

		if len(result) == 0:
			self.log('No bugs found.')
			return

		self.listbugs(result, show_url, show_status)

	search.args = "<search term> [options..]"
	search.options = {
		'order': make_option('-o', '--order', type='choice',
								choices = config.choices['order'].keys(),
								default = 'number'),
		'assigned_to': make_option('-a', '--assigned-to',
								help = 'email the bug is assigned to'),
		'reporter': make_option('-r', '--reporter',
								help = 'email the bug was reported by'),
		'cc': make_option('--cc',help = 'Restrict by CC email address'),
		'commenter': make_option('--commenter',help = 'email that commented the bug'),
		'status': make_option('-s', '--status', action='append',
								help = 'Bug status (for multiple choices,'
								'use --status=NEW --status=ASSIGNED) or --status=all for all statuses'),
		'severity': make_option('--severity', action='append',
								choices = config.choices['severity'],
								help = 'Restrict by severity.'),
		'priority': make_option('--priority', action='append',
								choices = config.choices['priority'].values(),
								help = 'Restrict by priority (1 or more)'),
		'comments': make_option('-c', '--comments',  action='store_true',
								help = 'Search comments instead of title'),
		'product': make_option('--product', action='append',
								help = 'Restrict by product (1 or more)'),
		'component': make_option('-C', '--component', action='append',
								help = 'Restrict by component (1 or more)'),
		'keywords': make_option('-k', '--keywords', help = 'Bug keywords'),
		'whiteboard': make_option('-w', '--whiteboard',
								help = 'Status whiteboard'),
		'show_status': make_option('--show-status', help='show status of bugs',
								action = 'store_true', default = False),
		'show_url': make_option('--show-url', help='Show bug id as a url.',
								action = 'store_true', default = False),
	}

	def namedcmd(self, command, show_status=False, show_url=False):
		"""Run a command stored in Bugzilla by name."""
		log_msg = 'Running namedcmd \'%s\''%command
		result = Bugz.namedcmd(self, command)
		if result == None:
			raise RuntimeError('Failed to run command\nWrong namedcmd perhaps?')

		if len(result) == 0:
			self.log('No result from command')
			return

		self.listbugs(result, show_url, show_status)

	namedcmd.args = "<command name>"
	namedcmd.options = {
		'show_status': make_option('--show-status', help='show status of bugs',
								action = 'store_true', default = False),
		'show_url': make_option('--show-url', help='Show bug id as a url.',
								action = 'store_true', default = False),
	}

	def get(self, bugid, comments = True, attachments = True):
		""" Fetch bug details given the bug id """
		self.log('Getting bug %s ..' % bugid)

		result = Bugz.get(self, bugid)

		if result == None:
			raise RuntimeError('Bug %s not found' % bugid)

		# Print out all the fields below by extract the text
		# directly from the tag, and just ignore if we don't
		# see the tag.
		FIELDS = (
			('short_desc', 'Title'),
			('assigned_to', 'Assignee'),
			('creation_ts', 'Reported'),
			('delta_ts', 'Updated'),
			('bug_status', 'Status'),
			('resolution', 'Resolution'),
			('bug_file_loc', 'URL'),
			('bug_severity', 'Severity'),
			('priority', 'Priority'),
			('reporter', 'Reporter'),
		)

		MORE_FIELDS = (
			('product', 'Product'),
			('component', 'Component'),
			('status_whiteboard', 'Whiteboard'),
			('keywords', 'Keywords'),
		)

		for field, name in FIELDS + MORE_FIELDS:
			try:
				value = result.find('//%s' % field).text
			except AttributeError:
				continue
			print '%-12s: %s' % (name, value.encode(self.enc))

		# Print out the cc'ed people
		cced = result.findall('.//cc')
		for cc in cced:
			print '%-12s: %s' %  ('CC', cc.text)

		# print out depends
		dependson = ', '.join([d.text for d in result.findall('.//dependson')])
		blocked = ', '.join([d.text for d in result.findall('.//blocked')])
		if dependson:
			print '%-12s: %s' % ('DependsOn', dependson)
		if blocked:
			print '%-12s: %s' % ('Blocked', blocked)

		bug_comments = result.findall('//long_desc')
		bug_attachments = result.findall('//attachment')

		print '%-12s: %d' % ('Comments', len(bug_comments))
		print '%-12s: %d' % ('Attachments', len(bug_attachments))
		print '%-12s: %s' % ('URL', '%s?id=%s' % (urljoin(self.base,
													config.urls['show']),
													bugid))
		print

		if attachments:
			for attachment in bug_attachments:
				aid = attachment.find('.//attachid').text
				desc = attachment.find('.//desc').text
				when = attachment.find('.//date').text
				print '[Attachment] [%s] [%s]' % (aid, desc.encode(self.enc))

		if comments:
			i = 0
			wrapper = textwrap.TextWrapper(width = self.columns)
			for comment in bug_comments:
				try:
					who = comment.find('.//who').text.encode(self.enc)
				except AttributeError:
					# Novell doesn't use 'who' on xml
					who = ""
				when = comment.find('.//bug_when').text.encode(self.enc)
				what =  comment.find('.//thetext').text
				print '\n[Comment #%d] %s : %s'  % (i, who, when)
				print '-' * (self.columns - 1)

				if what is None:
					what = ''

				# print wrapped version
				for line in what.split('\n'):
					if len(line) < self.columns:
						print line.encode(self.enc)
					else:
						for shortline in wrapper.wrap(line):
							print shortline.encode(self.enc)
				i += 1
			print

	get.args = "<bug_id> [options..]"
	get.options = {
		'comments': make_option("-n", "--no-comments", dest = 'comments',
								action="store_false", default = True,
								help = 'Do not show comments'),
	}

	def post(self, product = None, component = None,
			title = None, description = None, assigned_to = None,
			cc = None, url = None, keywords = None,
			description_from = None, prodversion = None, append_command = None,
			dependson = None, blocked = None, batch = False,
			default_confirm = 'y', priority = None, severity = None):
		"""Post a new bug"""

		# load description from file if possible
		if description_from:
			try:
				description = open(description_from, 'r').read()
			except IOError, e:
				raise BugzError('Unable to read from file: %s: %s' % \
								(description_from, e))

		if not batch:
			self.log('Press Ctrl+C at any time to abort.')

			#
			#  Check all bug fields.
			#  XXX: We use "if not <field>" for mandatory fields
			#       and "if <field> is None" for optional ones.
			#

			# check for product
			if not product:
				while not product or len(product) < 1:
					product = self.get_input('Enter product: ')
			else:
				self.log('Enter product: %s' % product)

			# check for version
			# FIXME: This default behaviour is not too nice.
			if prodversion is None:
				prodversion = self.get_input('Enter version (default: unspecified): ')
			else:
				self.log('Enter version: %s' % prodversion)

			# check for component
			if not component:
				while not component or len(component) < 1:
					component = self.get_input('Enter component: ')
			else:
				self.log('Enter component: %s' % component)

			# check for default priority
			if priority is None:
				priority_msg ='Enter priority (eg. P2) (optional): '
				priority = self.get_input(priority_msg)
			else:
				self.log('Enter priority (optional): %s' % priority)

			# check for default severity
			if severity is None:
				severity_msg ='Enter severity (eg. normal) (optional): '
				severity = self.get_input(severity_msg)
			else:
				self.log('Enter severity (optional): %s' % severity)

			# check for default assignee
			if assigned_to is None:
				assigned_msg ='Enter assignee (eg. [email protected]) (optional): '
				assigned_to = self.get_input(assigned_msg)
			else:
				self.log('Enter assignee (optional): %s' % assigned_to)

			# check for CC list
			if cc is None:
				cc_msg = 'Enter a CC list (comma separated) (optional): '
				cc = self.get_input(cc_msg)
			else:
				self.log('Enter a CC list (optional): %s' % cc)

			# check for optional URL
			if url is None:
				url = self.get_input('Enter URL (optional): ')
			else:
				self.log('Enter URL (optional): %s' % url)

			# check for title
			if not title:
				while not title or len(title) < 1:
					title = self.get_input('Enter title: ')
			else:
				self.log('Enter title: %s' % title)

			# check for description
			if not description:
				description = block_edit('Enter bug description: ')
			else:
				self.log('Enter bug description: %s' % description)

			if append_command is None:
				append_command = self.get_input('Append the output of the following command (leave blank for none): ')
			else:
				self.log('Append command (optional): %s' % append_command)

			# check for Keywords list
			if keywords is None:
				kwd_msg = 'Enter a Keywords list (comma separated) (optional): '
				keywords = self.get_input(kwd_msg)
			else:
				self.log('Enter a Keywords list (optional): %s' % keywords)

			# check for bug dependencies
			if dependson is None:
				dependson_msg = 'Enter a list of bug dependencies (comma separated) (optional): '
				dependson = self.get_input(dependson_msg)
			else:
				self.log('Enter a list of bug dependencies (optional): %s' % dependson)

			# check for blocker bugs
			if blocked is None:
				blocked_msg = 'Enter a list of blocker bugs (comma separated) (optional): '
				blocked = self.get_input(blocked_msg)
			else:
				self.log('Enter a list of blocker bugs (optional): %s' % blocked)

		# append the output from append_command to the description
		if append_command is not None and append_command != '':
			append_command_output = commands.getoutput(append_command)
			description = description + '\n\n' + '$ ' + append_command + '\n' +  append_command_output

		# raise an exception if mandatory fields are not specified.
		if product is None:
			raise RuntimeError('Product not specified')
		if component is None:
			raise RuntimeError('Component not specified')
		if title is None:
			raise RuntimeError('Title not specified')
		if description is None:
			raise RuntimeError('Description not specified')

		# set optional fields to their defaults if they are not set.
		if prodversion is None:
			prodversion = ''
		if priority is None:
			priority = ''
		if severity is None:
			severity = ''
		if assigned_to is None:
			assigned_to = ''
		if cc is None:
			cc = ''
		if url is None:
			url = ''
		if keywords is None:
			keywords = ''
		if dependson is None:
			dependson = ''
		if blocked is None:
			blocked = ''

		# print submission confirmation
		print '-' * (self.columns - 1)
		print 'Product     : ' + product
		print 'Version     : ' + prodversion
		print 'Component   : ' + component
		print 'priority    : ' + priority
		print 'severity    : ' + severity
		print 'Assigned to : ' + assigned_to
		print 'CC          : ' + cc
		print 'URL         : ' + url
		print 'Title       : ' + title
		print 'Description : ' + description
		print 'Keywords    : ' + keywords
		print 'Depends on  : ' + dependson
		print 'Blocks      : ' + blocked
		print '-' * (self.columns - 1)

		if not batch:
			if default_confirm in ['Y','y']:
				confirm = raw_input('Confirm bug submission (Y/n)? ')
			else:
				confirm = raw_input('Confirm bug submission (y/N)? ')
			if len(confirm) < 1:
				confirm = default_confirm
			if confirm[0] not in ('y', 'Y'):
				self.log('Submission aborted')
				return

		result = Bugz.post(self, product, component, title, description, url, assigned_to, cc, keywords, prodversion, dependson, blocked, priority, severity)
		if result != None and result != 0:
			self.log('Bug %d submitted' % result)
		else:
			raise RuntimeError('Failed to submit bug')
示例#15
0
					raise BugzError('Failed to get read from file: %s: %s' % \
									(comment_from, e))

				if 'comment_editor' in kwds:
					if kwds['comment_editor']:
						kwds['comment'] = block_edit('Enter comment:', kwds['comment'])
						del kwds['comment_editor']

			del kwds['comment_from']

		if 'comment_editor' in kwds:
			if kwds['comment_editor']:
				kwds['comment'] = block_edit('Enter comment:')
			del kwds['comment_editor']

		result = Bugz.modify(self, bugid, **kwds)
		if not result:
			raise RuntimeError('Failed to modify bug')
		else:
			self.log('Modified bug %s with the following fields:' % bugid)
			for field, value in result:
				self.log('  %-12s: %s' % (field, value))


	modify.args = "<bug_id> [options..]"
	modify.options = {
		'title': make_option('-t', '--title', help = 'Set title of bug'),
		'comment_from': make_option('-F', '--comment-from',
									help = 'Add comment from file.  If -C is also specified, the editor will be opened with this file as its contents.'),
		'comment_editor': make_option('-C', '--comment-editor',
									action='store_true', default = False,