#!/usr/bin/env python # Copyright 1999-2007 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # Written by Robert Buchholz import string import sys import os cc_release = False def print_targets(version, liaisons, prestable, bugno, username): keywords = os.popen('adjutrix --log-level silent -k').readlines() if cc_release: target_keywords = set(("release",)) else: target_keywords = set() marker = 0 to_stable_line = 0 package = '' target_version = None for lineno, line in enumerate(keywords): if not line: continue if not marker and line[0] == 'K': import re matcher = re.compile("Keywords for (.*):") match = matcher.match(line) package = match.group(1) if line[0] == '-': if marker > 0: print "Warning! These ebuilds are SLOTed\n\n" else: marker = lineno if marker and line[0] not in (" ", "\n", "-"): # we have a keyword line line_stables = get_stable_arches(keywords, marker, line) target_keywords = target_keywords.union(line_stables) line_version = get_version(line) if (version and line_version == version) or ((not version) and line_version != "9999"): to_stable_line = lineno target_version = line_version if not target_version: print "Target version '%s' not found!" % (version) return if not prestable: stabled_keywords = get_stable_arches(keywords, marker, keywords[to_stable_line]) else: stabled_keywords = [] missing_keywords = target_keywords.difference(stabled_keywords) target_keywords_str = listsort(target_keywords) stabled_keywords_str = listsort(stabled_keywords) missing_keywords_str = listsort(missing_keywords) output = [] if prestable: output.append("Arch Security Liaisons, please test the attached ebuild and report it stable on this bug.") elif liaisons and not prestable: output.append("Arch Security Liaisons, please test and mark stable:\n=%s-%s" % (package, target_version)) else: output.append("Arches, please test and mark stable:\n=%s-%s" % (package, target_version)) output.append('Target keywords : "%s"' % (target_keywords_str)) if stabled_keywords: output.append('Already stabled : "%s"' % (stabled_keywords_str)) output.append('Missing keywords: "%s"' % (missing_keywords_str)) mails = [] if liaisons: import liaisons archlist = list(missing_keywords) archlist.sort() output.append("\nCC'ing current Liaisons:") for arch in archlist: liaison = liaisons.get(arch) if not liaison: continue output.append(" %7s : %s" % (arch, ', '.join(liaison))) mails.extend("%s@gentoo.org" % (l,) for l in liaison) elif missing_keywords: # not in liaison mode and missing keywords exist mails = ["%s@gentoo.org" % (mail) for mail in missing_keywords] message = "\n".join(output) print message if mails: cc_add = listsort(mails, ',') print "\nCC: %s" % (cc_add) if bugno: cc_arches_to(bugno, username, message, mails, liaisons) def cc_arches_to(bugno, username, message, cc_add, auth): try: try: import bugz.bugzilla as bugz except ImportError: import bugz import re except: return bz = bugz.Bugz(base = "https://bugs.gentoo.org", user = username, password = None, forget = False) if auth: pass # bz.auth() bug_xml = bz.get(bugno) if not bug_xml: print "Could not find bug %s" % (bugno) return if not bug_xml.find('//group') is None: print ' ! You cannot modify restricted bugs with this tool.' print ' ! Exiting.' sys.exit(1) whiteboard = bug_xml.find('//status_whiteboard') if not whiteboard is None: whiteboard = whiteboard.text new_whiteboard = re.sub("(ebuild\+?|upstream\+?|stable)\??", "stable", whiteboard) new_whiteboard = re.sub("stable/stable", "stable", new_whiteboard) else: whiteboard = "(empty)" new_whiteboard = "?? [stable]" if (whiteboard == new_whiteboard): print "Not changing whiteboard: %s" % (whiteboard) else: print 'Setting whiteboard "%s" to "%s"' % (whiteboard, new_whiteboard) keywords = bug_xml.find('//keywords') if not keywords is None: keywords = "%s %s" % (keywords.text, "STABLEREQ") else: keywords = "STABLEREQ" print "Go ahead? [y/n]: ", answer = sys.stdin.readline() if answer[0] == "y" or answer[0] == "Y": print "Modifying bug https://bugs.gentoo.org/%s ..." % (bugno), if bz.modify(bugno, comment = message, add_cc = cc_add, whiteboard = new_whiteboard, keywords = keywords): print "successful" else: print "error" def listsort(set, joinchar = ' '): mylist = list(set) mylist.sort() return joinchar.join(mylist) def get_version(line): start = line.find('|') if not start: return None return line[0:start-1].strip() def get_stable_arches(keywords, marker, line): start = line.find('|') arches = set() if not start: return for column, char in enumerate(line[start:]): if char == '+': arch = get_arch(keywords, marker, start + column) if arch not in ("mips"): arches.add(arch) return arches def get_arch(keywords, marker, column): arch = '' for lineno in range(marker - 1, 0, -1): char = keywords[lineno][column] if char != ' ': arch += char else: break # return the reverse string return arch[::-1] def usage(programname): """ Print usage information """ print "Usage: %s [-v version] [-l] [-p] [-b bugid] [-u bugz_username]" % (programname) print ''' This script prints target keywords for the latest ebuild in CWD, or version. ''' def main(): import getopt try: optlist, list = getopt.getopt(sys.argv[1:], 'v:lpb:u:') except getopt.GetoptError: usage(sys.argv[0]) sys.exit(2) version = None liaisons = False prestable = False bugno = None user = None for opt, arg in optlist: if opt == '-v': version = arg if opt == '-p': prestable = True if opt == '-l': liaisons = True if opt == '-b': bugno = int(arg) if opt == '-u': user = arg if prestable and not bugno is None: print ' ! Cannot use -p together with -b. Edit the bug manually.' print ' ! Exiting.' sys.exit(1) print_targets(version, liaisons, prestable, bugno, user) if __name__ == "__main__": try: main() except KeyboardInterrupt: print '\n ! Exiting.'