xref: /onnv-gate/usr/src/tools/onbld/Checks/Rti.py (revision 9920:9a117fecafb3)
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