comparison mxtool/mx.py @ 15149:2c7b18ae25d2

Add support for library dependencies
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 15 Apr 2014 17:45:51 +0200
parents 7357f62ed977
children f1c66b738dae
comparison
equal deleted inserted replaced
15148:7357f62ed977 15149:2c7b18ae25d2
404 _writeSha1Cached() 404 _writeSha1Cached()
405 405
406 return path 406 return path
407 407
408 class Library(Dependency): 408 class Library(Dependency):
409 def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1): 409 def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps):
410 Dependency.__init__(self, suite, name) 410 Dependency.__init__(self, suite, name)
411 self.path = path.replace('/', os.sep) 411 self.path = path.replace('/', os.sep)
412 self.urls = urls 412 self.urls = urls
413 self.sha1 = sha1 413 self.sha1 = sha1
414 self.mustExist = mustExist 414 self.mustExist = mustExist
415 self.sourcePath = sourcePath 415 self.sourcePath = sourcePath
416 self.sourceUrls = sourceUrls 416 self.sourceUrls = sourceUrls
417 self.sourceSha1 = sourceSha1 417 self.sourceSha1 = sourceSha1
418 self.deps = deps
418 for url in urls: 419 for url in urls:
419 if url.endswith('/') != self.path.endswith(os.sep): 420 if url.endswith('/') != self.path.endswith(os.sep):
420 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) 421 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url)
421 422
422 def __eq__(self, other): 423 def __eq__(self, other):
459 path = self.get_path(resolve) 460 path = self.get_path(resolve)
460 if path and (exists(path) or not resolve): 461 if path and (exists(path) or not resolve):
461 cp.append(path) 462 cp.append(path)
462 463
463 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): 464 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False):
464 if not includeLibs or not includeSelf: 465 """
466 Add the transitive set of dependencies for this library to the 'deps' list.
467 """
468 if not includeLibs:
465 return deps 469 return deps
466 deps.append(self) 470 childDeps = list(self.deps)
471 if self in deps:
472 return deps
473 for name in childDeps:
474 assert name != self.name
475 dep = library(name)
476 if not dep in deps:
477 dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors)
478 if not self in deps and includeSelf:
479 deps.append(self)
467 return deps 480 return deps
468 481
469 class HgConfig: 482 class HgConfig:
470 """ 483 """
471 Encapsulates access to Mercurial (hg) 484 Encapsulates access to Mercurial (hg)
618 urls = pop_list(attrs, 'urls') 631 urls = pop_list(attrs, 'urls')
619 sha1 = attrs.pop('sha1', None) 632 sha1 = attrs.pop('sha1', None)
620 sourcePath = attrs.pop('sourcePath', None) 633 sourcePath = attrs.pop('sourcePath', None)
621 sourceUrls = pop_list(attrs, 'sourceUrls') 634 sourceUrls = pop_list(attrs, 'sourceUrls')
622 sourceSha1 = attrs.pop('sourceSha1', None) 635 sourceSha1 = attrs.pop('sourceSha1', None)
623 l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1) 636 deps = pop_list(attrs, 'dependencies')
637 l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps)
624 l.__dict__.update(attrs) 638 l.__dict__.update(attrs)
625 self.libs.append(l) 639 self.libs.append(l)
626 640
627 for name, attrs in distsMap.iteritems(): 641 for name, attrs in distsMap.iteritems():
628 path = attrs.pop('path') 642 path = attrs.pop('path')
2857 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)}) 2871 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)})
2858 2872
2859 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project 2873 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project
2860 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) 2874 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'})
2861 2875
2862 containers = set() 2876 containerDeps = set()
2877 libraryDeps = set()
2878 projectDeps = set()
2879
2863 for dep in p.all_deps([], True): 2880 for dep in p.all_deps([], True):
2864 if dep == p: 2881 if dep == p:
2865 continue 2882 continue
2866
2867 if dep.isLibrary(): 2883 if dep.isLibrary():
2868 if hasattr(dep, 'eclipse.container') and getattr(dep, 'eclipse.container') not in containers: 2884 if hasattr(dep, 'eclipse.container'):
2869 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) 2885 container = getattr(dep, 'eclipse.container')
2870 containers.add(getattr(dep, 'eclipse.container')) 2886 containerDeps.add(container)
2871 elif hasattr(dep, 'eclipse.project'): 2887 libraryDeps -= set(dep.all_deps([], True))
2872 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')})
2873 else: 2888 else:
2874 path = dep.path 2889 libraryDeps.add(dep)
2875 dep.get_path(resolve=True)
2876 if not path or (not exists(path) and not dep.mustExist):
2877 continue
2878
2879 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
2880 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
2881 # safest to simply use absolute paths.
2882 path = _make_absolute(path, p.suite.dir)
2883
2884 attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path}
2885
2886 sourcePath = dep.get_source_path(resolve=True)
2887 if sourcePath is not None:
2888 attributes['sourcepath'] = sourcePath
2889 out.element('classpathentry', attributes)
2890 libFiles.append(path)
2891 else: 2890 else:
2892 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) 2891 projectDeps.add(dep)
2892
2893 for dep in containerDeps:
2894 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep})
2895
2896 for dep in libraryDeps:
2897 path = dep.path
2898 dep.get_path(resolve=True)
2899 if not path or (not exists(path) and not dep.mustExist):
2900 continue
2901
2902 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
2903 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
2904 # safest to simply use absolute paths.
2905 path = _make_absolute(path, p.suite.dir)
2906
2907 attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path}
2908
2909 sourcePath = dep.get_source_path(resolve=True)
2910 if sourcePath is not None:
2911 attributes['sourcepath'] = sourcePath
2912 out.element('classpathentry', attributes)
2913 libFiles.append(path)
2914
2915 for dep in projectDeps:
2916 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name})
2893 2917
2894 out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) 2918 out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')})
2895 out.close('classpath') 2919 out.close('classpath')
2896 classpathFile = join(p.dir, '.classpath') 2920 classpathFile = join(p.dir, '.classpath')
2897 update_file(classpathFile, out.xml(indent='\t', newl='\n')) 2921 update_file(classpathFile, out.xml(indent='\t', newl='\n'))