Mercurial > hg > graal-jvmci-8
comparison mxtool/mx.py @ 11605:3676540f71cf
Allow mxtool suites to be in separate repositories (CR-1367)
author | Mick Jordan <mick.jordan@oracle.com> |
---|---|
date | Wed, 11 Sep 2013 21:04:24 +0200 |
parents | 723796685546 |
children | 60e3fe0fe939 |
comparison
equal
deleted
inserted
replaced
11604:943f1863e1c1 | 11605:3676540f71cf |
---|---|
35 | 35 |
36 The organizing principle of mx is a project suite. A suite is a directory | 36 The organizing principle of mx is a project suite. A suite is a directory |
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. | 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). | |
42 An 'mx' subdirectory can be named as plain 'mx' or 'mxbasename', where | |
43 'basename' is the os.path.basename of the suite directory. | |
44 The latter is useful to avoid clashes in IDE project names. | |
41 | 45 |
42 When launched, mx treats the current working directory as a suite. | 46 When launched, mx treats the current working directory as a suite. |
43 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. |
44 | 48 |
45 The configuration files (i.e. in the 'mx' sub-directory) of a suite are: | 49 The configuration files (i.e. in the 'mx' sub-directory) of a suite are: |
135 by extension commands. | 139 by extension commands. |
136 | 140 |
137 Property values can use environment variables with Bash syntax (e.g. ${HOME}). | 141 Property values can use environment variables with Bash syntax (e.g. ${HOME}). |
138 """ | 142 """ |
139 | 143 |
140 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile | 144 import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch |
141 import textwrap | 145 import textwrap |
142 import xml.parsers.expat | 146 import xml.parsers.expat |
143 import shutil, re, xml.dom.minidom | 147 import shutil, re, xml.dom.minidom |
144 from collections import Callable | 148 from collections import Callable |
145 from threading import Thread | 149 from threading import Thread |
433 self.sourceUrls = sourceUrls | 437 self.sourceUrls = sourceUrls |
434 for url in urls: | 438 for url in urls: |
435 if url.endswith('/') != self.path.endswith(os.sep): | 439 if url.endswith('/') != self.path.endswith(os.sep): |
436 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) | 440 abort('Path for dependency directory must have a URL ending with "/": path=' + self.path + ' url=' + url) |
437 | 441 |
442 def __eq__(self, other): | |
443 if isinstance(other, Library): | |
444 if len(self.urls) == 0: | |
445 return self.path == other.path | |
446 else: | |
447 return self.urls == other.urls | |
448 else: | |
449 return NotImplemented | |
450 | |
451 | |
452 def __ne__(self, other): | |
453 result = self.__eq__(other) | |
454 if result is NotImplemented: | |
455 return result | |
456 return not result | |
457 | |
458 | |
438 def get_path(self, resolve): | 459 def get_path(self, resolve): |
439 path = self.path | 460 path = self.path |
440 if not isabs(path): | 461 if not isabs(path): |
441 path = join(self.suite.dir, path) | 462 path = join(self.suite.dir, path) |
442 if resolve and self.mustExist and not exists(path): | 463 if resolve and self.mustExist and not exists(path): |
466 return deps | 487 return deps |
467 deps.append(self) | 488 deps.append(self) |
468 return deps | 489 return deps |
469 | 490 |
470 class Suite: | 491 class Suite: |
471 def __init__(self, d, primary): | 492 def __init__(self, d, mxDir, primary): |
472 self.dir = d | 493 self.dir = d |
494 self.mxDir = mxDir | |
473 self.projects = [] | 495 self.projects = [] |
474 self.libs = [] | 496 self.libs = [] |
475 self.dists = [] | 497 self.dists = [] |
476 self.includes = [] | 498 self.includes = [] |
477 self.commands = None | 499 self.commands = None |
478 self.primary = primary | 500 self.primary = primary |
479 mxDir = join(d, 'mx') | |
480 self._load_env(mxDir) | 501 self._load_env(mxDir) |
481 self._load_commands(mxDir) | 502 self._load_commands(mxDir) |
482 self._load_includes(mxDir) | 503 self._load_includes(mxDir) |
483 self.name = d # re-initialized in _load_projects | 504 self.name = d # re-initialized in _load_projects |
484 | 505 |
588 if not hasattr(mod, 'mx_init'): | 609 if not hasattr(mod, 'mx_init'): |
589 abort(commandsPath + ' must define an mx_init(env) function') | 610 abort(commandsPath + ' must define an mx_init(env) function') |
590 if hasattr(mod, 'mx_post_parse_cmd_line'): | 611 if hasattr(mod, 'mx_post_parse_cmd_line'): |
591 self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line | 612 self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line |
592 | 613 |
593 mod.mx_init() | 614 mod.mx_init(self) |
594 self.commands = mod | 615 self.commands = mod |
595 | 616 |
596 def _load_includes(self, mxDir): | 617 def _load_includes(self, mxDir): |
597 includes = join(mxDir, 'includes') | 618 includes = join(mxDir, 'includes') |
598 if exists(includes): | 619 if exists(includes): |
599 with open(includes) as f: | 620 with open(includes) as f: |
600 for line in f: | 621 for line in f: |
601 include = expandvars_in_property(line.strip()) | 622 include = expandvars_in_property(line.strip()) |
602 self.includes.append(include) | 623 self.includes.append(include) |
603 _loadSuite(include, False) | 624 _loadSuite(os.path.abspath(include), False) |
604 | 625 |
605 def _load_env(self, mxDir): | 626 def _load_env(self, mxDir): |
606 e = join(mxDir, 'env') | 627 e = join(mxDir, 'env') |
607 if exists(e): | 628 if exists(e): |
608 with open(e) as f: | 629 with open(e) as f: |
614 if not '=' in line: | 635 if not '=' in line: |
615 abort(e + ':' + str(lineNum) + ': line does not match pattern "key=value"') | 636 abort(e + ':' + str(lineNum) + ': line does not match pattern "key=value"') |
616 key, value = line.split('=', 1) | 637 key, value = line.split('=', 1) |
617 os.environ[key.strip()] = expandvars_in_property(value.strip()) | 638 os.environ[key.strip()] = expandvars_in_property(value.strip()) |
618 def _post_init(self, opts): | 639 def _post_init(self, opts): |
619 mxDir = join(self.dir, 'mx') | 640 self._load_projects(self.mxDir) |
620 self._load_projects(mxDir) | |
621 for p in self.projects: | 641 for p in self.projects: |
622 existing = _projects.get(p.name) | 642 existing = _projects.get(p.name) |
623 if existing is not None: | 643 if existing is not None: |
624 abort('cannot override project ' + p.name + ' in ' + p.dir + " with project of the same name in " + existing.dir) | 644 abort('cannot override project ' + p.name + ' in ' + p.dir + " with project of the same name in " + existing.dir) |
625 if not p.name in _opts.ignored_projects: | 645 if not p.name in _opts.ignored_projects: |
626 _projects[p.name] = p | 646 _projects[p.name] = p |
627 for l in self.libs: | 647 for l in self.libs: |
628 existing = _libs.get(l.name) | 648 existing = _libs.get(l.name) |
629 if existing is not None: | 649 # Check that suites that define same library are consistent |
630 abort('cannot redefine library ' + l.name) | 650 if existing is not None and existing != l: |
651 abort('inconsistent library redefinition of ' + l.name + ' in ' + existing.suite.dir + ' and ' + l.suite.dir) | |
631 _libs[l.name] = l | 652 _libs[l.name] = l |
632 for d in self.dists: | 653 for d in self.dists: |
633 existing = _dists.get(d.name) | 654 existing = _dists.get(d.name) |
634 if existing is not None: | 655 if existing is not None: |
635 abort('cannot redefine distribution ' + d.name) | 656 abort('cannot redefine distribution ' + d.name) |
727 return 'windows' | 748 return 'windows' |
728 else: | 749 else: |
729 abort('Unknown operating system ' + sys.platform) | 750 abort('Unknown operating system ' + sys.platform) |
730 | 751 |
731 def _loadSuite(d, primary=False): | 752 def _loadSuite(d, primary=False): |
732 mxDir = join(d, 'mx') | 753 """ |
733 if not exists(mxDir) or not isdir(mxDir): | 754 Load a suite from the 'mx' or 'mxbbb' subdirectory of d, where 'bbb' is basename of d |
755 """ | |
756 mxDefaultDir = join(d, 'mx') | |
757 name = os.path.basename(d) | |
758 mxTaggedDir = mxDefaultDir + name | |
759 mxDir = None | |
760 if exists(mxTaggedDir) and isdir(mxTaggedDir): | |
761 mxDir = mxTaggedDir | |
762 else: | |
763 if exists(mxDefaultDir) and isdir(mxDefaultDir): | |
764 mxDir = mxDefaultDir | |
765 | |
766 | |
767 if mxDir is None: | |
734 return None | 768 return None |
735 if len([s for s in _suites.itervalues() if s.dir == d]) == 0: | 769 if len([s for s in _suites.itervalues() if s.dir == d]) == 0: |
736 s = Suite(d, primary) | 770 s = Suite(d, mxDir, primary) |
737 _suites[s.name] = s | 771 _suites[name] = s |
738 return s | 772 return s |
739 | 773 |
740 def suites(): | 774 def suites(): |
741 """ | 775 """ |
742 Get the list of all loaded suites. | 776 Get the list of all loaded suites. |
877 are before the projects that depend on them. Unless 'includeLibs' is | 911 are before the projects that depend on them. Unless 'includeLibs' is |
878 true, libraries are omitted from the result. | 912 true, libraries are omitted from the result. |
879 """ | 913 """ |
880 deps = [] | 914 deps = [] |
881 if projectNames is None: | 915 if projectNames is None: |
882 projects = _projects.values() | 916 projects = opt_limit_to_suite(_projects.values()) |
883 else: | 917 else: |
884 projects = [project(name) for name in projectNames] | 918 projects = [project(name) for name in projectNames] |
885 | 919 |
886 for p in projects: | 920 for p in projects: |
887 p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) | 921 p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) |
888 return deps | 922 return deps |
923 | |
924 def opt_limit_to_suite(projects): | |
925 if _opts.specific_suite is None: | |
926 return projects | |
927 else: | |
928 result = [] | |
929 for p in projects: | |
930 s = p.suite | |
931 if s.name == _opts.specific_suite: | |
932 result.append(p) | |
933 return result | |
889 | 934 |
890 def _handle_missing_java_home(): | 935 def _handle_missing_java_home(): |
891 if not sys.stdout.isatty(): | 936 if not sys.stdout.isatty(): |
892 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') | 937 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') |
893 | 938 |
934 return ArgumentParser.format_help(self) + _format_commands() | 979 return ArgumentParser.format_help(self) + _format_commands() |
935 | 980 |
936 | 981 |
937 def __init__(self): | 982 def __init__(self): |
938 self.java_initialized = False | 983 self.java_initialized = False |
939 ArgumentParser.__init__(self, prog='mx') | 984 # this doesn't resolve the right way, but can't figure out how to override _handle_conflict_resolve in _ActionsContainer |
985 ArgumentParser.__init__(self, prog='mx', conflict_handler='resolve') | |
940 | 986 |
941 self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') | 987 self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') |
942 self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') | 988 self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') |
943 self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on <port> for a debugger', metavar='<port>') | 989 self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on <port> for a debugger', metavar='<port>') |
944 self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') | 990 self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') |
948 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) | 994 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) |
949 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) | 995 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) |
950 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) | 996 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) |
951 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') | 997 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') |
952 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) | 998 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) |
999 self.add_argument('--suite', dest='specific_suite', help='limit command to given suite', default=None) | |
953 if get_os() != 'windows': | 1000 if get_os() != 'windows': |
954 # Time outs are (currently) implemented with Unix specific functionality | 1001 # Time outs are (currently) implemented with Unix specific functionality |
955 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') | 1002 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') |
956 self.add_argument('--ptimeout', help='timeout (in seconds) for subprocesses', type=int, default=0, metavar='<secs>') | 1003 self.add_argument('--ptimeout', help='timeout (in seconds) for subprocesses', type=int, default=0, metavar='<secs>') |
957 | 1004 |
984 | 1031 |
985 opts.ignored_projects = opts.ignored_projects + os.environ.get('IGNORED_PROJECTS', '').split(',') | 1032 opts.ignored_projects = opts.ignored_projects + os.environ.get('IGNORED_PROJECTS', '').split(',') |
986 | 1033 |
987 commandAndArgs = opts.__dict__.pop('commandAndArgs') | 1034 commandAndArgs = opts.__dict__.pop('commandAndArgs') |
988 return opts, commandAndArgs | 1035 return opts, commandAndArgs |
1036 | |
1037 def _handle_conflict_resolve(self, action, conflicting_actions): | |
1038 self._handle_conflict_error(action, conflicting_actions) | |
989 | 1039 |
990 def _format_commands(): | 1040 def _format_commands(): |
991 msg = '\navailable commands:\n\n' | 1041 msg = '\navailable commands:\n\n' |
992 for cmd in sorted(_commands.iterkeys()): | 1042 for cmd in sorted(_commands.iterkeys()): |
993 c, _ = _commands[cmd][:2] | 1043 c, _ = _commands[cmd][:2] |
1995 javafilelist += [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] | 2045 javafilelist += [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] |
1996 if len(javafilelist) == 0: | 2046 if len(javafilelist) == 0: |
1997 logv('[no Java sources in {0} - skipping]'.format(sourceDir)) | 2047 logv('[no Java sources in {0} - skipping]'.format(sourceDir)) |
1998 continue | 2048 continue |
1999 | 2049 |
2000 timestampFile = join(p.suite.dir, 'mx', 'checkstyle-timestamps', sourceDir[len(p.suite.dir) + 1:].replace(os.sep, '_') + '.timestamp') | 2050 timestampFile = join(p.suite.mxDir, 'checkstyle-timestamps', sourceDir[len(p.suite.dir) + 1:].replace(os.sep, '_') + '.timestamp') |
2001 if not exists(dirname(timestampFile)): | 2051 if not exists(dirname(timestampFile)): |
2002 os.makedirs(dirname(timestampFile)) | 2052 os.makedirs(dirname(timestampFile)) |
2003 mustCheck = False | 2053 mustCheck = False |
2004 if not args.force and exists(timestampFile): | 2054 if not args.force and exists(timestampFile): |
2005 timestamp = os.path.getmtime(timestampFile) | 2055 timestamp = os.path.getmtime(timestampFile) |
2081 if name == 'file': | 2131 if name == 'file': |
2082 source[0] = attrs['name'] | 2132 source[0] = attrs['name'] |
2083 elif name == 'error': | 2133 elif name == 'error': |
2084 errors.append('{}:{}: {}'.format(source[0], attrs['line'], attrs['message'])) | 2134 errors.append('{}:{}: {}'.format(source[0], attrs['line'], attrs['message'])) |
2085 | 2135 |
2086 p = xml.parsers.expat.ParserCreate() | 2136 xp = xml.parsers.expat.ParserCreate() |
2087 p.StartElementHandler = start_element | 2137 xp.StartElementHandler = start_element |
2088 with open(auditfileName) as fp: | 2138 with open(auditfileName) as fp: |
2089 p.ParseFile(fp) | 2139 xp.ParseFile(fp) |
2090 if len(errors) != 0: | 2140 if len(errors) != 0: |
2091 map(log, errors) | 2141 map(log, errors) |
2092 totalErrors = totalErrors + len(errors) | 2142 totalErrors = totalErrors + len(errors) |
2093 else: | 2143 else: |
2094 if exists(timestampFile): | 2144 if exists(timestampFile): |
2354 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) | 2404 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) |
2355 elif hasattr(dep, 'eclipse.project'): | 2405 elif hasattr(dep, 'eclipse.project'): |
2356 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')}) | 2406 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + getattr(dep, 'eclipse.project')}) |
2357 else: | 2407 else: |
2358 path = dep.path | 2408 path = dep.path |
2359 if dep.mustExist: | 2409 dep.get_path(resolve=True) |
2360 dep.get_path(resolve=True) | 2410 if not exists(path) and not dep.mustExist: |
2361 if not isabs(path): | 2411 continue |
2362 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse | 2412 |
2363 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's | 2413 if not isabs(path): |
2364 # safest to simply use absolute paths. | 2414 # Relative paths for "lib" class path entries have various semantics depending on the Eclipse |
2365 path = join(suite.dir, path) | 2415 # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's |
2366 | 2416 # safest to simply use absolute paths. |
2367 attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} | 2417 path = join(suite.dir, path) |
2368 | 2418 |
2369 sourcePath = dep.get_source_path(resolve=True) | 2419 attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} |
2370 if sourcePath is not None: | 2420 |
2371 attributes['sourcepath'] = sourcePath | 2421 sourcePath = dep.get_source_path(resolve=True) |
2372 out.element('classpathentry', attributes) | 2422 if sourcePath is not None: |
2423 attributes['sourcepath'] = sourcePath | |
2424 out.element('classpathentry', attributes) | |
2373 else: | 2425 else: |
2374 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) | 2426 out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) |
2375 | 2427 |
2376 out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) | 2428 out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) |
2377 out.close('classpath') | 2429 out.close('classpath') |
2452 | 2504 |
2453 settingsDir = join(p.dir, ".settings") | 2505 settingsDir = join(p.dir, ".settings") |
2454 if not exists(settingsDir): | 2506 if not exists(settingsDir): |
2455 os.mkdir(settingsDir) | 2507 os.mkdir(settingsDir) |
2456 | 2508 |
2457 eclipseSettingsDir = join(suite.dir, 'mx', 'eclipse-settings') | 2509 eclipseSettingsDir = join(suite.mxDir, 'eclipse-settings') |
2458 if exists(eclipseSettingsDir): | 2510 if exists(eclipseSettingsDir): |
2459 for name in os.listdir(eclipseSettingsDir): | 2511 for name in os.listdir(eclipseSettingsDir): |
2460 if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: | 2512 if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: |
2461 continue | 2513 continue |
2462 path = join(eclipseSettingsDir, name) | 2514 path = join(eclipseSettingsDir, name) |
2933 if len(indicators) != 0: | 2985 if len(indicators) != 0: |
2934 if not sys.stdout.isatty() or ask_yes_no(currentDir + ' looks like a removed project -- delete it', 'n'): | 2986 if not sys.stdout.isatty() or ask_yes_no(currentDir + ' looks like a removed project -- delete it', 'n'): |
2935 shutil.rmtree(currentDir) | 2987 shutil.rmtree(currentDir) |
2936 log('Deleted ' + currentDir) | 2988 log('Deleted ' + currentDir) |
2937 | 2989 |
2938 def javadoc(args, parser=None, docDir='javadoc', includeDeps=True): | 2990 def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=True): |
2939 """generate javadoc for some/all Java projects""" | 2991 """generate javadoc for some/all Java projects""" |
2940 | 2992 |
2941 parser = ArgumentParser(prog='mx javadoc') if parser is None else parser | 2993 parser = ArgumentParser(prog='mx javadoc') if parser is None else parser |
2942 parser.add_argument('-d', '--base', action='store', help='base directory for output') | 2994 parser.add_argument('-d', '--base', action='store', help='base directory for output') |
2943 parser.add_argument('--unified', action='store_true', help='put javadoc in a single directory instead of one per project') | 2995 parser.add_argument('--unified', action='store_true', help='put javadoc in a single directory instead of one per project') |
3035 print >> fp, '<html><body>Documentation for the <code>' + p.name + '</code> project.</body></html>' | 3087 print >> fp, '<html><body>Documentation for the <code>' + p.name + '</code> project.</body></html>' |
3036 delOverviewFile = True | 3088 delOverviewFile = True |
3037 nowarnAPI = [] | 3089 nowarnAPI = [] |
3038 if not args.warnAPI: | 3090 if not args.warnAPI: |
3039 nowarnAPI.append('-XDignore.symbol.file') | 3091 nowarnAPI.append('-XDignore.symbol.file') |
3092 | |
3093 # windowTitle onloy applies to the standard doclet processor | |
3094 windowTitle = [] | |
3095 if stdDoclet: | |
3096 windowTitle = ['-windowtitle', p.name + ' javadoc'] | |
3040 try: | 3097 try: |
3041 log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) | 3098 log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) |
3042 run([java().javadoc, memory, | 3099 run([java().javadoc, memory, |
3043 '-windowtitle', p.name + ' javadoc', | |
3044 '-XDignore.symbol.file', | 3100 '-XDignore.symbol.file', |
3045 '-classpath', cp, | 3101 '-classpath', cp, |
3046 '-quiet', | 3102 '-quiet', |
3047 '-d', out, | 3103 '-d', out, |
3048 '-overview', overviewFile, | 3104 '-overview', overviewFile, |
3049 '-sourcepath', sp] + | 3105 '-sourcepath', sp] + |
3050 links + | 3106 links + |
3051 extraArgs + | 3107 extraArgs + |
3052 nowarnAPI + | 3108 nowarnAPI + |
3109 windowTitle + | |
3053 list(pkgs)) | 3110 list(pkgs)) |
3054 log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) | 3111 log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) |
3055 finally: | 3112 finally: |
3056 if delOverviewFile: | 3113 if delOverviewFile: |
3057 os.remove(overviewFile) | 3114 os.remove(overviewFile) |
3435 """ | 3492 """ |
3436 Define how a single command-line argument. | 3493 Define how a single command-line argument. |
3437 """ | 3494 """ |
3438 assert _argParser is not None | 3495 assert _argParser is not None |
3439 _argParser.add_argument(*args, **kwargs) | 3496 _argParser.add_argument(*args, **kwargs) |
3497 | |
3498 def update_commands(suite, new_commands): | |
3499 for key, value in new_commands.iteritems(): | |
3500 if _commands.has_key(key) and not suite.primary: | |
3501 pass | |
3502 # print("WARNING: attempt to redefine command '" + key + "' in suite " + suite.dir) | |
3503 else: | |
3504 _commands[key] = value | |
3440 | 3505 |
3441 # Table of commands in alphabetical order. | 3506 # Table of commands in alphabetical order. |
3442 # Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...] | 3507 # Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...] |
3443 # If any of the format args are instances of Callable, then they are called with an 'env' are before being | 3508 # If any of the format args are instances of Callable, then they are called with an 'env' are before being |
3444 # used in the call to str.format(). | 3509 # used in the call to str.format(). |
3467 | 3532 |
3468 _argParser = ArgParser() | 3533 _argParser = ArgParser() |
3469 | 3534 |
3470 def _findPrimarySuite(): | 3535 def _findPrimarySuite(): |
3471 def is_suite_dir(d): | 3536 def is_suite_dir(d): |
3472 mxDir = join(d, 'mx') | 3537 for f in os.listdir(d): |
3473 if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): | 3538 if fnmatch.fnmatch(f, 'mx*'): |
3474 return dirname(mxDir) | 3539 mxDir = join(d, f) |
3540 if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): | |
3541 return dirname(mxDir) | |
3542 | |
3475 | 3543 |
3476 # try current working directory first | 3544 # try current working directory first |
3477 if is_suite_dir(os.getcwd()): | 3545 if is_suite_dir(os.getcwd()): |
3478 return os.getcwd() | 3546 return os.getcwd() |
3479 | 3547 |