Mercurial > hg > graal-jvmci-8
comparison mxtool/mx.py @ 11756:78e6109ee411
mx refactoring for split-repo suites; should have no effect on existing repos
author | Mick Jordan <mick.jordan@oracle.com> |
---|---|
date | Mon, 23 Sep 2013 21:30:35 -0700 |
parents | e29743466d00 |
children | 8bcd76c3f23b |
comparison
equal
deleted
inserted
replaced
11755:bbcb72443066 | 11756:78e6109ee411 |
---|---|
37 containing one or more projects. It's not coincidental that this closely | 37 containing one or more projects. It's not coincidental that this closely |
38 matches the layout of one or more projects in a Mercurial repository. | 38 matches the layout of one or more projects in a Mercurial repository. |
39 The configuration information for a suite lives in an 'mx' sub-directory | 39 The configuration information for a suite lives in an 'mx' sub-directory |
40 at the top level of the suite. A suite is given a name by a 'suite=name' | 40 at the top level of the suite. A suite is given a name by a 'suite=name' |
41 property in the 'mx/projects' file (if omitted the name is suite directory). | 41 property in the 'mx/projects' file (if omitted the name is suite directory). |
42 An 'mx' subdirectory can be named as plain 'mx' or 'mxbasename', where | 42 An 'mx' subdirectory can be named as plain 'mx' or 'mx.name', where |
43 'basename' is the os.path.basename of the suite directory. | 43 'name' is typically the name as the suite name. |
44 The latter is useful to avoid clashes in IDE project names. | 44 The latter is useful to avoid clashes in IDE project names. |
45 | 45 |
46 When launched, mx treats the current working directory as a suite. | 46 When launched, mx treats the current working directory as a suite. |
47 This is the primary suite. All other suites are called included suites. | 47 This is the primary suite. All other suites are called included suites. |
48 | 48 |
156 _suites = dict() | 156 _suites = dict() |
157 _annotationProcessors = None | 157 _annotationProcessors = None |
158 _mainSuite = None | 158 _mainSuite = None |
159 _opts = None | 159 _opts = None |
160 _java = None | 160 _java = None |
161 _check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting | |
162 | |
161 | 163 |
162 """ | 164 """ |
163 A distribution is a jar or zip file containing the output from one or more Java projects. | 165 A distribution is a jar or zip file containing the output from one or more Java projects. |
164 """ | 166 """ |
165 class Distribution: | 167 class Distribution: |
514 projsMap = dict() | 516 projsMap = dict() |
515 distsMap = dict() | 517 distsMap = dict() |
516 projectsFile = join(mxDir, 'projects') | 518 projectsFile = join(mxDir, 'projects') |
517 if not exists(projectsFile): | 519 if not exists(projectsFile): |
518 return | 520 return |
521 | |
522 def _find_suite_key(): | |
523 for items in _suites.items(): | |
524 if items[1].dir == self.dir: | |
525 return items[0] | |
526 raise KeyError | |
527 | |
519 with open(projectsFile) as f: | 528 with open(projectsFile) as f: |
520 for line in f: | 529 for line in f: |
521 line = line.strip() | 530 line = line.strip() |
522 if len(line) != 0 and line[0] != '#': | 531 if len(line) != 0 and line[0] != '#': |
523 key, value = line.split('=', 1) | 532 key, value = line.split('=', 1) |
525 parts = key.split('@') | 534 parts = key.split('@') |
526 | 535 |
527 if len(parts) == 1: | 536 if len(parts) == 1: |
528 if parts[0] != 'suite': | 537 if parts[0] != 'suite': |
529 abort('Single part property must be "suite": ' + key) | 538 abort('Single part property must be "suite": ' + key) |
530 self.name = value | 539 if self.name != value: |
540 currentKey = _find_suite_key() | |
541 _suites.pop(currentKey) | |
542 self.name = value | |
543 _suites[value] = self | |
531 continue | 544 continue |
532 if len(parts) != 3: | 545 if len(parts) != 3: |
533 abort('Property name does not have 3 parts separated by "@": ' + key) | 546 abort('Property name does not have 3 parts separated by "@": ' + key) |
534 kind, name, attr = parts | 547 kind, name, attr = parts |
535 if kind == 'project': | 548 if kind == 'project': |
637 if len(line) != 0 and line[0] != '#': | 650 if len(line) != 0 and line[0] != '#': |
638 if not '=' in line: | 651 if not '=' in line: |
639 abort(e + ':' + str(lineNum) + ': line does not match pattern "key=value"') | 652 abort(e + ':' + str(lineNum) + ': line does not match pattern "key=value"') |
640 key, value = line.split('=', 1) | 653 key, value = line.split('=', 1) |
641 os.environ[key.strip()] = expandvars_in_property(value.strip()) | 654 os.environ[key.strip()] = expandvars_in_property(value.strip()) |
655 | |
642 def _post_init(self, opts): | 656 def _post_init(self, opts): |
643 self._load_projects(self.mxDir) | 657 self._load_projects(self.mxDir) |
658 # set the global data structures, checking for conflicts unless _global_structures is False | |
644 for p in self.projects: | 659 for p in self.projects: |
645 existing = _projects.get(p.name) | 660 existing = _projects.get(p.name) |
646 if existing is not None: | 661 if existing is not None and _check_global_structures: |
647 abort('cannot override project ' + p.name + ' in ' + p.dir + " with project of the same name in " + existing.dir) | 662 abort('cannot override project ' + p.name + ' in ' + p.dir + " with project of the same name in " + existing.dir) |
648 if not p.name in _opts.ignored_projects: | 663 if not p.name in _opts.ignored_projects: |
649 _projects[p.name] = p | 664 _projects[p.name] = p |
650 for l in self.libs: | 665 for l in self.libs: |
651 existing = _libs.get(l.name) | 666 existing = _libs.get(l.name) |
652 # Check that suites that define same library are consistent | 667 # Check that suites that define same library are consistent |
653 if existing is not None and existing != l: | 668 if existing is not None and existing != l and _check_global_structures: |
654 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir) | 669 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir) |
655 _libs[l.name] = l | 670 _libs[l.name] = l |
656 for d in self.dists: | 671 for d in self.dists: |
657 existing = _dists.get(d.name) | 672 existing = _dists.get(d.name) |
658 if existing is not None: | 673 if existing is not None and _check_global_structures: |
659 abort('cannot redefine distribution ' + d.name) | 674 # allow redefinition, so use path from existing |
675 # abort('cannot redefine distribution ' + d.name) | |
676 print('WARNING: distribution ' + d.name + ' redefined') | |
677 d.path = existing.path | |
660 _dists[d.name] = d | 678 _dists[d.name] = d |
661 if hasattr(self, 'mx_post_parse_cmd_line'): | 679 if hasattr(self, 'mx_post_parse_cmd_line'): |
662 self.mx_post_parse_cmd_line(opts) | 680 self.mx_post_parse_cmd_line(opts) |
663 | 681 |
664 class XMLElement(xml.dom.minidom.Element): | 682 class XMLElement(xml.dom.minidom.Element): |
749 return 'solaris' | 767 return 'solaris' |
750 elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): | 768 elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): |
751 return 'windows' | 769 return 'windows' |
752 else: | 770 else: |
753 abort('Unknown operating system ' + sys.platform) | 771 abort('Unknown operating system ' + sys.platform) |
754 | 772 |
755 def _loadSuite(d, primary=False): | 773 def _loadSuite(d, primary=False): |
756 """ | 774 """ |
757 Load a suite from the 'mx' or 'mxbbb' subdirectory of d, where 'bbb' is basename of d | 775 Load a suite from the 'mx' or 'mx.bbb' subdirectory of d, where 'bbb' is basename of d |
758 """ | 776 """ |
759 mxDefaultDir = join(d, 'mx') | 777 mxDefaultDir = join(d, 'mx') |
760 name = os.path.basename(d) | 778 name = os.path.basename(d) |
761 mxTaggedDir = mxDefaultDir + name | 779 mxTaggedDir = mxDefaultDir + '.' + name |
762 mxDir = None | 780 mxDir = None |
763 if exists(mxTaggedDir) and isdir(mxTaggedDir): | 781 if exists(mxTaggedDir) and isdir(mxTaggedDir): |
764 mxDir = mxTaggedDir | 782 mxDir = mxTaggedDir |
765 else: | 783 else: |
766 if exists(mxDefaultDir) and isdir(mxDefaultDir): | 784 if exists(mxDefaultDir) and isdir(mxDefaultDir): |
769 | 787 |
770 if mxDir is None: | 788 if mxDir is None: |
771 return None | 789 return None |
772 if len([s for s in _suites.itervalues() if s.dir == d]) == 0: | 790 if len([s for s in _suites.itervalues() if s.dir == d]) == 0: |
773 s = Suite(d, mxDir, primary) | 791 s = Suite(d, mxDir, primary) |
792 # N.B. this will be updated once the projects file has been read | |
774 _suites[name] = s | 793 _suites[name] = s |
775 return s | 794 return s |
776 | 795 |
777 def suites(): | 796 def suites(opt_limit_to_suite=False): |
778 """ | 797 """ |
779 Get the list of all loaded suites. | 798 Get the list of all loaded suites. |
780 """ | 799 """ |
781 return _suites.values() | 800 if opt_limit_to_suite and _opts.specific_suites: |
801 result = [] | |
802 for s in _suites: | |
803 if s.name in _opts.specific_suites: | |
804 result.append(s) | |
805 return result | |
806 else: | |
807 return _suites.values() | |
782 | 808 |
783 def suite(name, fatalIfMissing=True): | 809 def suite(name, fatalIfMissing=True): |
784 """ | 810 """ |
785 Get the suite for a given name. | 811 Get the suite for a given name. |
786 """ | 812 """ |
787 s = _suites.get(name) | 813 s = _suites.get(name) |
788 if s is None and fatalIfMissing: | 814 if s is None and fatalIfMissing: |
789 abort('suite named ' + name + ' not found') | 815 abort('suite named ' + name + ' not found') |
790 return s | 816 return s |
791 | 817 |
792 def projects(): | 818 def projects_from_names(projectNames): |
793 """ | 819 """ |
794 Get the list of all loaded projects. | 820 Get the list of projects corresponding to projectNames; all projects if None |
795 """ | 821 """ |
796 return _projects.values() | 822 if projectNames is None: |
823 return projects() | |
824 else: | |
825 return [project(name) for name in projectNames] | |
826 | |
827 def projects(opt_limit_to_suite=False): | |
828 """ | |
829 Get the list of all loaded projects limited by --suite option if opt_limit_to_suite == True | |
830 """ | |
831 | |
832 if opt_limit_to_suite: | |
833 return _projects_opt_limit_to_suites(_projects.values()) | |
834 else: | |
835 return _projects.values() | |
836 | |
837 def projects_opt_limit_to_suites(): | |
838 """ | |
839 Get the list of all loaded projects optionally limited by --suite option | |
840 """ | |
841 return projects(True) | |
842 | |
843 def _projects_opt_limit_to_suites(projects): | |
844 if not _opts.specific_suites: | |
845 return projects | |
846 else: | |
847 result = [] | |
848 for p in projects: | |
849 s = p.suite | |
850 if s.name in _opts.specific_suites: | |
851 result.append(p) | |
852 return result | |
797 | 853 |
798 def annotation_processors(): | 854 def annotation_processors(): |
799 """ | 855 """ |
800 Get the list of all loaded projects that define an annotation processor. | 856 Get the list of all loaded projects that define an annotation processor. |
801 """ | 857 """ |
912 """ | 968 """ |
913 Gets projects and libraries sorted such that dependencies | 969 Gets projects and libraries sorted such that dependencies |
914 are before the projects that depend on them. Unless 'includeLibs' is | 970 are before the projects that depend on them. Unless 'includeLibs' is |
915 true, libraries are omitted from the result. | 971 true, libraries are omitted from the result. |
916 """ | 972 """ |
973 projects = projects_from_names(projectNames) | |
974 | |
975 return sorted_project_deps(projects, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) | |
976 | |
977 def sorted_project_deps(projects, includeLibs=False, includeAnnotationProcessors=False): | |
917 deps = [] | 978 deps = [] |
918 if projectNames is None: | |
919 projects = opt_limit_to_suite(_projects.values()) | |
920 else: | |
921 projects = [project(name) for name in projectNames] | |
922 | |
923 for p in projects: | 979 for p in projects: |
924 p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) | 980 p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) |
925 return deps | 981 return deps |
926 | |
927 def opt_limit_to_suite(projects): | |
928 if _opts.specific_suite is None: | |
929 return projects | |
930 else: | |
931 result = [] | |
932 for p in projects: | |
933 s = p.suite | |
934 if s.name == _opts.specific_suite: | |
935 result.append(p) | |
936 return result | |
937 | 982 |
938 def _handle_missing_java_home(): | 983 def _handle_missing_java_home(): |
939 if not sys.stdout.isatty(): | 984 if not sys.stdout.isatty(): |
940 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') | 985 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') |
941 | 986 |
997 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) | 1042 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) |
998 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) | 1043 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) |
999 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) | 1044 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) |
1000 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') | 1045 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') |
1001 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) | 1046 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) |
1002 self.add_argument('--suite', dest='specific_suite', help='limit command to given suite', default=None) | 1047 self.add_argument('--suite', action='append', dest='specific_suites', help='limit command to given suite', default=[]) |
1003 if get_os() != 'windows': | 1048 if get_os() != 'windows': |
1004 # Time outs are (currently) implemented with Unix specific functionality | 1049 # Time outs are (currently) implemented with Unix specific functionality |
1005 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') | 1050 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') |
1006 self.add_argument('--ptimeout', help='timeout (in seconds) for subprocesses', type=int, default=0, metavar='<secs>') | 1051 self.add_argument('--ptimeout', help='timeout (in seconds) for subprocesses', type=int, default=0, metavar='<secs>') |
1007 | 1052 |
1551 # Silently ignore JDT if default location is used but not ecj.jar exists there | 1596 # Silently ignore JDT if default location is used but not ecj.jar exists there |
1552 jdtJar = None | 1597 jdtJar = None |
1553 | 1598 |
1554 built = set() | 1599 built = set() |
1555 | 1600 |
1556 projects = None | |
1557 if args.projects is not None: | |
1558 projects = args.projects.split(',') | |
1559 | |
1560 if args.only is not None: | 1601 if args.only is not None: |
1602 # N.B. This build will not include dependencies including annotation processor dependencies | |
1561 sortedProjects = [project(name) for name in args.only.split(',')] | 1603 sortedProjects = [project(name) for name in args.only.split(',')] |
1562 else: | 1604 else: |
1563 sortedProjects = sorted_deps(projects, includeAnnotationProcessors=True) | 1605 if args.projects is not None: |
1606 projectNames = args.projects.split(',') | |
1607 else: | |
1608 projectNames = None | |
1609 | |
1610 projects = _projects_opt_limit_to_suites(projects_from_names(projectNames)) | |
1611 # N.B. Limiting to a suite only affects the starting set of projects. Dependencies in other suites will still be compiled | |
1612 sortedProjects = sorted_project_deps(projects, includeAnnotationProcessors=True) | |
1564 | 1613 |
1565 if args.java: | 1614 if args.java: |
1566 ideinit([], refreshOnly=True, buildProcessorJars=False) | 1615 ideinit([], refreshOnly=True, buildProcessorJars=False) |
1567 | 1616 |
1568 for p in sortedProjects: | 1617 for p in sortedProjects: |
2058 | 2107 |
2059 parser.add_argument('-f', action='store_true', dest='force', help='force checking (disables timestamp checking)') | 2108 parser.add_argument('-f', action='store_true', dest='force', help='force checking (disables timestamp checking)') |
2060 args = parser.parse_args(args) | 2109 args = parser.parse_args(args) |
2061 | 2110 |
2062 totalErrors = 0 | 2111 totalErrors = 0 |
2063 for p in sorted_deps(): | 2112 for p in projects_opt_limit_to_suites(): |
2064 if p.native: | 2113 if p.native: |
2065 continue | 2114 continue |
2066 sourceDirs = p.source_dirs() | 2115 sourceDirs = p.source_dirs() |
2067 dotCheckstyle = join(p.dir, '.checkstyle') | 2116 dotCheckstyle = join(p.dir, '.checkstyle') |
2068 | 2117 |
2189 parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects') | 2238 parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects') |
2190 parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects') | 2239 parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects') |
2191 | 2240 |
2192 args = parser.parse_args(args) | 2241 args = parser.parse_args(args) |
2193 | 2242 |
2194 for p in projects(): | 2243 for p in projects_opt_limit_to_suites(): |
2195 if p.native: | 2244 if p.native: |
2196 if args.native: | 2245 if args.native: |
2197 run([gmake_cmd(), '-C', p.dir, 'clean']) | 2246 run([gmake_cmd(), '-C', p.dir, 'clean']) |
2198 else: | 2247 else: |
2199 if args.java: | 2248 if args.java: |
2281 | 2330 |
2282 slm.close('sourceContainers') | 2331 slm.close('sourceContainers') |
2283 slm.close('sourceLookupDirector') | 2332 slm.close('sourceLookupDirector') |
2284 return slm | 2333 return slm |
2285 | 2334 |
2286 def make_eclipse_attach(hostname, port, name=None, deps=None): | 2335 def make_eclipse_attach(suite, hostname, port, name=None, deps=None): |
2287 """ | 2336 """ |
2288 Creates an Eclipse launch configuration file for attaching to a Java process. | 2337 Creates an Eclipse launch configuration file for attaching to a Java process. |
2289 """ | 2338 """ |
2290 if deps is None: | 2339 if deps is None: |
2291 deps = [] | 2340 deps = [] |
2303 launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.VM_CONNECTOR_ID', 'value' : 'org.eclipse.jdt.launching.socketAttachConnector'}) | 2352 launch.element('stringAttribute', {'key' : 'org.eclipse.jdt.launching.VM_CONNECTOR_ID', 'value' : 'org.eclipse.jdt.launching.socketAttachConnector'}) |
2304 launch.close('launchConfiguration') | 2353 launch.close('launchConfiguration') |
2305 launch = launch.xml(newl='\n', standalone='no') % slm.xml(escape=True, standalone='no') | 2354 launch = launch.xml(newl='\n', standalone='no') % slm.xml(escape=True, standalone='no') |
2306 | 2355 |
2307 if name is None: | 2356 if name is None: |
2308 name = 'attach-' + hostname + '-' + port | 2357 if len(suites()) == 1: |
2309 eclipseLaunches = join('mx', 'eclipse-launches') | 2358 suitePrefix ='' |
2359 else: | |
2360 suitePrefix = suite.name + '-' | |
2361 name = suitePrefix + 'attach-' + hostname + '-' + port | |
2362 eclipseLaunches = join(suite.mxDir, 'eclipse-launches') | |
2310 if not exists(eclipseLaunches): | 2363 if not exists(eclipseLaunches): |
2311 os.makedirs(eclipseLaunches) | 2364 os.makedirs(eclipseLaunches) |
2312 return update_file(join(eclipseLaunches, name + '.launch'), launch) | 2365 return update_file(join(eclipseLaunches, name + '.launch'), launch) |
2313 | 2366 |
2314 def make_eclipse_launch(javaArgs, jre, name=None, deps=None): | 2367 def make_eclipse_launch(javaArgs, jre, name=None, deps=None): |
2376 eclipseLaunches = join('mx', 'eclipse-launches') | 2429 eclipseLaunches = join('mx', 'eclipse-launches') |
2377 if not exists(eclipseLaunches): | 2430 if not exists(eclipseLaunches): |
2378 os.makedirs(eclipseLaunches) | 2431 os.makedirs(eclipseLaunches) |
2379 return update_file(join(eclipseLaunches, name + '.launch'), launch) | 2432 return update_file(join(eclipseLaunches, name + '.launch'), launch) |
2380 | 2433 |
2381 def eclipseinit(args, suite=None, buildProcessorJars=True, refreshOnly=False): | 2434 def eclipseinit(args, buildProcessorJars=True, refreshOnly=False): |
2382 """(re)generate Eclipse project configurations and working sets""" | 2435 """(re)generate Eclipse project configurations and working sets""" |
2383 | 2436 for s in suites(True): |
2384 if suite is None: | 2437 _eclipseinit_suite(args, s, buildProcessorJars, refreshOnly) |
2385 suite = _mainSuite | 2438 |
2386 | 2439 generate_eclipse_workingsets() |
2440 | |
2441 | |
2442 def _eclipseinit_suite(args, suite, buildProcessorJars=True, refreshOnly=False): | |
2387 projectsFile = join(suite.mxDir, 'projects') | 2443 projectsFile = join(suite.mxDir, 'projects') |
2388 timestamp = TimeStampFile(join(suite.mxDir, 'eclipseinit.timestamp')) | 2444 timestamp = TimeStampFile(join(suite.mxDir, 'eclipseinit.timestamp')) |
2389 if refreshOnly and not timestamp.exists(): | 2445 if refreshOnly and not timestamp.exists(): |
2390 return | 2446 return |
2391 | 2447 |
2392 if not timestamp.outOfDate(projectsFile): | 2448 if not timestamp.outOfDate(projectsFile): |
2393 logv('[Eclipse configurations are up to date - skipping]') | 2449 logv('[Eclipse configurations are up to date - skipping]') |
2394 return | 2450 return |
2395 | 2451 |
2396 if buildProcessorJars: | 2452 if buildProcessorJars: |
2453 ## todo suite specific | |
2397 processorjars() | 2454 processorjars() |
2398 | 2455 |
2399 projToDist = dict() | 2456 projToDist = dict() |
2400 for dist in _dists.values(): | 2457 for dist in _dists.values(): |
2401 distDeps = sorted_deps(dist.deps) | 2458 distDeps = sorted_deps(dist.deps) |
2402 for p in distDeps: | 2459 for p in distDeps: |
2403 projToDist[p.name] = (dist, [dep.name for dep in distDeps]) | 2460 projToDist[p.name] = (dist, [dep.name for dep in distDeps]) |
2404 | 2461 |
2405 for p in projects(): | 2462 for p in suite.projects: |
2406 if p.native: | 2463 if p.native: |
2407 continue | 2464 continue |
2408 | 2465 |
2409 if not exists(p.dir): | 2466 if not exists(p.dir): |
2410 os.makedirs(p.dir) | 2467 os.makedirs(p.dir) |
2575 else: | 2632 else: |
2576 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) | 2633 out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) |
2577 out.close('factorypath') | 2634 out.close('factorypath') |
2578 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) | 2635 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) |
2579 | 2636 |
2580 make_eclipse_attach('localhost', '8000', deps=projects()) | 2637 make_eclipse_attach(suite, 'localhost', '8000', deps=projects()) |
2581 generate_eclipse_workingsets(suite) | |
2582 timestamp.touch() | 2638 timestamp.touch() |
2583 | 2639 |
2584 def _isAnnotationProcessorDependency(p): | 2640 def _isAnnotationProcessorDependency(p): |
2585 """ | 2641 """ |
2586 Determines if a given project is part of an annotation processor. | 2642 Determines if a given project is part of an annotation processor. |
2587 """ | 2643 """ |
2588 return p in sorted_deps(annotation_processors()) | 2644 return p in sorted_deps(annotation_processors()) |
2634 dotProjectDoc.element('value', data='true') | 2690 dotProjectDoc.element('value', data='true') |
2635 dotProjectDoc.close('dictionary') | 2691 dotProjectDoc.close('dictionary') |
2636 dotProjectDoc.close('arguments') | 2692 dotProjectDoc.close('arguments') |
2637 dotProjectDoc.close('buildCommand') | 2693 dotProjectDoc.close('buildCommand') |
2638 | 2694 |
2639 def generate_eclipse_workingsets(suite): | 2695 def generate_eclipse_workingsets(): |
2640 """ | 2696 """ |
2641 Populate the workspace's working set configuration with working sets generated from project data. | 2697 Populate the workspace's working set configuration with working sets generated from project data for the primary suite |
2642 If the workspace already contains working set definitions, the existing ones will be retained and extended. | 2698 If the workspace already contains working set definitions, the existing ones will be retained and extended. |
2643 In case mx/env does not contain a WORKSPACE definition pointing to the workspace root directory, the Graal project root directory will be assumed. | 2699 In case mx/env does not contain a WORKSPACE definition pointing to the workspace root directory, a parent search from the primary suite directory is performed. |
2644 If no workspace root directory can be identified, the Graal project root directory is used and the user has to place the workingsets.xml file by hand. | 2700 If no workspace root directory can be identified, the primary suite directory is used and the user has to place the workingsets.xml file by hand. |
2645 """ | 2701 """ |
2646 | 2702 |
2647 # identify the location where to look for workingsets.xml | 2703 # identify the location where to look for workingsets.xml |
2648 wsfilename = 'workingsets.xml' | 2704 wsfilename = 'workingsets.xml' |
2649 wsloc = '.metadata/.plugins/org.eclipse.ui.workbench' | 2705 wsloc = '.metadata/.plugins/org.eclipse.ui.workbench' |
2650 wsroot = suite.dir | |
2651 if os.environ.has_key('WORKSPACE'): | 2706 if os.environ.has_key('WORKSPACE'): |
2652 wsroot = os.environ['WORKSPACE'] | 2707 expected_wsroot = os.environ['WORKSPACE'] |
2708 else: | |
2709 expected_wsroot = _mainSuite.dir | |
2710 | |
2711 wsroot =_find_eclipse_wsroot(expected_wsroot) | |
2712 if wsroot is None: | |
2713 # failed to find it | |
2714 wsroot = expected_wsroot | |
2715 | |
2653 wsdir = join(wsroot, wsloc) | 2716 wsdir = join(wsroot, wsloc) |
2654 if not exists(wsdir): | 2717 if not exists(wsdir): |
2655 wsdir = wsroot | 2718 wsdir = wsroot |
2656 log('Could not find Eclipse metadata directory. Please place ' + wsfilename + ' in ' + wsloc + ' manually.') | 2719 log('Could not find Eclipse metadata directory. Please place ' + wsfilename + ' in ' + wsloc + ' manually.') |
2657 wspath = join(wsdir, wsfilename) | 2720 wspath = join(wsdir, wsfilename) |
2671 wsdoc = _copy_workingset_xml(wspath, workingSets) | 2734 wsdoc = _copy_workingset_xml(wspath, workingSets) |
2672 else: | 2735 else: |
2673 wsdoc = _make_workingset_xml(workingSets) | 2736 wsdoc = _make_workingset_xml(workingSets) |
2674 | 2737 |
2675 update_file(wspath, wsdoc.xml(newl='\n')) | 2738 update_file(wspath, wsdoc.xml(newl='\n')) |
2739 | |
2740 def _find_eclipse_wsroot(wsdir): | |
2741 md = join(wsdir, '.metadata') | |
2742 if exists(md): | |
2743 return wsdir | |
2744 split = os.path.split(wsdir) | |
2745 # How to do this for Windows? | |
2746 if split[0] == '/': | |
2747 return None | |
2748 else: | |
2749 return _find_eclipse_wsroot(split[0]) | |
2750 | |
2751 def _foobar(val): | |
2752 print(val) | |
2676 | 2753 |
2677 def _make_workingset_xml(workingSets): | 2754 def _make_workingset_xml(workingSets): |
2678 wsdoc = XMLDoc() | 2755 wsdoc = XMLDoc() |
2679 wsdoc.open('workingSetManager') | 2756 wsdoc.open('workingSetManager') |
2680 | 2757 |
2754 wsdoc.open('workingSet', {'editPageID': 'org.eclipse.jdt.ui.JavaWorkingSetPage', 'factoryID': 'org.eclipse.ui.internal.WorkingSetFactory', 'id': 'wsid_' + ws, 'label': ws, 'name': ws}) | 2831 wsdoc.open('workingSet', {'editPageID': 'org.eclipse.jdt.ui.JavaWorkingSetPage', 'factoryID': 'org.eclipse.ui.internal.WorkingSetFactory', 'id': 'wsid_' + ws, 'label': ws, 'name': ws}) |
2755 | 2832 |
2756 def _workingset_element(wsdoc, p): | 2833 def _workingset_element(wsdoc, p): |
2757 wsdoc.element('item', {'elementID': '=' + p, 'factoryID': 'org.eclipse.jdt.ui.PersistableJavaElementFactory'}) | 2834 wsdoc.element('item', {'elementID': '=' + p, 'factoryID': 'org.eclipse.jdt.ui.PersistableJavaElementFactory'}) |
2758 | 2835 |
2759 def netbeansinit(args, suite=None, refreshOnly=False, buildProcessorJars=True): | 2836 def netbeansinit(args, refreshOnly=False, buildProcessorJars=True): |
2760 """(re)generate NetBeans project configurations""" | 2837 """(re)generate NetBeans project configurations""" |
2761 | 2838 |
2762 if suite is None: | 2839 for suite in suites(True): |
2763 suite = _mainSuite | 2840 _netbeansinit_suite(args, suite, refreshOnly, buildProcessorJars) |
2764 | 2841 |
2842 def _netbeansinit_suite(args, suite, refreshOnly=False, buildProcessorJars=True): | |
2765 projectsFile = join(suite.mxDir, 'projects') | 2843 projectsFile = join(suite.mxDir, 'projects') |
2766 timestamp = TimeStampFile(join(suite.mxDir, 'netbeansinit.timestamp')) | 2844 timestamp = TimeStampFile(join(suite.mxDir, 'netbeansinit.timestamp')) |
2767 if refreshOnly and not timestamp.exists(): | 2845 if refreshOnly and not timestamp.exists(): |
2768 return | 2846 return |
2769 | 2847 |
2770 if not timestamp.outOfDate(projectsFile): | 2848 if not timestamp.outOfDate(projectsFile): |
2771 logv('[NetBeans configurations are up to date - skipping]') | 2849 logv('[NetBeans configurations are up to date - skipping]') |
2772 return | 2850 return |
2773 | 2851 |
2774 updated = False | 2852 updated = False |
2775 for p in projects(): | 2853 for p in suite.projects: |
2776 if p.native: | 2854 if p.native: |
2777 continue | 2855 continue |
2778 | 2856 |
2779 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 2857 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
2780 continue | 2858 continue |
2986 log(' 1. Ensure that a platform named "JDK_' + str(java().version) + '" is defined (Tools -> Java Platforms)') | 3064 log(' 1. Ensure that a platform named "JDK_' + str(java().version) + '" is defined (Tools -> Java Platforms)') |
2987 log(' 2. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)') | 3065 log(' 2. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)') |
2988 | 3066 |
2989 timestamp.touch() | 3067 timestamp.touch() |
2990 | 3068 |
2991 def ideclean(args, suite=None): | 3069 def ideclean(args): |
2992 """remove all Eclipse and NetBeans project configurations""" | 3070 """remove all Eclipse and NetBeans project configurations""" |
2993 def rm(path): | 3071 def rm(path): |
2994 if exists(path): | 3072 if exists(path): |
2995 os.remove(path) | 3073 os.remove(path) |
2996 | 3074 |
3014 rm(join(p.dir, p.name + '.jar')) | 3092 rm(join(p.dir, p.name + '.jar')) |
3015 except: | 3093 except: |
3016 log("Error removing {0}".format(p.name + '.jar')) | 3094 log("Error removing {0}".format(p.name + '.jar')) |
3017 | 3095 |
3018 | 3096 |
3019 def ideinit(args, suite=None, refreshOnly=False, buildProcessorJars=True): | 3097 def ideinit(args, refreshOnly=False, buildProcessorJars=True): |
3020 """(re)generate Eclipse and NetBeans project configurations""" | 3098 """(re)generate Eclipse and NetBeans project configurations""" |
3021 eclipseinit(args, suite, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) | 3099 eclipseinit(args, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) |
3022 netbeansinit(args, suite, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) | 3100 netbeansinit(args, refreshOnly=refreshOnly, buildProcessorJars=buildProcessorJars) |
3023 if not refreshOnly: | 3101 if not refreshOnly: |
3024 fsckprojects([]) | 3102 fsckprojects([]) |
3025 | 3103 |
3026 def fsckprojects(args): | 3104 def fsckprojects(args): |
3027 """find directories corresponding to deleted Java projects and delete them""" | 3105 """find directories corresponding to deleted Java projects and delete them""" |
3028 for suite in suites(): | 3106 for suite in suites(True): |
3029 projectDirs = [p.dir for p in suite.projects] | 3107 projectDirs = [p.dir for p in suite.projects] |
3030 for root, dirnames, files in os.walk(suite.dir): | 3108 for root, dirnames, files in os.walk(suite.dir): |
3031 currentDir = join(suite.dir, root) | 3109 currentDir = join(suite.dir, root) |
3032 if currentDir in projectDirs: | 3110 if currentDir in projectDirs: |
3033 # don't traverse subdirs of an existing project | 3111 # don't traverse subdirs of an existing project |
3056 parser.add_argument('--exclude-packages', action='store', help='comma separated packages to exclude') | 3134 parser.add_argument('--exclude-packages', action='store', help='comma separated packages to exclude') |
3057 | 3135 |
3058 args = parser.parse_args(args) | 3136 args = parser.parse_args(args) |
3059 | 3137 |
3060 # build list of projects to be processed | 3138 # build list of projects to be processed |
3061 candidates = sorted_deps() | |
3062 if args.projects is not None: | 3139 if args.projects is not None: |
3063 candidates = [project(name) for name in args.projects.split(',')] | 3140 candidates = [project(name) for name in args.projects.split(',')] |
3141 else: | |
3142 candidates = projects_opt_limit_to_suites() | |
3064 | 3143 |
3065 # optionally restrict packages within a project | 3144 # optionally restrict packages within a project |
3066 packages = [] | 3145 packages = [] |
3067 if args.packages is not None: | 3146 if args.packages is not None: |
3068 packages = [name for name in args.packages.split(',')] | 3147 packages = [name for name in args.packages.split(',')] |
3522 projectsFile = join(s.mxDir, 'projects') | 3601 projectsFile = join(s.mxDir, 'projects') |
3523 if exists(projectsFile): | 3602 if exists(projectsFile): |
3524 log(projectsFile) | 3603 log(projectsFile) |
3525 for p in s.projects: | 3604 for p in s.projects: |
3526 log('\t' + p.name) | 3605 log('\t' + p.name) |
3527 | 3606 |
3528 def ask_yes_no(question, default=None): | 3607 def ask_yes_no(question, default=None): |
3529 """""" | 3608 """""" |
3530 assert not default or default == 'y' or default == 'n' | 3609 assert not default or default == 'y' or default == 'n' |
3531 if not sys.stdout.isatty(): | 3610 if not sys.stdout.isatty(): |
3532 if default: | 3611 if default: |
3586 _argParser = ArgParser() | 3665 _argParser = ArgParser() |
3587 | 3666 |
3588 def _findPrimarySuite(): | 3667 def _findPrimarySuite(): |
3589 def is_suite_dir(d): | 3668 def is_suite_dir(d): |
3590 for f in os.listdir(d): | 3669 for f in os.listdir(d): |
3591 if fnmatch.fnmatch(f, 'mx*'): | 3670 if f == 'mx' or fnmatch.fnmatch(f, 'mx.*'): |
3592 mxDir = join(d, f) | 3671 mxDir = join(d, f) |
3593 if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): | 3672 if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): |
3594 return dirname(mxDir) | 3673 return dirname(mxDir) |
3595 | 3674 |
3596 | 3675 |