Module validateoverlay |
[hide private]
[frames] | no frames]

# Source Code for Module validateoverlay

      1  #============================================================================
      2  #Name        : validateoverlay.py
      3  #Part of     : Helium
      4
      5  #Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
      6  #All rights reserved.
      7  #This component and the accompanying materials are made available
      8  #under the terms of the License "Eclipse Public License v1.0"
      9  #which accompanies this distribution, and is available
     10  #at the URL "http://www.eclipse.org/legal/epl-v10.html".
     11  #
     12  #Initial Contributors:
     13  #Nokia Corporation - initial contribution.
     14  #
     15  #Contributors:
     16  #
     17  #Description:
     18  #===============================================================================
     19
     20
     21
     22  import StringIO
     23  import sys
     24  import os
     25  import optparse
     26  import traceback
     27
     28  import amara
     29
     30  import ccm
     31  import comments
     32  import helium.logger
     33  from helium.outputer import XML2XHTML
     34  import nokia.nokiaccm
     35  import virtualbuildarea
     36
     37
     38 -def __findChild(p, d, name):
     39      if (p is None or d is None):
     40          return None
     41      for child in d.children(p):
     42          if name.lower() == child.name.lower():
     43              return child
     44      return None
     45
     46 -def __getDir(p, o):
     47      if (o.type == 'project'):
     48          return o, o.root_dir()
     49      return p, o
     50
     51 -class ValidateOverlayInfo:
     52      UNKNOW = 0
     53      STILL_VALID = 1
     54      MERGE = 2
     55 -    def __init__(self, name):
     56          self.name = name
     57          #self.status = status
     58          self.overlayObject = None
     59          self.deliveryObjects = []
     60
     61 -def ValidateOverlay(vproject, vdir, oproject, odir, extraobject = None):
     62      """ This function scan an the virtual build area and the overlay to validate
     63          if the overlay content is still up to date compare to the delivery.
     64      """
     65      if extraobject is None:
     66          extraobject = []
     67      print "ValidateOverlay(%s,%s,%s,%s)" % (vproject, vdir, oproject, odir)
     68      result = {'name': odir.name, 'content': []}
     69      for child in odir.children(oproject):
     70          o = __findChild(vproject, vdir, child.name)
     71          if o is None:
     72              if (child.type == 'dir' or child.type == 'project'):
     73                  op, oo = __getDir(oproject, child)
     74                  result['content'].append(ValidateOverlay(None, None, op, oo, extraobject))
     75              else:
     76                  info = ValidateOverlayInfo(child.name)
     77                  info.overlayObject = child
     78                  result['content'].append(info)
     79          else:
     80              if (child.type == 'dir' or child.type == 'project'):
     81                  vp, vo = __getDir(vproject, o)
     82                  op, oo = __getDir(oproject, child)
     83                  result['content'].append(ValidateOverlay(vp, vo, op, oo, extraobject))
     84              else:
     85                  info = ValidateOverlayInfo(child.name)
     86                  info.overlayObject = child
     87                  info.deliveryObjects.append({'status': ValidateOverlayInfo.UNKNOW, 'object': o})
     88
     89                  for eo in extraobject:
     90                      if eo.is_same_family(o):
     91                          info.deliveryObjects.append({'status': ValidateOverlayInfo.UNKNOW, 'object': eo})
     92
     93                  for delivery in info.deliveryObjects:
     94                      if child.is_recursive_sucessor_of(delivery['object']):
     95                          delivery['status'] = ValidateOverlayInfo.STILL_VALID
     96                      else:
     97                          delivery['status'] = ValidateOverlayInfo.MERGE
     98
     99                  result['content'].append(info)
    100      return result
    101
    102 -def getObjectPath(project, spath, dir=None):
    103      name = spath.pop(0)
    104      if (dir == None):
    105          if project.root_dir().name.lower() == name.lower():
    106              return getObjectPath(project, spath, project.root_dir())
    107          raise Exception("project.root_dir().name.lower()!=name.lower():")
    108      else:
    109          for o in dir.children(project):
    110              if o.name.lower() == name.lower():
    111                  if len(spath) == 0:
    112                      return o
    113                  elif o.type == 'dir':
    114                      return getObjectPath(project, spath, o)
    115                  else:
    116                      raise Exception("Object could not be accessed")
    117          raise Exception("Object not found")
    118
    119 -def showBranchInfo(logger, object):
    120      doc = comments.CommentParser.scan_content(str(object.overlayObject), object.overlayObject.content(), "branchInfo")
    121      if len(doc.commentLog.xml_xpath('branchInfo'))>0:
    122          for child in doc.commentLog.xml_xpath('branchInfo'):
    123              logger.PrintRaw("<b>Branch Information:</b>\n")
    124              if hasattr(child, 'xml_attributes'):
    125                  for attr in child.xml_attributes:
    126                      logger.PrintRaw("<b>%s:</b> %s\n" % (attr, getattr(child, attr)))
    127                      if hasattr(child, 'branch'):
    128                          logger.PrintRaw("<b>Should validate compare to file:</b> %s\n" % child.branch)
    129      else:
    130          logger.Print("No branch info...\n")
    131
    132 -def showValidity(logger, obj):
    133      if len(obj.deliveryObjects)==0:
    134          logger.NotFound("Could not find %s relative objects." % (obj.overlayObject))
    135      else:
    136          for delivery in obj.deliveryObjects:
    137              if (delivery['status'] == ValidateOverlayInfo.MERGE):
    138                  logger.Merge("Overlay object %s requires a merge with %s." % (obj.overlayObject, delivery['object']))
    139              elif (delivery['status'] == ValidateOverlayInfo.STILL_VALID):
    140                  logger.Valid("%s is still a successor of %s." % (obj.overlayObject, delivery['object']))
    141
    142
    143 -def showValidateOverlayInfo(logger, data, comments=False):
    144      logger.OpenEvent(data['name'])
    145      for o in data['content']:
    146          if isinstance(o, ValidateOverlayInfo):
    147              logger.OpenEvent(o.name)
    148              showValidity(logger, o)
    149              # Showing branch information.
    150              if comments:
    151                  showBranchInfo(logger, o)
    152              logger.CloseEvent()
    153          else:
    154              showValidateOverlayInfo(logger, o, comments)
    155      logger.CloseEvent()
    156
    157 -def mergeObjects(logger, data, task):
    158      for obj in data['content']:
    159          if isinstance(obj, ValidateOverlayInfo):
    160              mergedobject = None
    161              for delivery in obj.deliveryObjects:
    162                  if (delivery['status'] == ValidateOverlayInfo.MERGE):
    163                      try:
    164                          if not mergedobject:
    165                              (mergedobject, validity) = obj.overlayObject.merge(delivery['object'], task)
    166                              mergedobject.checkin('public', 'Makes object public.')
    167                              logger.Print("%s (%s, %s)" % (mergedobject, obj.overlayObject, delivery['object']))
    168                          else:
    169                              delivery['object'].relate(mergedobject)
    170                              logger.Print("%s (%s, %s)" % (mergedobject, obj.overlayObject, delivery['object']))
    171                              #mergedobject
    172                      except Exception, e:
    173                          logger.Error("%s" % e)
    174  #            if o.status == ValidateOverlayInfo.MERGE:
    175  #                try:
    176  #                    (object, validity) = o.overlayObject.merge(o.deliveryObject, task)
    177  #                    object.checkin('public', 'Makes object public.')
    178  ##                   logger.Print("%s (%s, %s)" % (object, o.overlayObject, o.deliveryObject))
    179  #                except Exception, e:
    180  #                    logger.Error("%s" % e)
    181          else:
    182              mergeObjects(logger, obj, task)
    183
    184
    185 -def validate(session, inputfile, overlaydir, showBranchInfo, createtask=False, releasetag = None, extra_objects = None, logname = "validate_overlay"):
    186      """ Validate an overlay uisng data from the inputfile to generate the virtual build area. """
    187      vba = virtualbuildarea.create(session, open(inputfile, 'r'))
    188      print overlaydir
    189      if extra_objects is None:
    190          extra_objects = []
    191      overlay = session.get_workarea_info(overlaydir)['project']
    192      voresult = ValidateOverlay(vba, vba.root_dir(), overlay, getObjectPath(overlay, [overlay.name, 'common', 'files']), extra_objects)
    193
    194      mclogger = helium.logger.Logger()
    195      mclogger.SetInterface("http://fawww.europe.nokia.com/isis/isis_interface/")
    196      mclogger.SetTitle("Validate Overlay")
    197      mclogger.SetSubTitle("Validating: %s" % overlay)
    198      mclogger.OpenMainContent("Analysing %s" % overlay)
    199      showValidateOverlayInfo(mclogger, voresult, showBranchInfo)
    200      mclogger.CloseMainContent()
    201      if createtask and releasetag != None:
    202          mclogger.OpenMainContent("Creating merge task")
    203          team = 'TEAM_NAME'
    204          if os.environ.has_key('TEAM'):
    205              team = os.environ['TEAM']
    206          try:
    207              task = ccm.Task.create(session, session.create(releasetag), "%s: %s: %s: Merge task" % (team, overlay.name, os.environ['USERNAME']))
    208              #task = session.create("Task fa1f5132#17458")
    209              task.assign(os.environ['USERNAME'])
    210              mclogger.Print("Created task %s.\n" % task['displayname'])
    211              mergeObjects(mclogger, voresult, task)
    212          except Exception, e:
    213              traceback.print_exc(file=sys.stdout)
    214              mclogger.Error(e)
    215          mclogger.CloseMainContent()
    216
    217      mclogger.WriteToFile(logname + ".xml")
    218      g = XML2XHTML(logname+".xml")
    219      g.addCSSLink("http://fawww.europe.nokia.com/isis/isis_interface/css/overlaycheck.css")
    220      g.generate()
    221      g.WriteToFile(logname + ".html")
    222
    223
    224 -def main():
    225
    226      usage = "usage: %prog [options] arg1 arg2"
    227      parser = optparse.OptionParser(usage=usage)
    228      parser.add_option("--host", dest="ccm_host", action="store",
    229                                  help="Synergy Host")
    230      parser.add_option("-d", "--db", dest="ccm_db", action="store",
    231                                  help="Synergy database")
    232      parser.add_option("-u", "--username", dest="ccm_login",  action="store",
    233                                  help="Synergy username")
    234      parser.add_option("-p", "--password", dest="ccm_password",  action="store",
    235                                  help="Synergy user password")
    236      parser.add_option("-c",  "--config", dest="inputfile", action="store",
    237                                  help="Configuration file", metavar="PATH")
    238      parser.add_option("-o", "--overlay", dest="overlaydir", action="store",
    239                                  help="Overlay work area directory", metavar="PATH")
    240      parser.add_option("--showBranchInfo", dest="showBranchInfo", action="store_true",
    241                                  help="Show up branch information", default=False)
    242      parser.add_option("--ct", dest="createtask", action="store_true",
    243                                  help="Create merge task", default=False)
    244      parser.add_option("--rt", dest="releasetag", action="store",
    245                                  help="Release tag", default=None)
    246
    247      (options, args) = parser.parse_args()
    248      session = nokia.nokiaccm.open_session(options.ccm_login, options.ccm_password, options.ccm_host, options.ccm_db)
    249      validate(session, options.inputfile, options.overlaydir, options.showBranchInfo, options.createtask, options.releasetag)
    250      session.close()
    251
    252  if __name__ == "__main__":
    253      main()
    254
    255  #vba = virtualbuildarea.VirtualProject(session,'vba')
    256
    257  #try:
    258  #    #dom = xml.dom.minidom.parse(input)
    259  #    dom = xml.dom.minidom.parseString(input)
    260  #except Exception, e:
    261  #    raise Exception("XML cannot be parsed properly %s" % e)
    262  #
    263  #virtualBA = dom.documentElement
    264  #for child in virtualBA.childNodes:
    265  #    if (child.nodeType == xml.dom.Node.ELEMENT_NODE) and (child.nodeName=='add'):
    266  #        print "add node :%s (%d)" % (child.getAttribute('project'),len(child.childNodes))
    267  #        pathobject = createVirtualPath(child.getAttribute('to').split('/'),vba)
    268  #        if len(child.childNodes)==0:
    269  #            p = session.create(child.getAttribute('project'))
    270  #            pathobject.addChild(p,p)
    271  #        else:
    272  #            project = session.create(child.getAttribute('project'))
    273  #            for subChild in child.childNodes:
    274  #                if (subChild.nodeType == xml.dom.Node.ELEMENT_NODE) and (subChild.nodeName=='objects'):
    275  #                    spath = removeEmptyStrings(subChild.getAttribute('from').split('/'))
    276  #                    for t in getObjects(project,spath):
    277  #                        pathobject.addChild(t['object'],t['project'])
    278  #
    279
    280
    281  #print "******************************************"
    282 -def showVirtualContent(project, path, indent=''):
    283      if not isinstance(path, virtualbuildarea.VirtualDir):
    284          return
    285      print "%s+ %s" % (indent, path)
    286      indent += "   "
    287      for obj in path.children(project):
    288          if (obj.type == 'dir'):
    289              showVirtualContent(project, obj, indent)
    290          else:
    291              print "%s- %s" % (indent, obj)
    292
    293  #showVirtualContent(vba, vba.root_dir())
    294
    295 -def get_additional_delivery_objects(session, deliveryinput):
    296      objects = []
    297      delivery = amara.parse(open(deliveryinput, 'r'))
    298      for t in delivery.xml_xpath('/deliveryConfiguration//task[@id]'):
    299          for task in map(lambda x: x.strip(), t.id.split(',')):
    300              objects.extend(session.create("Task %s" % task).objects)
    301      for f in delivery.xml_xpath('/deliveryConfiguration//folder[@id]'):
    302          for folder in map(lambda x: x.strip(), f.id.split(',')):
    303              objects.extend(session.create("Folder %s" % folder).objects)
    304      return objects
    305