pr_commits = requests.get( 'https://api.github.com/repos/candlepin/candlepin/pulls/{pr}/commits'. format(pr=args.pr), headers={ 'Authorization': 'token {}'.format(github_token) }).json() for commit in pr_commits: message = commit['commit']['message'] first_line = message.split('\n')[0] match = re.search('^(\d+):? ', first_line) if match: bz_number = match.group(1) bug = bz.getbug(bz_number) target_release = bug.target_release[0] if '---' in target_release: target_release = fetch_master_version() final_version = target_release or bug.version if final_version != version: print(UH_OH) print( '{commit}: BZ#{bz_number} references {final_version}, while PR references {version}' .format(commit=commit['sha'], bz_number=bz_number, final_version=final_version, version=version)) sys.exit(1)
class BugzillaBug(AbstractBug): """ This class handles interaction with bugzilla using xmlrpc. """ def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. """ AbstractBug.__init__(self) self.check_options() self.bug_num = bug bz_url = os.path.join(Settings.current_bz_url, 'xmlrpc.cgi') self.bugzilla = Bugzilla(url=bz_url) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) if Settings.login: self.login(Settings.user) if Settings.assign: self.assign_bug() def login(self, user, password=None): """ Handles the login of the user into bugzilla. Will ask for password on the commandline unless it's provided as argument. :arg user, the bugzilla username. :arg password, bugzilla password. """ if not user: raise SettingsError('--user required for --login') if not password: password=getpass.getpass() ret = self.bugzilla.login(user=user, password=password) if ret: self.log.info("You are logged in to bugzilla. " "Credential cookies cached for future.") else: raise SettingsError("Can't login (bad password?)") self.user = user return True def _find_urls(self): """ Reads the page on bugzilla, search for all urls and extract the last urls for the spec and the srpm. """ urls = [] if self.bug.longdescs: for cat in self.bug.longdescs: body = cat['body'] # workaround for bugzilla/xmlrpc bug. When comment # text is pure number it converts to number type (duh) if type(body) != str and type(body) != unicode: continue urls.extend(re.findall('(?:ht|f)tp[s]?://' '(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|' '(?:%[0-9a-fA-F~\.][0-9a-fA-F]))+', body)) return urls def find_spec_url(self): urls = self._find_urls() urls = filter(lambda u: '.spec' in u, urls) if len(urls) == 0: raise BugException ( 'No spec file URL found in bug #%s' % self.bug_num) url = urls[-1] self.spec_url = url def find_srpm_url(self): urls = self._find_urls() urls = filter(lambda u: '.src.rpm' in u, urls) if len(urls) == 0: raise BugException ( 'No srpm file URL found in bug #%s' % self.bug_num) url = urls[-1] self.srpm_url = url def get_location(self): return Settings.bug def get_dirname(self): ''' Return dirname to be used for this bug. ''' if self.get_name() != '?': return self.bug_num + '-' + self.get_name() else: return self.bug_num def check_options(self): AbstractBug.do_check_options(self, '--bug', ['prebuilt']) def assign_bug(self): """ Assign the bug to the reviewer. """ try: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) except xmlrpclib.Fault, e: self.handle_xmlrpc_err(e) self.log.error("Some parts of bug assignment " "failed. Please check manually") except ValueError, e: self.log.error("Invalid bugzilla values: %s" % e) self.log.error("Some parts of bug assignment " "failed. Please check manually")
class BugzillaBackend(object): def __init__(self, _id, config): self._bug = None self.config = config self.id = _id self.url = config.get('bz_url') if "bugzilla.redhat.com" in self.url: self.bugzilla = RHBugzilla(url=self.url) else: self.bugzilla = Bugzilla(url=self.url) def ensure_login(func): def wrapper(self, *args, **kwargs): user = self.config.get('bz_user') password = self.config.get('bz_password') if (user and password) and not self.bugzilla.logged_in: self.bugzilla.login(user, password) return func(self, *args, **kwargs) return wrapper @property @ensure_login def bug(self): if not self._bug: self._bug = self.bugzilla.getbug(self.id) return self._bug @ensure_login def search(self, query): q = self.config.get("bz_query", {}).copy() q.update(query) for k, v in q.items(): if isinstance(v, basestring) and "," in v: q[k] = v.split(",") return self.bugzilla.query(q) @classmethod def on_search(cls, config, query, **kwargs): bugz = cls(None, config) results = bugz.search(query) headers = [ 'ID', 'Component', 'Status', 'Summary', 'Assignee'] table = prettytable.PrettyTable(headers, header=False, border=False) for rst in results: bug = rst.__dict__ table.add_row([ bug["id"], colored(bug["component"], "green"), colored(bug["status"], "red"), bug["summary"], bug["assigned_to"], ]) print table.get_string() @classmethod def on_take(cls, config, **kwargs): bugz = cls(kwargs.get("bug"), config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) @classmethod def on_update(cls, config, **kwargs): def update_bug(bug): bugz = cls(bug, config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) if kwargs.get("bug"): return update_bug(kwargs.get("bug")) for sub in os.listdir("./"): bugdir = os.path.join("./", sub) if not os.path.exists(os.path.join(bugdir, '.bugzilla.json')): continue update_bug(sub.lstrip(config.get("prefix", ""))) @classmethod def on_show(cls, config, **kwargs): if os.path.exists(".bugzilla.json"): with open(".bugzilla.json", "rb") as f: summary = loads(f.read()) print colored("Bug Title: ", 'green') + summary["summary"] print "\tStatus: %s" % summary["status"] print "\t%s comments" % len(summary["comments"]) # Check if conf.args has attr so we can reuse it for listing if hasattr(conf.args, "verbose") and conf.args.verbose: for idx, comment in enumerate(summary["comments"]): print colored("\tComment: %s" % (idx + 1), 'yellow') header = "\tAuthor: %s, Private: %s, Date %s" % \ (comment["author"], comment["is_private"], comment["time"]) print colored(header, 'yellow') print "\t%s" % comment["text"].replace("\n", "\n\t") print "\t" on_list = on_show
class ReviewBug(Helpers): def __init__(self, bug, user=None, password=None, cache=False, nobuild=False): Helpers.__init__(self, cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.bugzilla = Bugzilla(url=BZ_URL) self.is_login = False if user and password: rc = self.bugzilla.login(user=user, password=password) if rc > 0: self.is_login = True self.user = user self.bug = self.bugzilla.getbug(self.bug_num) self.log = get_logger() def login(self, user, password): if self.bugzilla.login(user=user, password=password) > 0: self.is_login = True self.user = user else: self.is_login = False return self.is_login def find_urls(self): found = True if self.bug.longdescs: for c in self.bug.longdescs: body = c['body'] #self.log.debug(body) urls = re.findall( 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', body) if urls: for url in urls: if url.endswith(".spec"): self.spec_url = url elif url.endswith(".src.rpm"): self.srpm_url = url if not self.spec_url: self.log.info('not spec file URL found in bug #%s' % self.bug_num) found = False if not self.srpm_url: self.log.info('not SRPM file URL found in bug #%s' % self.bug_num) found = False return found def assign_bug(self): if self.is_login: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) else: self.log.info("You need to login before assigning a bug") def add_comment(self, comment): if self.is_login: self.bug.addcomment(comment) else: self.log.info("You need to is_login before commenting on a bug") def add_comment_from_file(self, fname): fd = open(fname, "r") lines = fd.readlines() fd.close self.add_comment("".join(lines)) def download_files(self): if not self.cache: self.log.info('Downloading .spec and .srpm files') found = True if not self.spec_url or not self.srpm_url: found = self.find_urls() if found and self.spec_url and self.srpm_url: self.spec_file = self._get_file(self.spec_url) self.srpm_file = self._get_file(self.srpm_url) if self.spec_file and self.srpm_file: return True return False
class BugzillaBug(AbstractBug): """ This class handles interaction with bugzilla using xmlrpc. """ def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. """ AbstractBug.__init__(self) self.check_options() self.bug_num = bug bz_url = os.path.join(Settings.current_bz_url, 'xmlrpc.cgi') self.bugzilla = Bugzilla(url=bz_url) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) if Settings.login: self.login(Settings.user) if Settings.assign: self.assign_bug() def login(self, user, password=None): """ Handles the login of the user into bugzilla. Will ask for password on the commandline unless it's provided as argument. :arg user, the bugzilla username. :arg password, bugzilla password. """ if not user: raise SettingsError('--user required for --login') if not password: password = getpass.getpass() ret = self.bugzilla.login(user=user, password=password) if ret: self.log.info("You are logged in to bugzilla. " "Credential cookies cached for future.") else: raise SettingsError("Can't login (bad password?)") self.user = user return True def _find_urls(self): """ Reads the page on bugzilla, search for all urls and extract the last urls for the spec and the srpm. """ urls = [] if self.bug.longdescs: for cat in self.bug.longdescs: body = cat['body'] # workaround for bugzilla/xmlrpc bug. When comment # text is pure number it converts to number type (duh) if type(body) != str and type(body) != unicode: continue urls.extend( re.findall( '(?:ht|f)tp[s]?://' '(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|' '(?:%[0-9a-fA-F~\.][0-9a-fA-F]))+', body)) return urls def find_spec_url(self): urls = self._find_urls() urls = filter(lambda u: '.spec' in u, urls) if len(urls) == 0: raise BugException('No spec file URL found in bug #%s' % self.bug_num) url = urls[-1] self.spec_url = url def find_srpm_url(self): urls = self._find_urls() urls = filter(lambda u: '.src.rpm' in u, urls) if len(urls) == 0: raise BugException('No srpm file URL found in bug #%s' % self.bug_num) url = urls[-1] self.srpm_url = url def get_location(self): return Settings.bug def get_dirname(self): ''' Return dirname to be used for this bug. ''' if self.get_name() != '?': return self.bug_num + '-' + self.get_name() else: return self.bug_num def check_options(self): AbstractBug.do_check_options(self, '--bug', ['prebuilt']) def assign_bug(self): """ Assign the bug to the reviewer. """ try: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) except xmlrpclib.Fault, e: self.handle_xmlrpc_err(e) self.log.error("Some parts of bug assignment " "failed. Please check manually") except ValueError, e: self.log.error("Invalid bugzilla values: %s" % e) self.log.error("Some parts of bug assignment " "failed. Please check manually")
class BugzillaBackend(object): def __init__(self, _id, config): self._bug = None self.config = config self.id = _id self.url = config.get('bz_url') if "bugzilla.redhat.com" in self.url: self.bugzilla = RHBugzilla(url=self.url) else: self.bugzilla = Bugzilla(url=self.url) def ensure_login(func): def wrapper(self): user = self.config.get('user') password = self.config.get('password') if (user and password) and not self.bugzilla.logged_in: self.bugzilla.login(user, password) return func(self) return wrapper @property @ensure_login def bug(self): if not self._bug: self._bug = self.bugzilla.getbug(self.id) return self._bug @classmethod def on_take(cls, config, **kwargs): bugz = cls(kwargs.get("bug"), config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) @classmethod def on_update(cls, config, **kwargs): def update_bug(bug): bugz = cls(bug, config) bug = bugz.bug.__dict__ if bug: with open('.bugzilla.json', 'wab') as f: f.write(dumps(bug, ensure_ascii=True, indent=4)) if kwargs.get("bug"): return update_bug(kwargs.get("bug")) for sub in os.listdir("./"): bugdir = os.path.join("./", sub) if not os.path.exists(os.path.join(bugdir, '.bugzilla.json')): continue update_bug(sub.lstrip(config.get("prefix", ""))) @classmethod def on_show(cls, config, **kwargs): if os.path.exists(".bugzilla.json"): with open(".bugzilla.json", "rb") as f: summary = loads(f.read()) print colored("Bug Title: ", 'green') + summary["summary"] print "\tStatus: %s" % summary["status"] print "\t%s comments" % len(summary["comments"]) # Check if conf.args has attr so we can reuse it for listing if hasattr(conf.args, "verbose") and conf.args.verbose: for idx, comment in enumerate(summary["comments"]): print colored("\tComment: %s" % (idx + 1), 'yellow') header = "\tAuthor: %s, Private: %s, Date %s" % (comment["author"], comment["is_private"], comment["time"]) print colored(header, 'yellow') print "\t%s" % comment["text"].replace("\n", "\n\t") print "\t" on_list = on_show
class ReviewBug(Helpers): def __init__(self,bug,user=None,password=None, cache=False, nobuild=False): Helpers.__init__(self,cache, nobuild) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.bugzilla = Bugzilla(url=BZ_URL) self.is_login = False if user and password: rc = self.bugzilla.login(user=user, password=password) if rc > 0: self.is_login = True self.user = user self.bug = self.bugzilla.getbug(self.bug_num) self.log = get_logger() def login(self, user, password): if self.bugzilla.login(user=user, password=password) > 0: self.is_login = True self.user = user else: self.is_login = False return self.is_login def find_urls(self): found = True if self.bug.longdescs: for c in self.bug.longdescs: body = c['body'] #self.log.debug(body) urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', body) if urls: for url in urls: if url.endswith(".spec"): self.spec_url = url elif url.endswith(".src.rpm"): self.srpm_url = url if not self.spec_url: self.log.info('not spec file URL found in bug #%s' % self.bug_num) found = False if not self.srpm_url: self.log.info('not SRPM file URL found in bug #%s' % self.bug_num) found = False return found def assign_bug(self): if self.is_login: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review' : '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) else: self.log.info("You need to login before assigning a bug") def add_comment(self,comment): if self.is_login: self.bug.addcomment(comment) else: self.log.info("You need to is_login before commenting on a bug") def add_comment_from_file(self,fname): fd = open(fname,"r") lines = fd.readlines() fd.close self.add_comment("".join(lines)) def download_files(self): if not self.cache: self.log.info('Downloading .spec and .srpm files') found = True if not self.spec_url or not self.srpm_url: found = self.find_urls() if found and self.spec_url and self.srpm_url: self.spec_file = self._get_file(self.spec_url) self.srpm_file = self._get_file(self.srpm_url) if self.spec_file and self.srpm_file: return True return False
class ReviewBug(Helpers): """ This class handles interaction with bugzilla. """ def __init__(self, bug, user=None, password=None): """ Constructor. :arg bug, the bug number on bugzilla :kwarg user, the username with which to log in in bugzilla. :kwarg password, the password associated with this account. be re-downloaded or not. """ Helpers.__init__(self) self.bug_num = bug self.spec_url = None self.srpm_url = None self.spec_file = None self.srpm_file = None self.log = get_logger() if Settings.other_bz: self.bugzilla = Bugzilla(url=Settings.other_bz + '/xmlrpc.cgi') else: self.bugzilla = Bugzilla(url=BZ_URL) self.log.info("Trying bugzilla cookies for authentication") self.user = user self.bug = self.bugzilla.getbug(self.bug_num) def login(self, user): """ Handles the login of the user into bugzilla. Will ask for password on the commandline :arg user, the bugzilla username. """ ret = self.bugzilla.login(user=user, password=getpass.getpass()) if ret > 0: self.log.info("You are logged in to bugzilla. " "Credential cookies cached for future.") self.user = user return True def find_urls(self): """ Reads the page on bugzilla, search for all urls and extract the last urls for the spec and the srpm. """ found = True if self.bug.longdescs: for cat in self.bug.longdescs: body = cat['body'] # workaround for bugzilla/xmlrpc bug. When comment # text is pure number it converts to number type (duh) if type(body) != str and type(body) != unicode: continue urls = re.findall('(?:ht|f)tp[s]?://(?:[a-zA-Z]|[0-9]|\ [$-_@.&+~]|[!*\(\),]|(?:%[0-9a-fA-F~\.][0-9a-fA-F]))+', body) if urls: for url in urls: if ".spec" in url: self.spec_url = url elif ".src.rpm" in url: self.srpm_url = url if not self.spec_url: self.log.info('no spec file URL found in bug #%s' % self.bug_num) found = False if not self.srpm_url: self.log.info('no SRPM file URL found in bug #%s' % self.bug_num) found = False return found def assign_bug(self): """ Assign the bug to the reviewer. """ try: self.bug.setstatus('ASSIGNED') self.bug.setassignee(assigned_to=self.user) self.bug.addcomment('I will review this package') flags = {'fedora-review': '?'} self.bug.updateflags(flags) self.bug.addcc([self.user]) except xmlrpclib.Fault, e: self.handle_xmlrpc_err(e) self.log.error("Some parts of bug assignment " "failed. Please check manually") except ValueError, e: self.log.error("Invalid bugzilla values: %s" % e) self.log.error("Some parts of bug assignment " "failed. Please check manually")