1#! /usr/bin/python 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28# 29# Check on RTI status for bug IDs passed. 30# 31# How we obtain the bug IDs will vary per SCM. 32# - For Teamware, we want to check the active list comments. 33# - For Mercurial, we can check the incoming changegroup (via the 34# pretxnchangegroup hook) and abort if necessary 35# 36# This module is implemented as a generic checking module given a list of 37# bug IDs. It can then be wrapped or hooked into whatever SCM with an 38# SCM-specific hook to parse and pass the requisite bug IDs 39# 40 41import re, os, sys 42from onbld.Checks.DbLookups import Rti, RtiException, RtiNotFound, RtiOffSwan 43 44opensolarisGateRe = re.compile(r'.*osol[0-9]+-sust$') 45patchGateRe = re.compile(r'.*-patch.*') 46testGateRe = re.compile(r'.*-(stc2|test)$') 47 48def rti(bugids, gatePath=None, consolidation=None, 49 output=sys.stderr): 50 """Return True iff each of the specified bugids has an approved RTI. 51 52 Required argument: 53 bugids: list of seven-digit bug ids 54 55 Keyword arguments, used to limit the scope of the RTI search: 56 gatePath: fully qualified path to gate 57 consolidation: name of the consolidation 58 """ 59 60 rtiType = "MarketingRelease" 61 gateType = "MarketingRelease" 62 63 # Check to see if we were given a gate to lookup with 64 if gatePath != None: 65 66 # 67 # The gate name should be the last component of the gate path, 68 # no matter how it's accessed. 69 # 70 # We make a special case for "closed," and check to see if it 71 # appears to be the "usr/closed" portion of a nested repository. 72 # In that case, we really want the parent repository name. 73 # 74 gatePath = gatePath.rstrip(os.path.sep).split(os.path.sep) 75 gateName = gatePath[-1] 76 try: 77 if gatePath[-2:] == ['usr', 'closed']: 78 gateName = gatePath[-3] 79 except IndexError: 80 pass 81 82 # Is this an OpenSolaris gate? 83 if opensolarisGateRe.search(gateName): 84 rtiType = "OpenSolaris" 85 gateType = "OpenSolaris" 86 87 # Is this a patch gate? 88 if patchGateRe.search(gateName): 89 rtiType = "Patch" 90 gateType = "Patch" 91 92 # Is this a test gate? 93 if testGateRe.search(gateName): 94 rtiType = "RTI" 95 gateType = "RTI" 96 else: 97 gateName = None 98 99 # Query RTI if there's a gate 100 # Check the RTIs, caching them in the 'rtis' dictionary 101 # We do our error checking/handling here 102 rtis = {} 103 badRtis = [] 104 for cr in bugids: 105 # If we don't already have an Rti object for this cr cached, 106 # then go create/query it 107 if cr not in rtis.keys() + badRtis: 108 try: 109 rtis[cr] = Rti(cr, gateName, consolidation) 110 except RtiOffSwan, e: 111 output.write("%s\n" % e) 112 return False 113 except RtiException, e: 114 output.write("%s\n" % e) 115 badRtis.append(cr) 116 continue 117 118 crRti = rtis[cr] 119 120 # If we've reached this point, then the Rti query succeeded, 121 # and we didn't get an error back from webrti. There is still 122 # some sanity checking to be done, however 123 rtiNumber = crRti.rtiNumber() 124 rtiType = crRti.rtiType() 125 126 # check to make sure the RTI type matches the gate type 127 if not gateType in rtiType: 128 message = "Error: for bug " + cr 129 for each in rtiNumber: 130 message += " the RTI " + each + " is of " 131 message += rtiType[rtiNumber.index(each)] + " type " 132 message += "but the parent gate " + gateName + " is a " 133 message += gateType + " gate.\n" + "A " + gateType 134 message += " RTI must be submitted to putback bug " + cr + " to " 135 message += gateName + ". \n" 136 137 output.write( message ) 138 badRtis.append(cr) 139 continue 140 141 if not crRti.accepted(): 142 for each in rtiNumber: 143 message = "Error: RTI " + each + " for CR " + cr + " is not in " 144 message += "the accepted state.\n" 145 output.write(message) 146 badRtis.append(cr) 147 continue 148 149 if len(badRtis) > 0: 150 return False 151 152 return True 153 154