#============================================================================
#Name : validateoverlay.py
#Part of : Helium
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
#All rights reserved.
#This component and the accompanying materials are made available
#under the terms of the License "Eclipse Public License v1.0"
#which accompanies this distribution, and is available
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
#Initial Contributors:
#Nokia Corporation - initial contribution.
#
#Contributors:
#
#Description:
#===============================================================================
import StringIO
import sys
import os
import optparse
import traceback
import amara
import ccm
import comments
import helium.logger
from helium.outputer import XML2XHTML
import nokia.nokiaccm
import virtualbuildarea
def __findChild(p, d, name):
if (p is None or d is None):
return None
for child in d.children(p):
if name.lower() == child.name.lower():
return child
return None
def __getDir(p, o):
if (o.type == 'project'):
return o, o.root_dir()
return p, o
class ValidateOverlayInfo:
UNKNOW = 0
STILL_VALID = 1
MERGE = 2
def __init__(self, name):
self.name = name
#self.status = status
self.overlayObject = None
self.deliveryObjects = []
def ValidateOverlay(vproject, vdir, oproject, odir, extraobject = None):
""" This function scan an the virtual build area and the overlay to validate
if the overlay content is still up to date compare to the delivery.
"""
if extraobject is None:
extraobject = []
print "ValidateOverlay(%s,%s,%s,%s)" % (vproject, vdir, oproject, odir)
result = {'name': odir.name, 'content': []}
for child in odir.children(oproject):
o = __findChild(vproject, vdir, child.name)
if o is None:
if (child.type == 'dir' or child.type == 'project'):
op, oo = __getDir(oproject, child)
result['content'].append(ValidateOverlay(None, None, op, oo, extraobject))
else:
info = ValidateOverlayInfo(child.name)
info.overlayObject = child
result['content'].append(info)
else:
if (child.type == 'dir' or child.type == 'project'):
vp, vo = __getDir(vproject, o)
op, oo = __getDir(oproject, child)
result['content'].append(ValidateOverlay(vp, vo, op, oo, extraobject))
else:
info = ValidateOverlayInfo(child.name)
info.overlayObject = child
info.deliveryObjects.append({'status': ValidateOverlayInfo.UNKNOW, 'object': o})
for eo in extraobject:
if eo.is_same_family(o):
info.deliveryObjects.append({'status': ValidateOverlayInfo.UNKNOW, 'object': eo})
for delivery in info.deliveryObjects:
if child.is_recursive_sucessor_of(delivery['object']):
delivery['status'] = ValidateOverlayInfo.STILL_VALID
else:
delivery['status'] = ValidateOverlayInfo.MERGE
result['content'].append(info)
return result
def getObjectPath(project, spath, dir=None):
name = spath.pop(0)
if (dir == None):
if project.root_dir().name.lower() == name.lower():
return getObjectPath(project, spath, project.root_dir())
raise Exception("project.root_dir().name.lower()!=name.lower():")
else:
for o in dir.children(project):
if o.name.lower() == name.lower():
if len(spath) == 0:
return o
elif o.type == 'dir':
return getObjectPath(project, spath, o)
else:
raise Exception("Object could not be accessed")
raise Exception("Object not found")
def showBranchInfo(logger, object):
doc = comments.CommentParser.scan_content(str(object.overlayObject), object.overlayObject.content(), "branchInfo")
if len(doc.commentLog.xml_xpath('branchInfo'))>0:
for child in doc.commentLog.xml_xpath('branchInfo'):
logger.PrintRaw("<b>Branch Information:</b>\n")
if hasattr(child, 'xml_attributes'):
for attr in child.xml_attributes:
logger.PrintRaw("<b>%s:</b> %s\n" % (attr, getattr(child, attr)))
if hasattr(child, 'branch'):
logger.PrintRaw("<b>Should validate compare to file:</b> %s\n" % child.branch)
else:
logger.Print("No branch info...\n")
def showValidity(logger, obj):
if len(obj.deliveryObjects)==0:
logger.NotFound("Could not find %s relative objects." % (obj.overlayObject))
else:
for delivery in obj.deliveryObjects:
if (delivery['status'] == ValidateOverlayInfo.MERGE):
logger.Merge("Overlay object %s requires a merge with %s." % (obj.overlayObject, delivery['object']))
elif (delivery['status'] == ValidateOverlayInfo.STILL_VALID):
logger.Valid("%s is still a successor of %s." % (obj.overlayObject, delivery['object']))
def showValidateOverlayInfo(logger, data, comments=False):
logger.OpenEvent(data['name'])
for o in data['content']:
if isinstance(o, ValidateOverlayInfo):
logger.OpenEvent(o.name)
showValidity(logger, o)
# Showing branch information.
if comments:
showBranchInfo(logger, o)
logger.CloseEvent()
else:
showValidateOverlayInfo(logger, o, comments)
logger.CloseEvent()
def mergeObjects(logger, data, task):
for obj in data['content']:
if isinstance(obj, ValidateOverlayInfo):
mergedobject = None
for delivery in obj.deliveryObjects:
if (delivery['status'] == ValidateOverlayInfo.MERGE):
try:
if not mergedobject:
(mergedobject, validity) = obj.overlayObject.merge(delivery['object'], task)
mergedobject.checkin('public', 'Makes object public.')
logger.Print("%s (%s, %s)" % (mergedobject, obj.overlayObject, delivery['object']))
else:
delivery['object'].relate(mergedobject)
logger.Print("%s (%s, %s)" % (mergedobject, obj.overlayObject, delivery['object']))
#mergedobject
except Exception, e:
logger.Error("%s" % e)
# if o.status == ValidateOverlayInfo.MERGE:
# try:
# (object, validity) = o.overlayObject.merge(o.deliveryObject, task)
# object.checkin('public', 'Makes object public.')
## logger.Print("%s (%s, %s)" % (object, o.overlayObject, o.deliveryObject))
# except Exception, e:
# logger.Error("%s" % e)
else:
mergeObjects(logger, obj, task)
def validate(session, inputfile, overlaydir, showBranchInfo, createtask=False, releasetag = None, extra_objects = None, logname = "validate_overlay"):
""" Validate an overlay uisng data from the inputfile to generate the virtual build area. """
vba = virtualbuildarea.create(session, open(inputfile, 'r'))
print overlaydir
if extra_objects is None:
extra_objects = []
overlay = session.get_workarea_info(overlaydir)['project']
voresult = ValidateOverlay(vba, vba.root_dir(), overlay, getObjectPath(overlay, [overlay.name, 'common', 'files']), extra_objects)
mclogger = helium.logger.Logger()
mclogger.SetInterface("http://fawww.europe.nokia.com/isis/isis_interface/")
mclogger.SetTitle("Validate Overlay")
mclogger.SetSubTitle("Validating: %s" % overlay)
mclogger.OpenMainContent("Analysing %s" % overlay)
showValidateOverlayInfo(mclogger, voresult, showBranchInfo)
mclogger.CloseMainContent()
if createtask and releasetag != None:
mclogger.OpenMainContent("Creating merge task")
team = 'TEAM_NAME'
if os.environ.has_key('TEAM'):
team = os.environ['TEAM']
try:
task = ccm.Task.create(session, session.create(releasetag), "%s: %s: %s: Merge task" % (team, overlay.name, os.environ['USERNAME']))
#task = session.create("Task fa1f5132#17458")
task.assign(os.environ['USERNAME'])
mclogger.Print("Created task %s.\n" % task['displayname'])
mergeObjects(mclogger, voresult, task)
except Exception, e:
traceback.print_exc(file=sys.stdout)
mclogger.Error(e)
mclogger.CloseMainContent()
mclogger.WriteToFile(logname + ".xml")
g = XML2XHTML(logname+".xml")
g.addCSSLink("http://fawww.europe.nokia.com/isis/isis_interface/css/overlaycheck.css")
g.generate()
g.WriteToFile(logname + ".html")
def main():
usage = "usage: %prog [options] arg1 arg2"
parser = optparse.OptionParser(usage=usage)
parser.add_option("--host", dest="ccm_host", action="store",
help="Synergy Host")
parser.add_option("-d", "--db", dest="ccm_db", action="store",
help="Synergy database")
parser.add_option("-u", "--username", dest="ccm_login", action="store",
help="Synergy username")
parser.add_option("-p", "--password", dest="ccm_password", action="store",
help="Synergy user password")
parser.add_option("-c", "--config", dest="inputfile", action="store",
help="Configuration file", metavar="PATH")
parser.add_option("-o", "--overlay", dest="overlaydir", action="store",
help="Overlay work area directory", metavar="PATH")
parser.add_option("--showBranchInfo", dest="showBranchInfo", action="store_true",
help="Show up branch information", default=False)
parser.add_option("--ct", dest="createtask", action="store_true",
help="Create merge task", default=False)
parser.add_option("--rt", dest="releasetag", action="store",
help="Release tag", default=None)
(options, args) = parser.parse_args()
session = nokia.nokiaccm.open_session(options.ccm_login, options.ccm_password, options.ccm_host, options.ccm_db)
validate(session, options.inputfile, options.overlaydir, options.showBranchInfo, options.createtask, options.releasetag)
session.close()
if __name__ == "__main__":
main()
#vba = virtualbuildarea.VirtualProject(session,'vba')
#try:
# #dom = xml.dom.minidom.parse(input)
# dom = xml.dom.minidom.parseString(input)
#except Exception, e:
# raise Exception("XML cannot be parsed properly %s" % e)
#
#virtualBA = dom.documentElement
#for child in virtualBA.childNodes:
# if (child.nodeType == xml.dom.Node.ELEMENT_NODE) and (child.nodeName=='add'):
# print "add node :%s (%d)" % (child.getAttribute('project'),len(child.childNodes))
# pathobject = createVirtualPath(child.getAttribute('to').split('/'),vba)
# if len(child.childNodes)==0:
# p = session.create(child.getAttribute('project'))
# pathobject.addChild(p,p)
# else:
# project = session.create(child.getAttribute('project'))
# for subChild in child.childNodes:
# if (subChild.nodeType == xml.dom.Node.ELEMENT_NODE) and (subChild.nodeName=='objects'):
# spath = removeEmptyStrings(subChild.getAttribute('from').split('/'))
# for t in getObjects(project,spath):
# pathobject.addChild(t['object'],t['project'])
#
#print "******************************************"
def showVirtualContent(project, path, indent=''):
if not isinstance(path, virtualbuildarea.VirtualDir):
return
print "%s+ %s" % (indent, path)
indent += " "
for obj in path.children(project):
if (obj.type == 'dir'):
showVirtualContent(project, obj, indent)
else:
print "%s- %s" % (indent, obj)
#showVirtualContent(vba, vba.root_dir())
def get_additional_delivery_objects(session, deliveryinput):
objects = []
delivery = amara.parse(open(deliveryinput, 'r'))
for t in delivery.xml_xpath('/deliveryConfiguration//task[@id]'):
for task in map(lambda x: x.strip(), t.id.split(',')):
objects.extend(session.create("Task %s" % task).objects)
for f in delivery.xml_xpath('/deliveryConfiguration//folder[@id]'):
for folder in map(lambda x: x.strip(), f.id.split(',')):
objects.extend(session.create("Folder %s" % folder).objects)
return objects