From 05e77b608c9eb898004f5c193e18cda28203e422 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Thu, 5 Jun 2008 16:05:20 -0400 Subject: Add a whole bunch of useful flags, courtesy of Chris Ward at Red Hat --- bin/bugzilla | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 138 insertions(+), 25 deletions(-) (limited to 'bin') diff --git a/bin/bugzilla b/bin/bugzilla index af4bb3b..060820b 100755 --- a/bin/bugzilla +++ b/bin/bugzilla @@ -14,7 +14,7 @@ import bugzilla, optparse import os, sys, glob, re import logging -version = '0.2' +version = '0.3' default_bz = 'https://bugzilla.redhat.com/xmlrpc.cgi' # Initial simple logging stuff @@ -84,33 +84,76 @@ def setup_action_parser(action): help="OPTIONAL: URL for further bug info") p.add_option('--cc', help="OPTIONAL: add emails to initial CC list") - # TODO: alias, assigned_to, reporter, qa_contact, dependson, blocked + elif action == 'query': + # General bug metadata + p.add_option('-b','--bug_id', + help="specify individual bugs by IDs, separated with commas") p.add_option('-p','--product', - help="product name (list with 'bugzilla info -p')") + help="product name, comma-separated (list with 'bugzilla info -p')") p.add_option('-v','--version', help="product version") p.add_option('-c','--component', - help="component name (list with 'bugzilla info -c PRODUCT')") + help="component name(s), comma-separated (list with 'bugzilla info -c PRODUCT')") + p.add_option('--components_file', + help="list of component names from a file, one component per line (list with 'bugzilla info -c PRODUCT')") p.add_option('-l','--long_desc', help="search inside bug comments") p.add_option('-s','--short_desc', help="search bug summaries") + p.add_option('-t','--bug_status',default="NEW", + help="comma-separated list of bug statuses to accept [Default:NEW] [Available:NEW,ASSIGNED,NEEDINFO,ON_DEV,MODIFIED,POST,ON_QA,FAILS_QA,PASSES_QA,REOPENED,VERIFIED,RELEASE_PENDING,CLOSED]") + p.add_option('-x','--severity', + help="search severities, comma-separated") + p.add_option('-z','--priority', + help="search priorities, comma-separated") + + # Email + p.add_option('-E','--emailtype', + help="Email: specify searching option for emails, ie. substring,notsubstring,exact,... [Default: substring]",default="substring") p.add_option('-o','--cc', - help="search cc lists for given address") + help="Email: search cc lists for given address") p.add_option('-r','--reporter', - help="search for bugs reported by this address") + help="Email: search reporter email for given address") p.add_option('-a','--assigned_to', - help="search for bugs assigned to this address") + help="Email: search for bugs assigned to this address") + p.add_option('-q','--qa_contact', + help="Email: search for bugs which have QA Contact assigned to this address") + + # Strings + p.add_option('-u','--url', + help="search keywords field for given url") + p.add_option('-U','--url_type', + help="specify searching option for urls, ie. anywords,allwords,nowords") + p.add_option('-k','--keywords', + help="search keywords field for specified words") + p.add_option('-K','--keywords_type', + help="specify searching option for keywords, ie. anywords,allwords,nowords") + p.add_option('-w','--status_whiteboard', + help="search Status Whiteboard field for specified words") + p.add_option('-W','--status_whiteboard_type', + help="specify searching option for Status Whiteboard, ie. anywords,allwords,nowords") + + # Boolean Charts + p.add_option('-B','--booleantype', + help="specify searching option for booleans, ie. substring,notsubstring,exact,... [Default: substring]",default="substring") + p.add_option('--boolean_query', + help="Boolean:Create your own query. Format: BooleanName-Condition-Parameter &/| ... . ie, keywords-substring-Partner & keywords-notsubstring-OtherQA") p.add_option('--blocked', - help="search for bugs that block this bug ID") + help="Boolean:search for bugs that block this bug ID") p.add_option('--dependson', - help="search for bugs that depend on this bug ID") - p.add_option('-b','--bug_id', - help="specify individual bugs by IDs, separated with commas") - p.add_option('-t','--bug_status','--status', - default="NEW,VERIFIED,ASSIGNED,NEEDINFO,ON_DEV,FAILS_QA,REOPENED", - help="comma-separated list of bug statuses to accept") + help="Boolean:search for bugs that depend on this bug ID") + p.add_option('--flag', + help="Boolean:search for bugs that have certain flag states present") + p.add_option('--qa_whiteboard', + help="Boolean:search for bugs that have certain QA Whiteboard text present") + p.add_option('--devel_whiteboard', + help="Boolean:search for bugs that have certain Devel Whiteboard text present") + p.add_option('--alias', + help="Boolean:search for bugs that have the provided alias") + p.add_option('--fixed_in', + help="search Status Whiteboard field for specified words") + elif action == 'info': p.add_option('-p','--products',action='store_true', help='Get a list of products') @@ -135,6 +178,8 @@ def setup_action_parser(action): const='full',default='normal',help="output detailed bug info") p.add_option('-i','--ids',action='store_const',dest='output', const='ids',help="output only bug IDs") + p.add_option('-e','--extra',action='store_const',dest='output', + const='extra',help="output additional bug information (keywords, Whiteboards, etc.)") p.add_option('--outputformat', help="Print output in the form given. You can use RPM-style "+ "tags that match bug fields, e.g.: '%{bug_id}: %{short_desc}'") @@ -203,27 +248,85 @@ if __name__ == '__main__': q = dict() email_count = 1 chart_id = 0 - for a in ('product','component','version','long_desc','bug_id', - 'short_desc','cc','assigned_to','reporter','bug_status', - 'blocked','dependson'): + for a in ('product','component','components_file','version','long_desc','bug_id', + 'short_desc','cc','assigned_to','reporter','qa_contact','bug_status', + 'blocked','dependson','keywords','keywords_type','url','url_type','status_whiteboard', + 'status_whiteboard_type','fixed_in','fixed_in_type','flag','alias','qa_whiteboard', + 'devel_whiteboard','boolean_query','severity','priority'): if hasattr(opt,a): i = getattr(opt,a) if i: if a in ('bug_status'): # list args - q[a] = i.split(',') - elif a in ('cc','assigned_to','reporter'): - # the email query fields are kind of weird - thanks - # to Florian La Roche for figuring this bit out. + # FIXME: statuses can differ between bugzilla instances.. + if i == 'ALL': + # Alias for all available bug statuses + q[a] = 'NEW,ASSIGNED,NEEDINFO,ON_DEV,MODIFIED,POST,ON_QA,FAILS_QA,PASSES_QA,REOPENED,VERIFIED,RELEASE_PENDING,CLOSED'.split(',') + elif i == 'DEV': + # Alias for all development bug statuses + q[a] = 'NEW,ASSIGNED,NEEDINFO,ON_DEV,MODIFIED,POST,REOPENED'.split(',') + elif i == 'QE': + # Alias for all QE relevant bug statuses + q[a] = 'ASSIGNED,ON_QA,FAILS_QA,PASSES_QA'.split(',') + elif i == 'EOL': + # Alias for EndOfLife bug statuses + q[a] = 'VERIFIED,RELEASE_PENDING,CLOSED'.split(',') + else: + q[a] = i.split(',') + elif a in ('cc','assigned_to','reporter','qa_contact'): + # Emails # ex.: {'email1':'foo@bar.com','emailcc1':True} q['email%i' % email_count] = i q['email%s%i' % (a,email_count)] = True + q['emailtype%i' % email_count] = opt.emailtype email_count += 1 - elif a in ('blocked','dependson'): - # Chart args are weird. - q['field%i-0-0' % chart_id] = a - q['type%i-0-0' % chart_id] = 'equals' + elif a in ('components_file'): + # Components slurped in from file (one component per line) + # This can be made more robust + arr = [] + f = open (i, 'r') + for line in f.readlines(): + line = line.rstrip("\n") + arr.append(line) + q['component'] = ",".join(arr) + elif a in ('keywords','keywords_type','url','url_type','status_whiteboard', + 'status_whiteboard_type','severity','priority'): + if a in ('url'): + q['bug_file_loc'] = i + elif a in ('url'): + q['bug_file_loc_type'] = i + else: + q['%s' % a] = i + elif a in ('fixed_in','blocked','dependson','flag','qa_whiteboard','devel_whiteboard','alias'): + # Boolean Charts + if a in ('flag'): + # Flags have strange parameter name + q['field%i-0-0' % chart_id] = 'flagtypes.name' + else: + q['field%i-0-0' % chart_id] = a q['value%i-0-0' % chart_id] = i + q['type%i-0-0' % chart_id] = opt.booleantype chart_id += 1 + elif a in ('boolean_query'): + # Custom Boolean Chart query + # Format: BooleanName-Condition-Parameter &/| BooleanName-Condition-Parameter &/| ... + # ie, keywords-substring-Partner | keywords-notsubstring-PartnerVerified & keywords-notsubstring-OtherQA + chart_id = 0 + and_count = 0 + or_count = 0 + # Manually specified boolean query + x = i.split(' ') + for par in x : + if par.find('&') != -1: + and_count += 1 + elif par.find('|') != -1: + or_count += 1 + elif par.find('-') != -1: + args = par.split('-') + q['field%i-%i-%i' % (chart_id,and_count,or_count)] = args[0] + q['type%i-%i-%i' % (chart_id,and_count,or_count)] = args[1] + q['value%i-%i-%i' % (chart_id,and_count,or_count)] = args[2] + else: + parser.error('Malformed boolean query: %s' % i) else: q[a] = i log.debug("bz.query: %s", q) @@ -298,5 +401,15 @@ if __name__ == '__main__': elif opt.output == 'normal': for b in buglist: print b + elif opt.output == 'extra': + print "Grabbing 'extra' bug information. This could take a moment." + fullbuglist = bz.getbugs([b.bug_id for b in buglist]) + for b in fullbuglist: + print b + if b.keywords: print " +Keywords: ",b.keywords + if b.qa_whiteboard: print " +QA Whiteboard: ",b.qa_whiteboard + if b.status_whiteboard: print " +Status Whiteboard: ",b.status_whiteboard + if b.devel_whiteboard: print " +Devel Whiteboard: ",b.devel_whiteboard + print "\nBugs listed: ",len(buglist) else: parser.error("opt.output was set to something weird.") -- cgit