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

Source Code for Module dependancygraph

  1  #============================================================================  
  2  #Name        : dependancygraph.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  import os 
 21  import amara 
 22  import codecs 
 23  import zipfile 
 24  from Ft.Lib import Uri 
 25   
26 -class Library:
27 - def __init__(self, name, license, version=''):
28 self.name = name 29 self.license = license 30 self.version = version 31 self.requires = []
32
33 -class ModuleGroup:
34 - def __init__(self):
35 self.libraries = {}
36 - def addConf(self, name, des, color):
37 self.libraries[name] = (des, [], color)
38 - def addLibrary(self, conf, library):
39 for lib in self.getLibraries(conf): 40 if lib.name.lower() == library.name.lower(): 41 lib.license = library.license 42 return 43 self.getLibraries(conf).append(library)
44 - def getLibraries(self, conf):
45 (_, libs, _) = self.libraries[conf] 46 return libs
47 - def getDescription(self, conf):
48 (des, _, _) = self.libraries[conf] 49 return des
50 - def getColor(self, conf):
51 (_, _, color) = self.libraries[conf] 52 return color
53 54 COLORS = ['pink', 'red', 'lightblue', 'orange', 'green', 'yellow', 'turquoise', 'limegreen'] 55
56 -class ReadIvyConfig:
57 - def __init__(self, ivyfilename):
58 self.ivyfilename = ivyfilename 59 self.ivyxml = amara.parse(Uri.OsPathToUri(ivyfilename)) 60 self.group = ModuleGroup()
61
62 - def readConfigurations(self):
63 for conf in self.ivyxml['ivy-module'].configurations.conf: 64 color = COLORS.pop() 65 self.group.addConf(conf.name, conf.description, color)
66
67 - def readModules(self):
68 license = '' 69 for module in self.ivyxml['ivy-module'].dependencies.xml_children: 70 if hasattr(module, 'data'): 71 if 'License:' in module.data: 72 license = module.data.strip() 73 elif hasattr(module, 'name'): 74 modulename = module.name.replace('-', '_') 75 76 if module.org != 'SWEPT': 77 self.group.addLibrary(module.conf, Library(modulename, license)) 78 license = ''
79
80 - def readSubModules(self):
81 for module in self.ivyxml['ivy-module'].dependencies.xml_children: 82 if hasattr(module, 'name'): 83 if 'jars' in module.name: 84 ivydir = os.path.dirname(self.ivyfilename) 85 ivydir = os.path.join(ivydir, 'modules') 86 ivyjarfile = os.path.join(ivydir, module.name + '-1.0.ivy.xml') 87 ivymodulexml = amara.parse(Uri.OsPathToUri(ivyjarfile)) 88 license = '' 89 for artifact in ivymodulexml['ivy-module'].publications.xml_children: 90 if hasattr(artifact, 'data'): 91 if 'License:' in artifact.data: 92 license = artifact.data.strip() 93 elif hasattr(artifact, 'name'): 94 bits = artifact.name.split('-') 95 name = bits[0] 96 version = '' 97 if len(bits) > 1: 98 version = bits[1] 99 self.group.addLibrary(module.conf, Library(name, license, version)) 100 license = ''
101 102 PYTHON_GROUP = True 103 SUBCON_PYTHON_GROUP = False 104
105 -def readEggs(libraries, dirtosearch, internaldir):
106 libraries.addConf(PYTHON_GROUP, 'Python libs', libraries.getColor('core_install')) 107 libraries.addConf(SUBCON_PYTHON_GROUP, 'Python subcon libs', libraries.getColor('subcon')) 108 109 for x in [os.walk(dirtosearch, topdown=False), os.walk(internaldir, topdown=False)]: 110 for root, _, files in x: 111 notinsubcon = os.path.normpath(internaldir) in os.path.normpath(root) 112 113 for fname in files: 114 filename = os.path.join(root, fname) 115 if fname == 'PKG-INFO': 116 pkgmetafile = open(filename) 117 library = readPkgInfo(pkgmetafile) 118 pkgmetafile.close() 119 120 requirefilename = os.path.join(filename, '..', 'requires.txt') 121 if os.path.exists(requirefilename): 122 requiresfile = open(requirefilename) 123 readRequiresFile(requiresfile, library) 124 requiresfile.close() 125 126 libraries.addLibrary(notinsubcon, library) 127 128 if os.path.isfile(filename) and fname.endswith('.egg'): 129 eggfile = zipfile.ZipFile(filename, 'r', zipfile.ZIP_DEFLATED) 130 131 data = eggfile.read('EGG-INFO/PKG-INFO') 132 133 library = readPkgInfo(data.split('\n')) 134 135 if 'EGG-INFO/requires.txt' in eggfile.namelist(): 136 requiresdata = eggfile.read('EGG-INFO/requires.txt') 137 readRequiresFile(requiresdata.split('\n'), library) 138 139 libraries.addLibrary(notinsubcon, library) 140 141 eggfile.close()
142
143 -def readRequiresFile(data, library):
144 for line in data: 145 line = line.strip() 146 if line != '' and not (line.startswith('[') and line.endswith(']')): 147 library.requires.append(line.split('>=')[0].strip())
148
149 -def readPkgInfo(data):
150 name = '' 151 version = '' 152 license = '' 153 license2 = '' 154 155 for line in data: 156 if 'Name:' in line: 157 name = line.strip().replace('Name: ', '') 158 if 'Version:' in line: 159 version = line.strip().replace('Version: ', '') 160 if 'License:' in line: 161 license = line.strip().replace('License: ', '') 162 if 'Classifier: License :: ' in line: 163 license2 = license2 + ' ' + line.strip().replace('Classifier: License :: ', '').replace('OSI Approved :: ', '') 164 165 if license.lower() == 'unknown' or license == '' or license2 != '': 166 license = license2 167 168 return Library(name, license, version)
169
170 -def addLicensesColors(graphdata, group):
171 newgraphdata = [] 172 for line in graphdata: 173 newline = line 174 for conf in group.libraries: 175 for module in group.getLibraries(conf): 176 if module.name.lower() in line.lower() and 'label=' in line: 177 newline = line.replace('label=', 'color=%s,label=' % group.getColor(conf)) 178 179 if module.license != '': 180 newline = newline.replace("\"];", "|%s\"];" % module.license) 181 182 break 183 newgraphdata.append(newline) 184 return newgraphdata
185
186 -def createKey(group):
187 key = """subgraph cluster1 { 188 label = "Key"; 189 style=filled; 190 color=lightgrey; 191 """ 192 193 for conf in group.libraries: 194 if conf != PYTHON_GROUP and conf != SUBCON_PYTHON_GROUP: 195 key = key + "\"%s: %s\" [style=filled,color=%s];" % (conf, group.getDescription(conf), group.getColor(conf)) 196 197 key = key + "}" 198 return key
199
200 -def createGraph(ivyxmlfilename, graphfilename, dirtosearch, internaldir, subcon):
201 readivy = ReadIvyConfig(ivyxmlfilename) 202 readivy.readConfigurations() 203 readivy.readModules() 204 readivy.readSubModules() 205 206 group = readivy.group 207 208 readEggs(group, dirtosearch, internaldir) 209 210 key = createKey(group) 211 212 graphdata = loadGraphFile(graphfilename) 213 214 newgraphdata = addLicensesColors(graphdata, group) 215 216 #add key to graph 217 newgraphdata[-1] = newgraphdata[-1].replace('}', key + '\n}') 218 219 graphwritefile = codecs.open(graphfilename, 'w', 'utf8') 220 graphwritefile.writelines(newgraphdata) 221 graphwritefile.close() 222 223 linkPythonLibs(group, graphfilename, subcon)
224
225 -def loadGraphFile(graphfilename):
226 destgraphfile = codecs.open(graphfilename, 'r', 'utf8') 227 graphdata = [] 228 for line in destgraphfile: 229 graphdata.append(line) 230 destgraphfile.close() 231 return graphdata
232
233 -def addToGraph(graphfilenametoadd, destgraphfilename):
234 graphdata = loadGraphFile(destgraphfilename) 235 236 graphfile = codecs.open(graphfilenametoadd, 'r', 'utf8') 237 graphdatatoadd = '' 238 for line in graphfile: 239 line = line.replace('digraph {', '') 240 graphdatatoadd = graphdatatoadd + line 241 graphfile.close() 242 243 graphdata[-1] = graphdata[-1].replace('}', graphdatatoadd) 244 245 graphwritefile = codecs.open(destgraphfilename, 'w', 'utf8') 246 graphwritefile.writelines(graphdata) 247 graphwritefile.close()
248
249 -def linkPythonLibs(libraries, destgraphfilename, subcon):
250 graphdata = loadGraphFile(destgraphfilename) 251 252 output = "helium_ant -> helium_python;\n" 253 254 if subcon: 255 list = [SUBCON_PYTHON_GROUP] 256 else: 257 list = [SUBCON_PYTHON_GROUP, PYTHON_GROUP] 258 259 for group in list: 260 for lib in libraries.getLibraries(group): 261 output = output + ("helium_python -> \"%s\";\n" % lib.name) 262 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)) 263 264 for require in lib.requires: 265 output = output + ("\"%s\" -> \"%s\";\n" % (lib.name, require)) 266 267 graphdata.reverse() 268 for line in graphdata: 269 if line.strip() == '': 270 graphdata.pop(0) 271 else: 272 break 273 graphdata.reverse() 274 275 graphdata[-1] = graphdata[-1].replace('}', output + '}') 276 277 graphwritefile = codecs.open(destgraphfilename, 'w', 'utf8') 278 graphwritefile.writelines(graphdata) 279 graphwritefile.close() 280
281 -def externalDependancies(database, output):
282 out = open(output, 'w') 283 db = amara.parse(Uri.OsPathToUri(database)) 284 out.write('digraph G {\n') 285 for p in db.antDatabase.project: 286 items = [] 287 if hasattr(p, 'property'): 288 for prop in p.property: 289 if 'external' + os.sep in os.path.abspath(str(prop.defaultValue)): 290 items.append(str(prop.defaultValue)) 291 if hasattr(p, 'fileDependency'): 292 for dep in p.fileDependency: 293 dep = str(dep).split(' ')[0] 294 if 'external' + os.sep in os.path.abspath(str(dep)): 295 items.append(str(dep)) 296 297 items = set(items) 298 for i in items: 299 out.write('\"%s\" -> \"%s\"\n' % (str(p.name), i.replace(os.environ['HELIUM_HOME'], 'helium').replace(os.sep, '/'))) 300 out.write('}') 301 out.close()
302
303 -def appendLogs(t, p, output, macro=False):
304 if hasattr(t, 'signal'): 305 for signal in t.signal: 306 if macro: 307 output.append("\"%s\" [fontname=\"Times-Italic\"];" % str(t.name)) 308 output.append('subgraph \"cluster%s\" {label = \"%s\"; \"%s\"}\n' % (str(p.name), str(p.name), str(t.name))) 309 output.append('\"%s\" -> \"%s\" [style=dotted]\n' % (str(t.name), signal)) 310 if hasattr(t, 'log'): 311 for log in t.log: 312 logdir = '/output/logs/' 313 logname = os.path.basename(str(log)) 314 if not ('**' in logname): 315 logname = logname.replace('*', '${sysdef.configuration}').replace('--logfile=', '') 316 if not logdir in logname: 317 logname = logdir + logname 318 logname = logname.replace(os.sep, '/') 319 320 if macro: 321 output.append("\"%s\" [fontname=\"Times-Italic\"];" % str(t.name)) 322 output.append('subgraph \"cluster%s\" {label = \"%s\"; \"%s\"}\n' % (str(p.name), str(p.name), str(t.name))) 323 output.append('\"%s\" -> \"%s\"\n' % (str(t.name), logname))
324
325 -def findLogFiles(database, output):
326 out = open(output, 'w') 327 db = amara.parse(Uri.OsPathToUri(database)) 328 out.write('digraph G {\n') 329 output = [] 330 331 for p in db.antDatabase.project: 332 if hasattr(p, 'macro'): 333 for t in p.macro: 334 appendLogs(t, p, output, True) 335 if hasattr(p, 'target'): 336 for t in p.target: 337 appendLogs(t, p, output) 338 for l in set(output): 339 out.write(l) 340 out.write('}') 341 out.close()
342