comparison mxtool/mx.py @ 15662:50fbda571d99

mx: added jrelibrary dependency type mx: once mx/projects is loaded, projects and libraries that depend on non-existent JRE library or have a javaCompliance higher than any available JDK are ignored
author Doug Simon <doug.simon@oracle.com>
date Thu, 15 May 2014 15:31:22 +0200
parents 83c69954bbaa
children 5ec52f033e58 807090ddbbf2
comparison
equal deleted inserted replaced
15658:304e1c30adaf 15662:50fbda571d99
47 from argparse import ArgumentParser, REMAINDER 47 from argparse import ArgumentParser, REMAINDER
48 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile 48 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile
49 49
50 _projects = dict() 50 _projects = dict()
51 _libs = dict() 51 _libs = dict()
52 _jreLibs = dict()
52 _dists = dict() 53 _dists = dict()
53 _suites = dict() 54 _suites = dict()
54 _annotationProcessors = None 55 _annotationProcessors = None
55 _primary_suite_path = None 56 _primary_suite_path = None
56 _primary_suite = None 57 _primary_suite = None
121 if srcArc.zf and libSourcePath: 122 if srcArc.zf and libSourcePath:
122 with zipfile.ZipFile(libSourcePath, 'r') as lp: 123 with zipfile.ZipFile(libSourcePath, 'r') as lp:
123 for arcname in lp.namelist(): 124 for arcname in lp.namelist():
124 overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname) 125 overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname)
125 srcArc.zf.writestr(arcname, lp.read(arcname)) 126 srcArc.zf.writestr(arcname, lp.read(arcname))
126 else: 127 elif dep.isProject():
127 p = dep 128 p = dep
128 129
129 isCoveredByDependecy = False 130 isCoveredByDependecy = False
130 for d in self.distDependencies: 131 for d in self.distDependencies:
131 if p in _dists[d].sorted_deps(): 132 if p in _dists[d].sorted_deps():
136 if isCoveredByDependecy: 137 if isCoveredByDependecy:
137 continue 138 continue
138 139
139 # skip a Java project if its Java compliance level is "higher" than the configured JDK 140 # skip a Java project if its Java compliance level is "higher" than the configured JDK
140 jdk = java(p.javaCompliance) 141 jdk = java(p.javaCompliance)
141 if not jdk: 142 assert jdk
142 log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, self.path))
143 continue
144 143
145 logv('[' + self.path + ': adding project ' + p.name + ']') 144 logv('[' + self.path + ': adding project ' + p.name + ']')
146 outputDir = p.output_dir() 145 outputDir = p.output_dir()
147 for root, _, files in os.walk(outputDir): 146 for root, _, files in os.walk(outputDir):
148 relpath = root[len(outputDir) + 1:] 147 relpath = root[len(outputDir) + 1:]
205 return hash(self.name) 204 return hash(self.name)
206 205
207 def isLibrary(self): 206 def isLibrary(self):
208 return isinstance(self, Library) 207 return isinstance(self, Library)
209 208
209 def isJreLibrary(self):
210 return isinstance(self, JreLibrary)
211
210 def isProject(self): 212 def isProject(self):
211 return isinstance(self, Project) 213 return isinstance(self, Project)
212 214
213 class Project(Dependency): 215 class Project(Dependency):
214 def __init__(self, suite, name, srcDirs, deps, javaCompliance, workingSets, d): 216 def __init__(self, suite, name, srcDirs, deps, javaCompliance, workingSets, d):
233 os.mkdir(d) 235 os.mkdir(d)
234 for s in self.source_dirs(): 236 for s in self.source_dirs():
235 if not exists(s): 237 if not exists(s):
236 os.mkdir(s) 238 os.mkdir(s)
237 239
238 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): 240 def all_deps(self, deps, includeLibs, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=False):
239 """ 241 """
240 Add the transitive set of dependencies for this project, including 242 Add the transitive set of dependencies for this project, including
241 libraries if 'includeLibs' is true, to the 'deps' list. 243 libraries if 'includeLibs' is true, to the 'deps' list.
242 """ 244 """
243 childDeps = list(self.deps) 245 childDeps = list(self.deps)
246 if self in deps: 248 if self in deps:
247 return deps 249 return deps
248 for name in childDeps: 250 for name in childDeps:
249 assert name != self.name 251 assert name != self.name
250 dep = dependency(name) 252 dep = dependency(name)
251 if not dep in deps and (includeLibs or not dep.isLibrary()): 253 if not dep in deps and (dep.isProject or (dep.isLibrary() and includeLibs) or (dep.isJreLibrary() and includeJreLibs)):
252 dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) 254 dep.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors)
253 if not self in deps and includeSelf: 255 if not self in deps and includeSelf:
254 deps.append(self) 256 deps.append(self)
255 return deps 257 return deps
256 258
257 def _compute_max_dep_distances(self, name, distances, dist): 259 def _compute_max_dep_distances(self, name, distances, dist):
510 abort("SHA1 does not match for " + name + ". Broken download? SHA1 not updated in projects file?") 512 abort("SHA1 does not match for " + name + ". Broken download? SHA1 not updated in projects file?")
511 _writeSha1Cached() 513 _writeSha1Cached()
512 514
513 return path 515 return path
514 516
515 class Library(Dependency): 517 class BaseLibrary(Dependency):
516 def __init__(self, suite, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps): 518 def __init__(self, suite, name, optional):
517 Dependency.__init__(self, suite, name) 519 Dependency.__init__(self, suite, name)
520 self.optional = optional
521
522 def __ne__(self, other):
523 result = self.__eq__(other)
524 if result is NotImplemented:
525 return result
526 return not result
527
528 """
529 A library that will be provided by the JDK but may be absent.
530 Any project or normal library that depends on a missing library
531 will be removed from the global project and library dictionaries
532 (i.e., _projects and _libs).
533
534 This mechanism exists primarily to be able to support code
535 that may use functionality in one JDK (e.g., Oracle JDK)
536 that is not present in another JDK (e.g., OpenJDK). A
537 motivating example is the Java Flight Recorder library
538 found in the Oracle JDK.
539 """
540 class JreLibrary(BaseLibrary):
541 def __init__(self, suite, name, jar, optional):
542 BaseLibrary.__init__(self, suite, name, optional)
543 self.jar = jar
544
545 def __eq__(self, other):
546 if isinstance(other, JreLibrary):
547 return self.jar == other.jar
548 else:
549 return NotImplemented
550
551 def is_present_in_jdk(self, jdk):
552 for e in jdk.bootclasspath().split(os.pathsep):
553 if basename(e) == self.jar:
554 return True
555 for d in jdk.extdirs().split(os.pathsep):
556 if len(d) and self.jar in os.listdir(d):
557 return True
558 for d in jdk.endorseddirs().split(os.pathsep):
559 if len(d) and self.jar in os.listdir(d):
560 return True
561 return False
562
563 def all_deps(self, deps, includeLibs, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=False):
564 """
565 Add the transitive set of dependencies for this JRE library to the 'deps' list.
566 """
567 if includeJreLibs and includeSelf and not self in deps:
568 deps.append(self)
569 return deps
570
571 class Library(BaseLibrary):
572 def __init__(self, suite, name, path, optional, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps):
573 BaseLibrary.__init__(self, suite, name, optional)
518 self.path = path.replace('/', os.sep) 574 self.path = path.replace('/', os.sep)
519 self.urls = urls 575 self.urls = urls
520 self.sha1 = sha1 576 self.sha1 = sha1
521 self.mustExist = mustExist
522 self.sourcePath = sourcePath 577 self.sourcePath = sourcePath
523 self.sourceUrls = sourceUrls 578 self.sourceUrls = sourceUrls
524 self.sourceSha1 = sourceSha1 579 self.sourceSha1 = sourceSha1
525 self.deps = deps 580 self.deps = deps
581 abspath = _make_absolute(self.path, self.suite.dir)
582 if not optional and not exists(abspath):
583 if not len(urls):
584 abort('Non-optional library {} must either exist at {} or specify one or more URLs from which it can be retrieved'.format(name, abspath))
526 for url in urls: 585 for url in urls:
527 if url.endswith('/') != self.path.endswith(os.sep): 586 if url.endswith('/') != self.path.endswith(os.sep):
528 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) 587 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url)
529 588
530 def __eq__(self, other): 589 def __eq__(self, other):
534 else: 593 else:
535 return self.urls == other.urls 594 return self.urls == other.urls
536 else: 595 else:
537 return NotImplemented 596 return NotImplemented
538 597
539
540 def __ne__(self, other):
541 result = self.__eq__(other)
542 if result is NotImplemented:
543 return result
544 return not result
545
546
547 def get_path(self, resolve): 598 def get_path(self, resolve):
548 path = _make_absolute(self.path, self.suite.dir) 599 path = _make_absolute(self.path, self.suite.dir)
549 sha1path = path + '.sha1' 600 sha1path = path + '.sha1'
550 601
551 includedInJDK = getattr(self, 'includedInJDK', None) 602 includedInJDK = getattr(self, 'includedInJDK', None)
552 if includedInJDK and java().javaCompliance >= JavaCompliance(includedInJDK): 603 if includedInJDK and java().javaCompliance >= JavaCompliance(includedInJDK):
553 return None 604 return None
554 605
555 return _download_file_with_sha1(self.name, path, self.urls, self.sha1, sha1path, resolve, self.mustExist) 606 return _download_file_with_sha1(self.name, path, self.urls, self.sha1, sha1path, resolve, self.optional)
556
557 607
558 def get_source_path(self, resolve): 608 def get_source_path(self, resolve):
559 if self.sourcePath is None: 609 if self.sourcePath is None:
560 return None 610 return None
561 path = _make_absolute(self.sourcePath, self.suite.dir) 611 path = _make_absolute(self.sourcePath, self.suite.dir)
566 def append_to_classpath(self, cp, resolve): 616 def append_to_classpath(self, cp, resolve):
567 path = self.get_path(resolve) 617 path = self.get_path(resolve)
568 if path and (exists(path) or not resolve): 618 if path and (exists(path) or not resolve):
569 cp.append(path) 619 cp.append(path)
570 620
571 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): 621 def all_deps(self, deps, includeLibs, includeSelf=True, includeJreLibs=False, includeAnnotationProcessors=False):
572 """ 622 """
573 Add the transitive set of dependencies for this library to the 'deps' list. 623 Add the transitive set of dependencies for this library to the 'deps' list.
574 """ 624 """
575 if not includeLibs: 625 if not includeLibs:
576 return deps 626 return deps
579 return deps 629 return deps
580 for name in childDeps: 630 for name in childDeps:
581 assert name != self.name 631 assert name != self.name
582 dep = library(name) 632 dep = library(name)
583 if not dep in deps: 633 if not dep in deps:
584 dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) 634 dep.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors)
585 if not self in deps and includeSelf: 635 if not self in deps and includeSelf:
586 deps.append(self) 636 deps.append(self)
587 return deps 637 return deps
588 638
589 class HgConfig: 639 class HgConfig:
635 def __init__(self, mxDir, primary, load=True): 685 def __init__(self, mxDir, primary, load=True):
636 self.dir = dirname(mxDir) 686 self.dir = dirname(mxDir)
637 self.mxDir = mxDir 687 self.mxDir = mxDir
638 self.projects = [] 688 self.projects = []
639 self.libs = [] 689 self.libs = []
690 self.jreLibs = []
640 self.dists = [] 691 self.dists = []
641 self.commands = None 692 self.commands = None
642 self.primary = primary 693 self.primary = primary
643 self.requiredMxVersion = None 694 self.requiredMxVersion = None
644 self.name = _suitename(mxDir) # validated in _load_projects 695 self.name = _suitename(mxDir) # validated in _load_projects
652 def __str__(self): 703 def __str__(self):
653 return self.name 704 return self.name
654 705
655 def _load_projects(self): 706 def _load_projects(self):
656 libsMap = dict() 707 libsMap = dict()
708 jreLibsMap = dict()
657 projsMap = dict() 709 projsMap = dict()
658 distsMap = dict() 710 distsMap = dict()
659 projectsFile = join(self.mxDir, 'projects') 711 projectsFile = join(self.mxDir, 'projects')
660 if not exists(projectsFile): 712 if not exists(projectsFile):
661 return 713 return
701 kind, name, attr = parts 753 kind, name, attr = parts
702 if kind == 'project': 754 if kind == 'project':
703 m = projsMap 755 m = projsMap
704 elif kind == 'library': 756 elif kind == 'library':
705 m = libsMap 757 m = libsMap
758 elif kind == 'jrelibrary':
759 m = jreLibsMap
706 elif kind == 'distribution': 760 elif kind == 'distribution':
707 m = distsMap 761 m = distsMap
708 else: 762 else:
709 error('Property name does not start with "project@", "library@" or "distribution@": ' + key) 763 error('Property name does not start with "project@", "library@" or "distribution@": ' + key)
710 764
741 if len(ap) > 0: 795 if len(ap) > 0:
742 p._declaredAnnotationProcessors = ap 796 p._declaredAnnotationProcessors = ap
743 p.__dict__.update(attrs) 797 p.__dict__.update(attrs)
744 self.projects.append(p) 798 self.projects.append(p)
745 799
800 for name, attrs in jreLibsMap.iteritems():
801 jar = attrs.pop('jar')
802 # JRE libraries are optional by default
803 optional = attrs.pop('optional', 'true') != 'false'
804 l = JreLibrary(self, name, jar, optional)
805 self.jreLibs.append(l)
806
746 for name, attrs in libsMap.iteritems(): 807 for name, attrs in libsMap.iteritems():
747 path = attrs.pop('path') 808 path = attrs.pop('path')
748 mustExist = attrs.pop('optional', 'false') != 'true'
749 urls = pop_list(attrs, 'urls') 809 urls = pop_list(attrs, 'urls')
750 sha1 = attrs.pop('sha1', None) 810 sha1 = attrs.pop('sha1', None)
751 sourcePath = attrs.pop('sourcePath', None) 811 sourcePath = attrs.pop('sourcePath', None)
752 sourceUrls = pop_list(attrs, 'sourceUrls') 812 sourceUrls = pop_list(attrs, 'sourceUrls')
753 sourceSha1 = attrs.pop('sourceSha1', None) 813 sourceSha1 = attrs.pop('sourceSha1', None)
754 deps = pop_list(attrs, 'dependencies') 814 deps = pop_list(attrs, 'dependencies')
755 l = Library(self, name, path, mustExist, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps) 815 # Add support optional libraries once we have a good use case
816 optional = False
817 l = Library(self, name, path, optional, urls, sha1, sourcePath, sourceUrls, sourceSha1, deps)
756 l.__dict__.update(attrs) 818 l.__dict__.update(attrs)
757 self.libs.append(l) 819 self.libs.append(l)
758 820
759 for name, attrs in distsMap.iteritems(): 821 for name, attrs in distsMap.iteritems():
760 path = attrs.pop('path') 822 path = attrs.pop('path')
840 existing = _libs.get(l.name) 902 existing = _libs.get(l.name)
841 # Check that suites that define same library are consistent 903 # Check that suites that define same library are consistent
842 if existing is not None and existing != l: 904 if existing is not None and existing != l:
843 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir) 905 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir)
844 _libs[l.name] = l 906 _libs[l.name] = l
907 for l in self.jreLibs:
908 existing = _jreLibs.get(l.name)
909 # Check that suites that define same library are consistent
910 if existing is not None and existing != l:
911 abort('inconsistent JRE library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir)
912 _jreLibs[l.name] = l
845 for d in self.dists: 913 for d in self.dists:
846 existing = _dists.get(d.name) 914 existing = _dists.get(d.name)
847 if existing is not None: 915 if existing is not None:
848 # allow redefinition, so use path from existing 916 # allow redefinition, so use path from existing
849 # abort('cannot redefine distribution ' + d.name) 917 # abort('cannot redefine distribution ' + d.name)
850 warn('distribution ' + d.name + ' redefined') 918 warn('distribution ' + d.name + ' redefined')
851 d.path = existing.path 919 d.path = existing.path
852 _dists[d.name] = d 920 _dists[d.name] = d
921
922 # Remove projects and libraries that (recursively) depend on an optional library
923 # whose artifact does not exist or on a JRE library that is not present in the
924 # JDK for a project. Also remove projects whose Java compliance requirement
925 # cannot be satisfied by the configured JDKs.
926 #
927 # Removed projects and libraries are also removed from
928 # distributions in they are listed as dependencies.
929 for d in sorted_deps(includeLibs=True):
930 if d.isLibrary():
931 if d.optional:
932 try:
933 d.optional = False
934 path = d.get_path(resolve=True)
935 except SystemExit:
936 path = None
937 finally:
938 d.optional = True
939 if not path:
940 logv('[omitting optional library {} as {} does not exist]'.format(d, d.path))
941 del _libs[d.name]
942 self.libs.remove(d)
943 elif d.isProject():
944 if java(d.javaCompliance) is None:
945 logv('[omitting project {} as Java compliance {} cannot be satisfied by configured JDKs]'.format(d, d.javaCompliance))
946 del _projects[d.name]
947 self.projects.remove(d)
948 else:
949 for name in list(d.deps):
950 jreLib = _jreLibs.get(name)
951 if jreLib:
952 if not jreLib.is_present_in_jdk(java(d.javaCompliance)):
953 if jreLib.optional:
954 logv('[omitting project {} as dependency {} is missing]'.format(d, name))
955 del _projects[d.name]
956 self.projects.remove(d)
957 else:
958 abort('JRE library {} required by {} not found'.format(jreLib, d))
959 elif not dependency(name, fatalIfMissing=False):
960 logv('[omitting project {} as dependency {} is missing]'.format(d, name))
961 del _projects[d.name]
962 self.projects.remove(d)
963 for dist in _dists.values():
964 for name in list(dist.deps):
965 if not dependency(name, fatalIfMissing=False):
966 logv('[omitting {} from distribution {}]'.format(name, dist))
967 dist.deps.remove(name)
968
853 if hasattr(self, 'mx_post_parse_cmd_line'): 969 if hasattr(self, 'mx_post_parse_cmd_line'):
854 self.mx_post_parse_cmd_line(opts) 970 self.mx_post_parse_cmd_line(opts)
855 971
856 class XMLElement(xml.dom.minidom.Element): 972 class XMLElement(xml.dom.minidom.Element):
857 def writexml(self, writer, indent="", addindent="", newl=""): 973 def writexml(self, writer, indent="", addindent="", newl=""):
1029 not exist for 'name' and 'fatalIfMissing' is true. 1145 not exist for 'name' and 'fatalIfMissing' is true.
1030 """ 1146 """
1031 d = _projects.get(name) 1147 d = _projects.get(name)
1032 if d is None: 1148 if d is None:
1033 d = _libs.get(name) 1149 d = _libs.get(name)
1150 if d is None:
1151 d = _jreLibs.get(name)
1034 if d is None and fatalIfMissing: 1152 if d is None and fatalIfMissing:
1035 if name in _opts.ignored_projects: 1153 if name in _opts.ignored_projects:
1036 abort('project named ' + name + ' is ignored') 1154 abort('project named ' + name + ' is ignored')
1037 abort('project or library named ' + name + ' not found') 1155 abort('project or library named ' + name + ' not found')
1038 return d 1156 return d
1544 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) 1662 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac'))
1545 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) 1663 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap'))
1546 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) 1664 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc'))
1547 self.toolsjar = join(self.jdk, 'lib', 'tools.jar') 1665 self.toolsjar = join(self.jdk, 'lib', 'tools.jar')
1548 self._bootclasspath = None 1666 self._bootclasspath = None
1667 self._extdirs = None
1668 self._endorseddirs = None
1549 1669
1550 if not exists(self.java): 1670 if not exists(self.java):
1551 abort('Java launcher does not exist: ' + self.java) 1671 abort('Java launcher does not exist: ' + self.java)
1552 1672
1553 def delAtAndSplit(s): 1673 def delAtAndSplit(s):
1712 """ 1832 """
1713 1833
1714 if _opts.killwithsigquit: 1834 if _opts.killwithsigquit:
1715 _send_sigquit() 1835 _send_sigquit()
1716 1836
1717 # import traceback
1718 # traceback.print_stack()
1719 for p, args in _currentSubprocesses: 1837 for p, args in _currentSubprocesses:
1720 try: 1838 try:
1721 if get_os() == 'windows': 1839 if get_os() == 'windows':
1722 p.terminate() 1840 p.terminate()
1723 else: 1841 else:
1724 _kill_process_group(p.pid, signal.SIGKILL) 1842 _kill_process_group(p.pid, signal.SIGKILL)
1725 except BaseException as e: 1843 except BaseException as e:
1726 log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e)) 1844 log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e))
1727 1845
1846 if _opts and _opts.verbose:
1847 import traceback
1848 traceback.print_stack()
1728 raise SystemExit(codeOrMessage) 1849 raise SystemExit(codeOrMessage)
1729 1850
1730 def download(path, urls, verbose=False): 1851 def download(path, urls, verbose=False):
1731 """ 1852 """
1732 Attempts to downloads content for each URL in a list, stopping after the first successful download. 1853 Attempts to downloads content for each URL in a list, stopping after the first successful download.
2028 continue 2149 continue
2029 2150
2030 # skip building this Java project if its Java compliance level is "higher" than the configured JDK 2151 # skip building this Java project if its Java compliance level is "higher" than the configured JDK
2031 requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None 2152 requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None
2032 jdk = java(requiredCompliance) 2153 jdk = java(requiredCompliance)
2033 if not jdk: 2154 assert jdk
2034 log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, requiredCompliance))
2035 continue
2036 2155
2037 outputDir = prepareOutputDirs(p, args.clean) 2156 outputDir = prepareOutputDirs(p, args.clean)
2038 2157
2039 sourceDirs = p.source_dirs() 2158 sourceDirs = p.source_dirs()
2040 buildReason = 'forced build' if args.force else None 2159 buildReason = 'forced build' if args.force else None
2626 if not exists(csConfig): 2745 if not exists(csConfig):
2627 abort('ERROR: Checkstyle configuration for project {} is missing: {}'.format(p.name, csConfig)) 2746 abort('ERROR: Checkstyle configuration for project {} is missing: {}'.format(p.name, csConfig))
2628 2747
2629 # skip checking this Java project if its Java compliance level is "higher" than the configured JDK 2748 # skip checking this Java project if its Java compliance level is "higher" than the configured JDK
2630 jdk = java(p.javaCompliance) 2749 jdk = java(p.javaCompliance)
2631 if not jdk: 2750 assert jdk
2632 log('Excluding {0} from checking (Java compliance level {1} required)'.format(p.name, p.javaCompliance))
2633 continue
2634 2751
2635 for sourceDir in sourceDirs: 2752 for sourceDir in sourceDirs:
2636 javafilelist = [] 2753 javafilelist = []
2637 for root, _, files in os.walk(sourceDir): 2754 for root, _, files in os.walk(sourceDir):
2638 javafilelist += [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] 2755 javafilelist += [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java']
2872 memento = XMLDoc().element('classpathContainer', {'path' : getattr(dep, 'eclipse.container')}).xml(standalone='no') 2989 memento = XMLDoc().element('classpathContainer', {'path' : getattr(dep, 'eclipse.container')}).xml(standalone='no')
2873 slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'}) 2990 slm.element('classpathContainer', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.classpathContainer'})
2874 elif dep.get_source_path(resolve=True): 2991 elif dep.get_source_path(resolve=True):
2875 memento = XMLDoc().element('archive', {'detectRoot' : 'true', 'path' : dep.get_source_path(resolve=True)}).xml(standalone='no') 2992 memento = XMLDoc().element('archive', {'detectRoot' : 'true', 'path' : dep.get_source_path(resolve=True)}).xml(standalone='no')
2876 slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.debug.core.containerType.externalArchive'}) 2993 slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.debug.core.containerType.externalArchive'})
2877 else: 2994 elif dep.isProject():
2878 memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no') 2995 memento = XMLDoc().element('javaProject', {'name' : dep.name}).xml(standalone='no')
2879 slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'}) 2996 slm.element('container', {'memento' : memento, 'typeId':'org.eclipse.jdt.launching.sourceContainer.javaProject'})
2880 if javaCompliance is None or dep.javaCompliance < javaCompliance: 2997 if javaCompliance is None or dep.javaCompliance < javaCompliance:
2881 javaCompliance = dep.javaCompliance 2998 javaCompliance = dep.javaCompliance
2882 2999
3039 3156
3040 for p in suite.projects: 3157 for p in suite.projects:
3041 if p.native: 3158 if p.native:
3042 continue 3159 continue
3043 3160
3044 if not java(p.javaCompliance): 3161 assert java(p.javaCompliance)
3045 log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance))
3046 continue
3047 3162
3048 if not exists(p.dir): 3163 if not exists(p.dir):
3049 os.makedirs(p.dir) 3164 os.makedirs(p.dir)
3050 3165
3051 out = XMLDoc() 3166 out = XMLDoc()
3082 container = getattr(dep, 'eclipse.container') 3197 container = getattr(dep, 'eclipse.container')
3083 containerDeps.add(container) 3198 containerDeps.add(container)
3084 libraryDeps -= set(dep.all_deps([], True)) 3199 libraryDeps -= set(dep.all_deps([], True))
3085 else: 3200 else:
3086 libraryDeps.add(dep) 3201 libraryDeps.add(dep)
3087 else: 3202 elif dep.isProject():
3088 projectDeps.add(dep) 3203 projectDeps.add(dep)
3089 3204
3090 for dep in containerDeps: 3205 for dep in containerDeps:
3091 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) 3206 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep})
3092 3207
3093 for dep in libraryDeps: 3208 for dep in libraryDeps:
3094 path = dep.path 3209 path = dep.path
3095 dep.get_path(resolve=True) 3210 dep.get_path(resolve=True)
3096 if not path or (not exists(path) and not dep.mustExist):
3097 continue
3098 3211
3099 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse 3212 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
3100 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's 3213 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
3101 # safest to simply use absolute paths. 3214 # safest to simply use absolute paths.
3102 path = _make_absolute(path, p.suite.dir) 3215 path = _make_absolute(path, p.suite.dir)
3250 out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) 3363 out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'})
3251 for ap in p.annotation_processors(): 3364 for ap in p.annotation_processors():
3252 for dep in dependency(ap).all_deps([], True): 3365 for dep in dependency(ap).all_deps([], True):
3253 if dep.isLibrary(): 3366 if dep.isLibrary():
3254 if not hasattr(dep, 'eclipse.container') and not hasattr(dep, 'eclipse.project'): 3367 if not hasattr(dep, 'eclipse.container') and not hasattr(dep, 'eclipse.project'):
3255 if dep.mustExist: 3368 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse
3256 path = dep.get_path(resolve=True) 3369 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's
3257 if path: 3370 # safest to simply use absolute paths.
3258 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse 3371 path = _make_absolute(dep.get_path(resolve=True), p.suite.dir)
3259 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's 3372 out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'})
3260 # safest to simply use absolute paths. 3373 files.append(path)
3261 path = _make_absolute(path, p.suite.dir) 3374 elif dep.isProject():
3262 out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'})
3263 files.append(path)
3264 else:
3265 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) 3375 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'})
3266 out.close('factorypath') 3376 out.close('factorypath')
3267 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) 3377 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n'))
3268 files.append(join(p.dir, '.factorypath')) 3378 files.append(join(p.dir, '.factorypath'))
3269 3379
3562 3672
3563 if not exists(join(p.dir, 'nbproject')): 3673 if not exists(join(p.dir, 'nbproject')):
3564 os.makedirs(join(p.dir, 'nbproject')) 3674 os.makedirs(join(p.dir, 'nbproject'))
3565 3675
3566 jdk = java(p.javaCompliance) 3676 jdk = java(p.javaCompliance)
3567 3677 assert jdk
3568 if not jdk:
3569 log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance))
3570 continue
3571 3678
3572 jdks.add(jdk) 3679 jdks.add(jdk)
3573 3680
3574 out = XMLDoc() 3681 out = XMLDoc()
3575 out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'}) 3682 out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'})
3606 firstDep = True 3713 firstDep = True
3607 for dep in p.all_deps([], True): 3714 for dep in p.all_deps([], True):
3608 if dep == p: 3715 if dep == p:
3609 continue 3716 continue
3610 3717
3611 if not dep.isLibrary(): 3718 if dep.isProject():
3612 n = dep.name.replace('.', '_') 3719 n = dep.name.replace('.', '_')
3613 if firstDep: 3720 if firstDep:
3614 out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'}) 3721 out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'})
3615 firstDep = False 3722 firstDep = False
3616 3723
3741 for dep in deps: 3848 for dep in deps:
3742 if dep == p: 3849 if dep == p:
3743 continue 3850 continue
3744 3851
3745 if dep.isLibrary(): 3852 if dep.isLibrary():
3746 if not dep.mustExist:
3747 continue
3748 path = dep.get_path(resolve=True) 3853 path = dep.get_path(resolve=True)
3749 if path: 3854 if path:
3750 if os.sep == '\\': 3855 if os.sep == '\\':
3751 path = path.replace('\\', '\\\\') 3856 path = path.replace('\\', '\\\\')
3752 ref = 'file.reference.' + dep.name + '-bin' 3857 ref = 'file.reference.' + dep.name + '-bin'
3753 print >> out, ref + '=' + path 3858 print >> out, ref + '=' + path
3754 libFiles.append(path) 3859 libFiles.append(path)
3755 3860
3756 else: 3861 elif dep.isProject():
3757 n = dep.name.replace('.', '_') 3862 n = dep.name.replace('.', '_')
3758 relDepPath = os.path.relpath(dep.dir, p.dir).replace(os.sep, '/') 3863 relDepPath = os.path.relpath(dep.dir, p.dir).replace(os.sep, '/')
3759 ref = 'reference.' + n + '.jar' 3864 ref = 'reference.' + n + '.jar'
3760 print >> out, 'project.' + n + '=' + relDepPath 3865 print >> out, 'project.' + n + '=' + relDepPath
3761 print >> out, ref + '=${project.' + n + '}/dist/' + dep.name + '.jar' 3866 print >> out, ref + '=${project.' + n + '}/dist/' + dep.name + '.jar'
3818 # create the modules (1 module = 1 Intellij project) 3923 # create the modules (1 module = 1 Intellij project)
3819 for p in suite.projects: 3924 for p in suite.projects:
3820 if p.native: 3925 if p.native:
3821 continue 3926 continue
3822 3927
3823 if not java(p.javaCompliance): 3928 assert java(p.javaCompliance)
3824 log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance))
3825 continue
3826 3929
3827 if not exists(p.dir): 3930 if not exists(p.dir):
3828 os.makedirs(p.dir) 3931 os.makedirs(p.dir)
3829 3932
3830 annotationProcessorProfileKey = tuple(p.annotation_processors()) 3933 annotationProcessorProfileKey = tuple(p.annotation_processors())
3867 for dep in deps: 3970 for dep in deps:
3868 if dep == p: 3971 if dep == p:
3869 continue 3972 continue
3870 3973
3871 if dep.isLibrary(): 3974 if dep.isLibrary():
3872 if dep.mustExist: 3975 libraries.add(dep)
3873 libraries.add(dep) 3976 moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'})
3874 moduleXml.element('orderEntry', attributes={'type': 'library', 'name': dep.name, 'level': 'project'}) 3977 elif dep.isProject():
3875 else:
3876 moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': dep.name}) 3978 moduleXml.element('orderEntry', attributes={'type': 'module', 'module-name': dep.name})
3877 3979
3878 moduleXml.close('component') 3980 moduleXml.close('component')
3879 moduleXml.close('module') 3981 moduleXml.close('module')
3880 moduleFile = join(p.dir, p.name + '.iml') 3982 moduleFile = join(p.dir, p.name + '.iml')
3942 for apName in processors: 4044 for apName in processors:
3943 pDep = dependency(apName) 4045 pDep = dependency(apName)
3944 for entry in pDep.all_deps([], True): 4046 for entry in pDep.all_deps([], True):
3945 if entry.isLibrary(): 4047 if entry.isLibrary():
3946 compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.path, suite.dir)}) 4048 compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.path, suite.dir)})
3947 else: 4049 elif entry.isProject():
3948 assert entry.isProject() 4050 assert entry.isProject()
3949 compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.output_dir(), suite.dir)}) 4051 compilerXml.element('entry', attributes={'name': '$PROJECT_DIR$/' + os.path.relpath(entry.output_dir(), suite.dir)})
3950 compilerXml.close('processorPath') 4052 compilerXml.close('processorPath')
3951 for module in modules: 4053 for module in modules:
3952 compilerXml.element('module', attributes={'name': module.name}) 4054 compilerXml.element('module', attributes={'name': module.name})