xref: /onnv-gate/usr/src/tools/onbld/Checks/Rti.py (revision 7298:b69e27387f74)
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 2008 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
44patchGateRe = re.compile(r'.*-patch.*')
45testGateRe = re.compile(r'.*-(stc2|test)$')
46
47def rti(bugids, gatePath=None, consolidation=None,
48	output=sys.stderr):
49	"""Return True iff each of the specified bugids has an approved RTI.
50
51	Required argument:
52	bugids:	list of seven-digit bug ids
53
54	Keyword arguments, used to limit the scope of the RTI search:
55	gatePath: fully qualified path to gate
56	consolidation: name of the consolidation
57	"""
58
59	rtiType = "MarketingRelease"
60	gateType = "MarketingRelease"
61
62	# Check to see if we were given a gate to lookup with
63	if gatePath != None:
64
65		#
66		# The gate name should be the last component of the gate path,
67		# no matter how it's accessed.
68		#
69		# We make a special case for "closed," and check to see if it
70		# appears to be the "usr/closed" portion of a nested repository.
71		# In that case, we really want the parent repository name.
72		#
73		gatePath = gatePath.rstrip(os.path.sep).split(os.path.sep)
74		gateName = gatePath[-1]
75		try:
76			if gatePath[-2:] == ['usr', 'closed']:
77				gateName = gatePath[-3]
78		except IndexError:
79			pass
80
81		# Is this a patch gate?
82		if patchGateRe.search(gateName):
83			rtiType = "Patch"
84			gateType = "Patch"
85
86		# Is this a test gate?
87		if testGateRe.search(gateName):
88			rtiType = "RTI"
89			gateType = "RTI"
90	else:
91		gateName = None
92
93	# Query RTI if there's a gate
94	# Check the RTIs, caching them in the 'rtis' dictionary
95	# We do our error checking/handling here
96	rtis = {}
97	badRtis = []
98	for cr in bugids:
99		# If we don't already have an Rti object for this cr cached,
100		# then go create/query it
101		if cr not in rtis.keys() + badRtis:
102			try:
103				rtis[cr] = Rti(cr, gateName, consolidation)
104			except RtiOffSwan, e:
105				output.write("%s\n" % e)
106				return False
107			except RtiNotFound, e:
108				output.write("Error: no RTI found for bug %s\n"
109					% cr)
110				badRtis.append(cr)
111				continue
112			except RtiException, e:
113				output.write("%s\n" % e)
114				badRtis.append(cr)
115				continue
116
117		crRti = rtis[cr]
118
119		# If we've reached this point, then the Rti query succeeded,
120		# and we didn't get an error back from webrti.  There is still
121		# some sanity checking to be done, however
122		rtiNumber = crRti.rtiNumber()
123		rtiType = crRti.rtiType()
124
125		# check to make sure the RTI type matches the gate type
126		if rtiType != gateType:
127			output.write(
128			    "Error: for bug %s the RTI %s is of %s type "
129			    "but the parent gate %s is a %s gate.\n"
130			    "A %s RTI must be submitted to putback bug %s "
131			    "to %s.\n" % (cr, rtiNumber, rtiType, gateName,
132					  gateType, gateType, cr, gateName))
133			badRtis.append(cr)
134			continue
135
136		if not crRti.accepted():
137			output.write("Error: RTI %s for CR %s is not in "
138			     "the accepted state.\n" % (rtiNumber, cr))
139			badRtis.append(cr)
140			continue
141
142	if len(badRtis) > 0:
143		return False
144
145	return True
146
147