17078Smjnelson#! /usr/bin/python 27078Smjnelson# 37078Smjnelson# CDDL HEADER START 47078Smjnelson# 57078Smjnelson# The contents of this file are subject to the terms of the 67078Smjnelson# Common Development and Distribution License (the "License"). 77078Smjnelson# You may not use this file except in compliance with the License. 87078Smjnelson# 97078Smjnelson# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107078Smjnelson# or http://www.opensolaris.org/os/licensing. 117078Smjnelson# See the License for the specific language governing permissions 127078Smjnelson# and limitations under the License. 137078Smjnelson# 147078Smjnelson# When distributing Covered Code, include this CDDL HEADER in each 157078Smjnelson# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167078Smjnelson# If applicable, add the following below this CDDL HEADER, with the 177078Smjnelson# fields enclosed by brackets "[]" replaced with your own identifying 187078Smjnelson# information: Portions Copyright [yyyy] [name of copyright owner] 197078Smjnelson# 207078Smjnelson# CDDL HEADER END 217078Smjnelson# 227078Smjnelson 237078Smjnelson# 247078Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 257078Smjnelson# Use is subject to license terms. 267078Smjnelson# 277078Smjnelson 287078Smjnelson# 297078Smjnelson# Check on RTI status for bug IDs passed. 307078Smjnelson# 317078Smjnelson# How we obtain the bug IDs will vary per SCM. 327078Smjnelson# - For Teamware, we want to check the active list comments. 337078Smjnelson# - For Mercurial, we can check the incoming changegroup (via the 347078Smjnelson# pretxnchangegroup hook) and abort if necessary 357078Smjnelson# 367078Smjnelson# This module is implemented as a generic checking module given a list of 377078Smjnelson# bug IDs. It can then be wrapped or hooked into whatever SCM with an 387078Smjnelson# SCM-specific hook to parse and pass the requisite bug IDs 397078Smjnelson# 407078Smjnelson 417078Smjnelsonimport re, os, sys 427078Smjnelsonfrom onbld.Checks.DbLookups import Rti, RtiException, RtiNotFound, RtiOffSwan 437078Smjnelson 447078SmjnelsonpatchGateRe = re.compile(r'.*-patch.*') 457078SmjnelsontestGateRe = re.compile(r'.*-(stc2|test)$') 467078Smjnelson 477078Smjnelsondef rti(bugids, gatePath=None, consolidation=None, 487078Smjnelson output=sys.stderr): 497078Smjnelson """Return True iff each of the specified bugids has an approved RTI. 507078Smjnelson 517078Smjnelson Required argument: 527078Smjnelson bugids: list of seven-digit bug ids 537078Smjnelson 547078Smjnelson Keyword arguments, used to limit the scope of the RTI search: 557078Smjnelson gatePath: fully qualified path to gate 567078Smjnelson consolidation: name of the consolidation 577078Smjnelson """ 587078Smjnelson 597078Smjnelson rtiType = "MarketingRelease" 607078Smjnelson gateType = "MarketingRelease" 617078Smjnelson 627078Smjnelson # Check to see if we were given a gate to lookup with 637078Smjnelson if gatePath != None: 647298SMark.J.Nelson@Sun.COM 657298SMark.J.Nelson@Sun.COM # 667298SMark.J.Nelson@Sun.COM # The gate name should be the last component of the gate path, 677298SMark.J.Nelson@Sun.COM # no matter how it's accessed. 687298SMark.J.Nelson@Sun.COM # 697298SMark.J.Nelson@Sun.COM # We make a special case for "closed," and check to see if it 707298SMark.J.Nelson@Sun.COM # appears to be the "usr/closed" portion of a nested repository. 717298SMark.J.Nelson@Sun.COM # In that case, we really want the parent repository name. 727298SMark.J.Nelson@Sun.COM # 737298SMark.J.Nelson@Sun.COM gatePath = gatePath.rstrip(os.path.sep).split(os.path.sep) 747298SMark.J.Nelson@Sun.COM gateName = gatePath[-1] 757298SMark.J.Nelson@Sun.COM try: 767298SMark.J.Nelson@Sun.COM if gatePath[-2:] == ['usr', 'closed']: 777298SMark.J.Nelson@Sun.COM gateName = gatePath[-3] 787298SMark.J.Nelson@Sun.COM except IndexError: 797298SMark.J.Nelson@Sun.COM pass 807078Smjnelson 817078Smjnelson # Is this a patch gate? 827298SMark.J.Nelson@Sun.COM if patchGateRe.search(gateName): 837078Smjnelson rtiType = "Patch" 847078Smjnelson gateType = "Patch" 857078Smjnelson 867078Smjnelson # Is this a test gate? 877298SMark.J.Nelson@Sun.COM if testGateRe.search(gateName): 887078Smjnelson rtiType = "RTI" 897078Smjnelson gateType = "RTI" 907078Smjnelson else: 917078Smjnelson gateName = None 927078Smjnelson 937078Smjnelson # Query RTI if there's a gate 947078Smjnelson # Check the RTIs, caching them in the 'rtis' dictionary 957078Smjnelson # We do our error checking/handling here 967078Smjnelson rtis = {} 977078Smjnelson badRtis = [] 987078Smjnelson for cr in bugids: 997078Smjnelson # If we don't already have an Rti object for this cr cached, 1007078Smjnelson # then go create/query it 1017078Smjnelson if cr not in rtis.keys() + badRtis: 1027078Smjnelson try: 1037078Smjnelson rtis[cr] = Rti(cr, gateName, consolidation) 1047078Smjnelson except RtiOffSwan, e: 1057078Smjnelson output.write("%s\n" % e) 1067078Smjnelson return False 1077078Smjnelson except RtiNotFound, e: 1087078Smjnelson output.write("Error: no RTI found for bug %s\n" 1097078Smjnelson % cr) 1107078Smjnelson badRtis.append(cr) 1117078Smjnelson continue 1127078Smjnelson except RtiException, e: 1137078Smjnelson output.write("%s\n" % e) 1147078Smjnelson badRtis.append(cr) 1157078Smjnelson continue 1167078Smjnelson 1177078Smjnelson crRti = rtis[cr] 1187078Smjnelson 1197078Smjnelson # If we've reached this point, then the Rti query succeeded, 1207078Smjnelson # and we didn't get an error back from webrti. There is still 1217078Smjnelson # some sanity checking to be done, however 1227078Smjnelson rtiNumber = crRti.rtiNumber() 1237078Smjnelson rtiType = crRti.rtiType() 1247078Smjnelson 1257078Smjnelson # check to make sure the RTI type matches the gate type 1267764SJohn.Sonnenschein@Sun.COM if not gateType in rtiType: 1277764SJohn.Sonnenschein@Sun.COM message = "Error: for bug " + cr 1287764SJohn.Sonnenschein@Sun.COM for each in rtiNumber: 1297765SJohn.Sonnenschein@Sun.COM message += " the RTI " + each + " is of " 1307764SJohn.Sonnenschein@Sun.COM message += rtiType[rtiNumber.index(each)] + " type " 1317764SJohn.Sonnenschein@Sun.COM message += "but the parent gate " + gateName + " is a " 1327764SJohn.Sonnenschein@Sun.COM message += gateType + " gate.\n" + "A " + gateType 1337764SJohn.Sonnenschein@Sun.COM message += " RTI must be submitted to putback bug " + cr + " to " 1347764SJohn.Sonnenschein@Sun.COM message += gateName + ". \n" 1357764SJohn.Sonnenschein@Sun.COM 1367764SJohn.Sonnenschein@Sun.COM output.write( message ) 1377078Smjnelson badRtis.append(cr) 1387078Smjnelson continue 1397078Smjnelson 1407078Smjnelson if not crRti.accepted(): 1417764SJohn.Sonnenschein@Sun.COM for each in rtiNumber: 1427764SJohn.Sonnenschein@Sun.COM message = "Error: RTI " + each + " for CR " + cr + " is not in " 143*7778SJohn.Sonnenschein@Sun.COM message += "the accepted state.\n" 144*7778SJohn.Sonnenschein@Sun.COM output.write(message) 1457078Smjnelson badRtis.append(cr) 1467078Smjnelson continue 1477078Smjnelson 1487078Smjnelson if len(badRtis) > 0: 1497078Smjnelson return False 1507078Smjnelson 1517078Smjnelson return True 1527078Smjnelson 153