--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/buildframework/helium/sf/python/pythoncore/lib/dependancygraph.py Tue Apr 27 08:33:08 2010 +0300
@@ -0,0 +1,376 @@
+#============================================================================
+#Name : dependancygraph.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:
+#===============================================================================
+"""create the dependancy graph for the documentation"""
+
+import os
+import amara
+import codecs
+import zipfile
+
+class Library:
+ """ Class Library holds information of the required modules or components such as license and the version """
+ def __init__(self, name, license, version=''):
+ self.name = name
+ self.license = license
+ self.version = version
+ self.requires = []
+
+class ModuleGroup:
+ """ This class represents a group of module """
+ def __init__(self):
+ self.libraries = {}
+ def addConf(self, name, des, color):
+ """add configuration"""
+ self.libraries[name] = (des, [], color)
+ def addLibrary(self, conf, library):
+ """add library"""
+ for lib in self.getLibraries(conf):
+ if lib.name.lower() == library.name.lower():
+ lib.license = library.license
+ return
+ self.getLibraries(conf).append(library)
+ def getLibraries(self, conf):
+ """get Libraries"""
+ (_, libs, _) = self.libraries[conf]
+ return libs
+ def getDescription(self, conf):
+ """get description"""
+ (des, _, _) = self.libraries[conf]
+ return des
+ def getColor(self, conf):
+ """get colour"""
+ (_, _, color) = self.libraries[conf]
+ return color
+
+COLORS = ['pink', 'red', 'lightblue', 'orange', 'green', 'yellow', 'turquoise', 'limegreen']
+
+class ReadIvyConfig:
+ """ Class to read the ivy configuration """
+ def __init__(self, ivyfilename):
+ self.ivyfilename = ivyfilename
+ self.ivyxml = amara.parse(open(ivyfilename))
+ self.group = ModuleGroup()
+
+ def readConfigurations(self):
+ """read configurations"""
+ for conf in self.ivyxml['ivy-module'].configurations.conf:
+ color = COLORS.pop()
+ self.group.addConf(conf.name, conf.description, color)
+
+ def readModules(self):
+ """read modules"""
+ license = ''
+ for module in self.ivyxml['ivy-module'].dependencies.xml_children:
+ if hasattr(module, 'data'):
+ if 'License:' in module.data:
+ license = module.data.strip()
+ elif hasattr(module, 'name'):
+ modulename = module.name.replace('-', '_')
+
+ if module.org != 'SWEPT':
+ self.group.addLibrary(module.conf, Library(modulename, license))
+ license = ''
+
+ def readSubModules(self):
+ """read Sub Modules"""
+ for module in self.ivyxml['ivy-module'].dependencies.xml_children:
+ if hasattr(module, 'name'):
+ if 'jars' in module.name:
+ ivydir = os.path.dirname(self.ivyfilename)
+ ivydir = os.path.join(ivydir, 'modules')
+ ivyjarfile = os.path.join(ivydir, module.name + '-1.0.ivy.xml')
+ ivymodulexml = amara.parse(open(ivyjarfile))
+ license = ''
+ for artifact in ivymodulexml['ivy-module'].publications.xml_children:
+ if hasattr(artifact, 'data'):
+ if 'License:' in artifact.data:
+ license = artifact.data.strip()
+ elif hasattr(artifact, 'name'):
+ bits = artifact.name.split('-')
+ name = bits[0]
+ version = ''
+ if len(bits) > 1:
+ version = bits[1]
+ self.group.addLibrary(module.conf, Library(name, license, version))
+ license = ''
+
+PYTHON_GROUP = True
+SUBCON_PYTHON_GROUP = False
+
+def readEggs(libraries, dirtosearch, internaldir):
+ """read Egg files"""
+ libraries.addConf(PYTHON_GROUP, 'Python libs', libraries.getColor('core_install'))
+ libraries.addConf(SUBCON_PYTHON_GROUP, 'Python subcon libs', libraries.getColor('subcon'))
+
+ for _xx in [os.walk(dirtosearch, topdown=False), os.walk(internaldir, topdown=False)]:
+ for root, _, files in _xx:
+ notinsubcon = os.path.normpath(internaldir) in os.path.normpath(root)
+
+ for fname in files:
+ filename = os.path.join(root, fname)
+ if fname == 'PKG-INFO':
+ pkgmetafile = open(filename)
+ library = readPkgInfo(pkgmetafile)
+ pkgmetafile.close()
+
+ requirefilename = os.path.join(filename, '..', 'requires.txt')
+ if os.path.exists(requirefilename):
+ requiresfile = open(requirefilename)
+ readRequiresFile(requiresfile, library)
+ requiresfile.close()
+
+ libraries.addLibrary(notinsubcon, library)
+
+ if os.path.isfile(filename) and fname.endswith('.egg'):
+ eggfile = zipfile.ZipFile(filename, 'r', zipfile.ZIP_DEFLATED)
+
+ data = eggfile.read('EGG-INFO/PKG-INFO')
+
+ library = readPkgInfo(data.split('\n'))
+
+ if 'EGG-INFO/requires.txt' in eggfile.namelist():
+ requiresdata = eggfile.read('EGG-INFO/requires.txt')
+ readRequiresFile(requiresdata.split('\n'), library)
+
+ libraries.addLibrary(notinsubcon, library)
+
+ eggfile.close()
+
+def readRequiresFile(data, library):
+ """read Requires File"""
+ for line in data:
+ line = line.strip()
+ if line != '' and not (line.startswith('[') and line.endswith(']')):
+ library.requires.append(line.split('>=')[0].strip())
+
+def readPkgInfo(data):
+ """read Pkg info"""
+ name = ''
+ version = ''
+ license = ''
+ license2 = ''
+
+ for line in data:
+ if 'Name:' in line:
+ name = line.strip().replace('Name: ', '')
+ if 'Version:' in line:
+ version = line.strip().replace('Version: ', '')
+ if 'License:' in line:
+ license = line.strip().replace('License: ', '')
+ if 'Classifier: License :: ' in line:
+ license2 = license2 + ' ' + line.strip().replace('Classifier: License :: ', '').replace('OSI Approved :: ', '')
+
+ if license.lower() == 'unknown' or license == '' or license2 != '':
+ license = license2
+
+ return Library(name, license, version)
+
+def addLicensesColors(graphdata, group):
+ """add license colours"""
+ newgraphdata = []
+ for line in graphdata:
+ newline = line
+ for conf in group.libraries:
+ for module in group.getLibraries(conf):
+ if module.name.lower() in line.lower() and 'label=' in line:
+ newline = line.replace('label=', 'color=%s,label=' % group.getColor(conf))
+ if module.license != '':
+ newline = newline.replace("\"];", "|%s\"];" % module.license)
+ break
+ newgraphdata.append(newline)
+ return newgraphdata
+
+def createKey(group):
+ """create key"""
+ key = """subgraph cluster1 {
+ label = "Key";
+ style=filled;
+ color=lightgrey;
+ """
+
+ for conf in group.libraries:
+ if conf != PYTHON_GROUP and conf != SUBCON_PYTHON_GROUP:
+ key = key + "\"%s: %s\" [style=filled,color=%s];" % (conf, group.getDescription(conf), group.getColor(conf))
+
+ key = key + "}"
+ return key
+
+def createGraph(ivyxmlfilename, graphfilename, dirtosearch, internaldir, subcon):
+ """create graph """
+ readivy = ReadIvyConfig(ivyxmlfilename)
+ readivy.readConfigurations()
+ readivy.readModules()
+ readivy.readSubModules()
+
+ group = readivy.group
+
+ readEggs(group, dirtosearch, internaldir)
+
+ key = createKey(group)
+
+ graphdata = loadGraphFile(graphfilename)
+
+ newgraphdata = addLicensesColors(graphdata, group)
+
+ #add key to graph
+ newgraphdata[-1] = newgraphdata[-1].replace('}', key + '\n}')
+
+ graphwritefile = codecs.open(graphfilename, 'w', 'utf8')
+ graphwritefile.writelines(newgraphdata)
+ graphwritefile.close()
+
+ linkPythonLibs(group, graphfilename, subcon)
+
+def loadGraphFile(graphfilename):
+ """load graph file"""
+ destgraphfile = codecs.open(graphfilename, 'r', 'utf8')
+ graphdata = []
+ for line in destgraphfile:
+ graphdata.append(line)
+ destgraphfile.close()
+ return graphdata
+
+def addToGraph(graphfilenametoadd, destgraphfilename):
+ """add to graph"""
+ graphdata = loadGraphFile(destgraphfilename)
+
+ graphfile = codecs.open(graphfilenametoadd, 'r', 'utf8')
+ graphdatatoadd = ''
+ for line in graphfile:
+ line = line.replace('digraph {', '')
+ graphdatatoadd = graphdatatoadd + line
+ graphfile.close()
+
+ graphdata[-1] = graphdata[-1].replace('}', graphdatatoadd)
+
+ graphwritefile = codecs.open(destgraphfilename, 'w', 'utf8')
+ graphwritefile.writelines(graphdata)
+ graphwritefile.close()
+
+def linkPythonLibs(libraries, destgraphfilename, subcon):
+ """link Python Libraries"""
+ graphdata = loadGraphFile(destgraphfilename)
+
+ output = "helium_ant -> helium_python;\n"
+
+ if subcon:
+ list = [SUBCON_PYTHON_GROUP]
+ else:
+ list = [SUBCON_PYTHON_GROUP, PYTHON_GROUP]
+
+ for group in list:
+ for lib in libraries.getLibraries(group):
+ output = output + ("helium_python -> \"%s\";\n" % lib.name)
+ output = output + ("\"%s\" [style=filled,shape=record,color=%s,label=\"%s %s|%s\"];\n" % (lib.name, libraries.getColor(group), lib.name, lib.version, lib.license))
+
+ for require in lib.requires:
+ output = output + ("\"%s\" -> \"%s\";\n" % (lib.name, require))
+
+ graphdata.reverse()
+ for line in graphdata:
+ if line.strip() == '':
+ graphdata.pop(0)
+ else:
+ break
+ graphdata.reverse()
+
+ graphdata[-1] = graphdata[-1].replace('}', output + '}')
+
+ graphwritefile = codecs.open(destgraphfilename, 'w', 'utf8')
+ graphwritefile.writelines(graphdata)
+ graphwritefile.close()
+
+def externalDependancies(database, output):
+ """External Dependancies"""
+ out = open(output, 'w')
+ dbase = amara.parse(open(database))
+ out.write('digraph G {\n')
+ for proj in dbase.antDatabase.project:
+ items = []
+ if hasattr(proj, 'property'):
+ for prop in proj.property:
+ if 'external' + os.sep in os.path.abspath(str(prop.defaultValue)):
+ items.append(str(prop.defaultValue))
+ if hasattr(proj, 'fileDependency'):
+ for dep in proj.fileDependency:
+ dep = str(dep).split(' ')[0]
+ if 'external' + os.sep in os.path.abspath(str(dep)):
+ items.append(str(dep))
+
+ items = set(items)
+ for i in items:
+ out.write('\"%s\" -> \"%s\"\n' % (str(proj.name), i.replace(os.environ['HELIUM_HOME'], 'helium').replace(os.sep, '/')))
+ out.write('}')
+ out.close()
+
+def appendLogs(targ, proj, output, macro=False):
+ """append logs"""
+ if hasattr(targ, 'signal'):
+ for signal in targ.signal:
+ if macro:
+ output.append("\"%s\" [fontname=\"Times-Italic\"];" % str(targ.name))
+ output.append('subgraph \"cluster%s\" {label = \"%s\"; \"%s\"}\n' % (str(proj.name), str(proj.name), str(targ.name)))
+ splt = str(signal).split(',')
+ if len(splt) > 1:
+ if splt[1] == 'now':
+ color = 'red'
+ elif splt[1] == 'defer':
+ color = 'yellow'
+ else:
+ color = 'green'
+ output.append('subgraph \"cluster%s\" {color=%s;style=filled;label = \"Failbuild: %s\"; \"%s\"}\n' % (str(splt[1]), color, str(splt[1]), str(splt[0])))
+ output.append('\"%s\" -> \"%s\" [style=dotted]\n' % (str(targ.name), str(splt[0])))
+ if hasattr(targ, 'log'):
+ for log in targ.log:
+ logdir = '/output/logs/'
+ logname = os.path.basename(str(log))
+ if not ('**' in logname):
+ logname = logname.replace('*', '${sysdef.configuration}').replace('--logfile=', '')
+ if not logdir in logname:
+ logname = logdir + logname
+ logname = logname.replace(os.sep, '/')
+
+ if macro:
+ output.append("\"%s\" [fontname=\"Times-Italic\"];" % str(targ.name))
+ output.append('subgraph \"cluster%s\" {label = \"%s\"; \"%s\"}\n' % (str(proj.name), str(proj.name), str(targ.name)))
+ output.append('\"%s\" -> \"%s\"\n' % (str(targ.name), logname))
+
+def findLogFiles(database, output):
+ """find Log files"""
+ out = open(output, 'w')
+ dbase = amara.parse(open(database))
+ out.write('digraph G {\n')
+ output = []
+
+ root_objects = []
+ for project in dbase.antDatabase.project:
+ root_objects.append(project)
+ for antlib in dbase.antDatabase.antlib:
+ root_objects.append(antlib)
+ for p_ro in root_objects:
+ if hasattr(p_ro, 'macro'):
+ for t_targ in p_ro.macro:
+ appendLogs(t_targ, p_ro, output, True)
+ if hasattr(p_ro, 'target'):
+ for t_targ in p_ro.target:
+ appendLogs(t_targ, p_ro, output)
+ for l_list in set(output):
+ out.write(l_list)
+ out.write('}')
+ out.close()