[GR-8893] Add command to flatten multi-release sources. · graalvm/mx@bad56c1 (original) (raw)

`@@ -62,7 +62,7 @@

`

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.

`

``

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()

`