|
62 | 62 | from collections import Callable, OrderedDict, namedtuple, deque |
63 | 63 | from datetime import datetime |
64 | 64 | from threading import Thread |
65 | | -from argparse import ArgumentParser, REMAINDER, Namespace, FileType, HelpFormatter |
| 65 | +from argparse import ArgumentParser, REMAINDER, Namespace, FileType, HelpFormatter, ArgumentTypeError |
66 | 66 | from os.path import join, basename, dirname, exists, isabs, expandvars, isdir |
67 | 67 | from tempfile import mkdtemp |
68 | 68 | import fnmatch |
@@ -1304,11 +1304,9 @@ def addSrcFromDir(srcDir, archivePrefix=''): |
1304 | 1304 | archivePrefix = p.archive_prefix() |
1305 | 1305 | if mrjVersion is not None: |
1306 | 1306 | try: |
1307 | | - mrjVersion = int(mrjVersion) |
1308 | | - if mrjVersion < 9: |
1309 | | - raise ValueError() |
1310 | | - except ValueError: |
1311 | | - abort("Value of 'multiReleaseJarVersion' attribute should be an integer greater or equal to 9: " + str(mrjVersion), context=p) |
| 1307 | + mrjVersion = _parse_multireleasejar_version(mrjVersion) |
| 1308 | + except ArgumentTypeError as e: |
| 1309 | + abort(str(e), context=p) |
1312 | 1310 | archivePrefix = 'META-INF/versions/{}/'.format(mrjVersion) |
1313 | 1311 | if 'Multi-Release: true' not in manifestEntries: |
1314 | 1312 | manifestEntries.append('Multi-Release: true') |
@@ -2311,6 +2309,47 @@ def _eclipseinit(self, files=None, libFiles=None, absolutePaths=False): |
2311 | 2309 | """ |
2312 | 2310 | _eclipseinit_project(self, files=files, libFiles=libFiles, absolutePaths=absolutePaths) |
2313 | 2311 |
|
| 2312 | + def get_multireleasesources_flatten_map(self): |
| 2313 | + """ |
| 2314 | + Gets a map from the versioned source directories in this project to the |
| 2315 | + non-versioned source directories they [preside over](https://docs.oracle.com/javase/9/docs/specs/jar/jar.html). |
| 2316 | + """ |
| 2317 | + if not hasattr(self, 'multiReleaseJarVersion'): |
| 2318 | + return {} |
| 2319 | + def _find_version_base_project(): |
| 2320 | + extended_packages = self.extended_java_packages() |
| 2321 | + if not extended_packages: |
| 2322 | + abort('Project with a multiReleaseJarVersion attribute must have sources in a package defined by project without multiReleaseJarVersion attribute', context=self) |
| 2323 | + base_project = None |
| 2324 | + base_package = None |
| 2325 | + for extended_package in extended_packages: |
| 2326 | + for p in projects(): |
| 2327 | + if self != p and p.isJavaProject() and not hasattr(p, 'multiReleaseJarVersion'): |
| 2328 | + if extended_package in p.defined_java_packages(): |
| 2329 | + if base_project is None: |
| 2330 | + base_project = p |
| 2331 | + base_package = extended_package |
| 2332 | + else: |
| 2333 | + if base_project != p: |
| 2334 | + abort('Multi-release jar versioned project {} must extend packages from exactly one project but extends {} from {} and {} from {}'.format(self, extended_package, p, base_project, base_package)) |
| 2335 | + if not base_project: |
| 2336 | + abort('Multi-release jar versioned project {} must extend package(s) from another project'.format(self)) |
| 2337 | + return base_project |
| 2338 | + |
| 2339 | + base = _find_version_base_project() |
| 2340 | + flatten_map = {} |
| 2341 | + self_packages = self.defined_java_packages() | self.extended_java_packages() |
| 2342 | + for package in self_packages: |
| 2343 | + relative_package_src_dir = package.replace('.', os.sep) |
| 2344 | + for self_package_src_dir in [join(s, relative_package_src_dir) for s in self.source_dirs()]: |
| 2345 | + if exists(self_package_src_dir): |
| 2346 | + assert len(base.source_dirs()) != 0, '{} has no source directories!'.format(base) |
| 2347 | + for base_package_src_dir in [join(s, relative_package_src_dir) for s in base.source_dirs()]: |
| 2348 | + if exists(base_package_src_dir) or not flatten_map.has_key(self_package_src_dir): |
| 2349 | + flatten_map[self_package_src_dir] = base_package_src_dir |
| 2350 | + assert len(self_packages) == len(flatten_map), 'could not find sources for all packages in ' + self.name |
| 2351 | + return flatten_map |
| 2352 | + |
2314 | 2353 | def getBuildTask(self, args): |
2315 | 2354 | requiredCompliance = self.javaCompliance |
2316 | 2355 | if not requiredCompliance.isExactBound and hasattr(args, 'javac_crosscompile') and args.javac_crosscompile: |
@@ -11338,10 +11377,11 @@ def findfiles_by_vc(pyfiles): |
11338 | 11377 | if f.endswith('.py'): |
11339 | 11378 | pyfile = join(root, f) |
11340 | 11379 | pyfiles.append(pyfile) |
11341 | | - if args.walk: |
11342 | | - findfiles_by_walk(pyfiles) |
11343 | 11380 | else: |
11344 | | - findfiles_by_vc(pyfiles) |
| 11381 | + if args.walk: |
| 11382 | + findfiles_by_walk(pyfiles) |
| 11383 | + else: |
| 11384 | + findfiles_by_vc(pyfiles) |
11345 | 11385 |
|
11346 | 11386 | env = os.environ.copy() |
11347 | 11387 |
|
@@ -11920,6 +11960,51 @@ def help_(args): |
11920 | 11960 | doc = doc.format(*fmtArgs) |
11921 | 11961 | print 'mx {0} {1}\n\n{2}\n'.format(name, usage, doc) |
11922 | 11962 |
|
| 11963 | +def _parse_multireleasejar_version(value): |
| 11964 | + try: |
| 11965 | + mrjVersion = int(value) |
| 11966 | + if mrjVersion < 9: |
| 11967 | + raise ArgumentTypeError('multi-release jar version ({}) must be greater than 8'.format(value)) |
| 11968 | + return mrjVersion |
| 11969 | + except ValueError: |
| 11970 | + raise ArgumentTypeError('multi-release jar version ({}) must be an int value greater than 8'.format(value)) |
| 11971 | + |
| 11972 | +def flattenMultiReleaseSources(args): |
| 11973 | + """print map for flattening multi-release sources |
| 11974 | + |
| 11975 | + Prints space separated (versioned_dir, base_dir) pairs where versioned_dir contains versioned sources |
| 11976 | + for a multi-release jar and base_dir contains the corresponding non-versioned (or base versioned) |
| 11977 | + sources. |
| 11978 | + """ |
| 11979 | + parser = ArgumentParser(prog='mx flattenmultireleasesources') |
| 11980 | + parser.add_argument('-c', '--commands', action='store_true', help='format the output as a series of commands to copy '\ |
| 11981 | + 'the versioned sources to the location of the non-versioned sources') |
| 11982 | + parser.add_argument('version', type=_parse_multireleasejar_version, help='major version of the Java release for which flattened sources will be produced') |
| 11983 | + |
| 11984 | + args = parser.parse_args(args) |
| 11985 | + versions = {} |
| 11986 | + for p in projects(): |
| 11987 | + if p.isJavaProject() and hasattr(p, 'multiReleaseJarVersion'): |
| 11988 | + version = _parse_multireleasejar_version(getattr(p, 'multiReleaseJarVersion')) |
| 11989 | + if version <= args.version: |
| 11990 | + versions.setdefault(version, []).append(p.get_multireleasesources_flatten_map()) |
| 11991 | + else: |
| 11992 | + # Ignore overlays for versions higher than the one requested |
| 11993 | + pass |
| 11994 | + |
| 11995 | + # Process versioned overlays in ascending order such that higher versions |
| 11996 | + # override lower versions. This corresponds with how versioned classes in |
| 11997 | + # multi-release jars are resolved. |
| 11998 | + for version, maps in sorted(versions.items()): |
| 11999 | + for flatten_map in maps: |
| 12000 | + for src_dir, dst_dir in flatten_map.iteritems(): |
| 12001 | + if not args.commands: |
| 12002 | + print src_dir, dst_dir |
| 12003 | + else: |
| 12004 | + if not exists(dst_dir): |
| 12005 | + print 'mkdir -p {}'.format(dst_dir) |
| 12006 | + print 'cp {}{}* {}'.format(src_dir, os.sep, dst_dir) |
| 12007 | + |
11923 | 12008 | def projectgraph(args, suite=None): |
11924 | 12009 | """create graph for project structure ("mx projectgraph | dot -Tpdf -oprojects.pdf" or "mx projectgraph --igv")""" |
11925 | 12010 |
|
@@ -15941,6 +16026,7 @@ def list_commands(l): |
15941 | 16026 | 'eclipseinit': [eclipseinit_cli, ''], |
15942 | 16027 | 'envs': [show_envs, '[options]'], |
15943 | 16028 | 'exportlibs': [exportlibs, ''], |
| 16029 | + 'flattenmultireleasesources' : [flattenMultiReleaseSources, 'version'], |
15944 | 16030 | 'findbugs': [mx_findbugs.findbugs, ''], |
15945 | 16031 | 'findclass': [findclass, ''], |
15946 | 16032 | 'fsckprojects': [fsckprojects, ''], |
@@ -16801,7 +16887,7 @@ def alarm_handler(signum, frame): |
16801 | 16887 |
|
16802 | 16888 |
|
16803 | 16889 | # The comment after VersionSpec should be changed in a random manner for every bump to force merge conflicts! |
16804 | | -version = VersionSpec("5.146") # always tasks |
| 16890 | +version = VersionSpec("5.147.0") # GR-8893 |
16805 | 16891 |
|
16806 | 16892 | currentUmask = None |
16807 | 16893 | _mx_start_datetime = datetime.utcnow() |
|
0 commit comments