Mercurial > hg > truffle
comparison mxtool/mx.py @ 11514:dc3c8df55905
added support for pylint and fixed errors/warnings it found
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 03 Sep 2013 16:33:41 +0200 |
parents | 3110bea9a6b0 |
children | 723796685546 |
comparison
equal
deleted
inserted
replaced
11513:8d4e5e08d83f | 11514:dc3c8df55905 |
---|---|
123 "true" if the project is native. | 123 "true" if the project is native. |
124 | 124 |
125 javaCompliance | 125 javaCompliance |
126 The minimum JDK version (format: x.y) to which the project's | 126 The minimum JDK version (format: x.y) to which the project's |
127 sources comply (required for non-native projects). | 127 sources comply (required for non-native projects). |
128 | 128 |
129 workingSets | 129 workingSets |
130 A comma separated list of working set names. The project belongs | 130 A comma separated list of working set names. The project belongs |
131 to the given working sets, for which the eclipseinit command | 131 to the given working sets, for which the eclipseinit command |
132 will generate Eclipse configurations. | 132 will generate Eclipse configurations. |
133 | 133 |
143 import shutil, re, xml.dom.minidom | 143 import shutil, re, xml.dom.minidom |
144 from collections import Callable | 144 from collections import Callable |
145 from threading import Thread | 145 from threading import Thread |
146 from argparse import ArgumentParser, REMAINDER | 146 from argparse import ArgumentParser, REMAINDER |
147 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile | 147 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile |
148 | |
149 DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g' | |
150 | 148 |
151 _projects = dict() | 149 _projects = dict() |
152 _libs = dict() | 150 _libs = dict() |
153 _dists = dict() | 151 _dists = dict() |
154 _suites = dict() | 152 _suites = dict() |
167 self.path = path.replace('/', os.sep) | 165 self.path = path.replace('/', os.sep) |
168 if not isabs(self.path): | 166 if not isabs(self.path): |
169 self.path = join(suite.dir, self.path) | 167 self.path = join(suite.dir, self.path) |
170 self.deps = deps | 168 self.deps = deps |
171 self.update_listeners = set() | 169 self.update_listeners = set() |
172 | 170 |
173 def __str__(self): | 171 def __str__(self): |
174 return self.name | 172 return self.name |
175 | 173 |
176 def add_update_listener(self, listener): | 174 def add_update_listener(self, listener): |
177 self.update_listeners.add(listener) | 175 self.update_listeners.add(listener) |
178 | 176 |
179 def notify_updated(self): | 177 def notify_updated(self): |
180 for l in self.update_listeners: | 178 for l in self.update_listeners: |
181 l(self) | 179 l(self) |
182 | 180 |
183 """ | 181 """ |
184 A dependency is a library or project specified in a suite. | 182 A dependency is a library or project specified in a suite. |
185 """ | 183 """ |
186 class Dependency: | 184 class Dependency: |
187 def __init__(self, suite, name): | 185 def __init__(self, suite, name): |
200 def __hash__(self): | 198 def __hash__(self): |
201 return hash(self.name) | 199 return hash(self.name) |
202 | 200 |
203 def isLibrary(self): | 201 def isLibrary(self): |
204 return isinstance(self, Library) | 202 return isinstance(self, Library) |
205 | 203 |
206 def isProject(self): | 204 def isProject(self): |
207 return isinstance(self, Project) | 205 return isinstance(self, Project) |
208 | 206 |
209 class Project(Dependency): | 207 class Project(Dependency): |
210 def __init__(self, suite, name, srcDirs, deps, javaCompliance, workingSets, d): | 208 def __init__(self, suite, name, srcDirs, deps, javaCompliance, workingSets, d): |
214 self.checkstyleProj = name | 212 self.checkstyleProj = name |
215 self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None | 213 self.javaCompliance = JavaCompliance(javaCompliance) if javaCompliance is not None else None |
216 self.native = False | 214 self.native = False |
217 self.workingSets = workingSets | 215 self.workingSets = workingSets |
218 self.dir = d | 216 self.dir = d |
219 | 217 |
220 # Create directories for projects that don't yet exist | 218 # Create directories for projects that don't yet exist |
221 if not exists(d): | 219 if not exists(d): |
222 os.mkdir(d) | 220 os.mkdir(d) |
223 for s in self.source_dirs(): | 221 for s in self.source_dirs(): |
224 if not exists(s): | 222 if not exists(s): |
242 if not self in deps and includeSelf: | 240 if not self in deps and includeSelf: |
243 deps.append(self) | 241 deps.append(self) |
244 return deps | 242 return deps |
245 | 243 |
246 def _compute_max_dep_distances(self, name, distances, dist): | 244 def _compute_max_dep_distances(self, name, distances, dist): |
247 currentDist = distances.get(name); | 245 currentDist = distances.get(name) |
248 if currentDist is None or currentDist < dist: | 246 if currentDist is None or currentDist < dist: |
249 distances[name] = dist | 247 distances[name] = dist |
250 p = project(name, False) | 248 p = project(name, False) |
251 if p is not None: | 249 if p is not None: |
252 for dep in p.deps: | 250 for dep in p.deps: |
258 via other dependencies). | 256 via other dependencies). |
259 """ | 257 """ |
260 distances = dict() | 258 distances = dict() |
261 result = set() | 259 result = set() |
262 self._compute_max_dep_distances(self.name, distances, 0) | 260 self._compute_max_dep_distances(self.name, distances, 0) |
263 for n,d in distances.iteritems(): | 261 for n, d in distances.iteritems(): |
264 assert d > 0 or n == self.name | 262 assert d > 0 or n == self.name |
265 if d == 1: | 263 if d == 1: |
266 result.add(n) | 264 result.add(n) |
267 | 265 |
268 if len(result) == len(self.deps) and frozenset(self.deps) == result: | 266 if len(result) == len(self.deps) and frozenset(self.deps) == result: |
269 return self.deps | 267 return self.deps |
270 return result; | 268 return result |
271 | 269 |
272 def max_depth(self): | 270 def max_depth(self): |
273 """ | 271 """ |
274 Get the maximum canonical distance between this project and its most distant dependency. | 272 Get the maximum canonical distance between this project and its most distant dependency. |
275 """ | 273 """ |
276 distances = dict() | 274 distances = dict() |
277 self._compute_max_dep_distances(self.name, distances, 0) | 275 self._compute_max_dep_distances(self.name, distances, 0) |
278 return max(distances.values()) | 276 return max(distances.values()) |
279 | 277 |
280 def source_dirs(self): | 278 def source_dirs(self): |
281 """ | 279 """ |
282 Get the directories in which the sources of this project are found. | 280 Get the directories in which the sources of this project are found. |
283 """ | 281 """ |
335 pkg = match.group(1) | 333 pkg = match.group(1) |
336 if function(line.strip()): | 334 if function(line.strip()): |
337 matchFound = True | 335 matchFound = True |
338 if pkg and matchFound: | 336 if pkg and matchFound: |
339 break | 337 break |
340 | 338 |
341 if matchFound: | 339 if matchFound: |
342 basename = name[:-len('.java')] | 340 simpleClassName = name[:-len('.java')] |
343 assert pkg is not None | 341 assert pkg is not None |
344 if pkgRoot is None or pkg.startswith(pkgRoot): | 342 if pkgRoot is None or pkg.startswith(pkgRoot): |
345 pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep)) | 343 pkgOutputDir = join(outputDir, pkg.replace('.', os.path.sep)) |
346 if exists(pkgOutputDir): | 344 if exists(pkgOutputDir): |
347 for e in os.listdir(pkgOutputDir): | 345 for e in os.listdir(pkgOutputDir): |
348 if includeInnerClasses: | 346 if includeInnerClasses: |
349 if e.endswith('.class') and (e.startswith(basename) or e.startswith(basename + '$')): | 347 if e.endswith('.class') and (e.startswith(simpleClassName) or e.startswith(simpleClassName + '$')): |
350 className = pkg + '.' + e[:-len('.class')] | 348 className = pkg + '.' + e[:-len('.class')] |
351 result[className] = source | 349 result[className] = source |
352 elif e == basename + '.class': | 350 elif e == simpleClassName + '.class': |
353 className = pkg + '.' + basename | 351 className = pkg + '.' + simpleClassName |
354 result[className] = source | 352 result[className] = source |
355 return result | 353 return result |
356 | 354 |
357 def _init_packages_and_imports(self): | 355 def _init_packages_and_imports(self): |
358 if not hasattr(self, '_defined_java_packages'): | 356 if not hasattr(self, '_defined_java_packages'): |
359 packages = set() | 357 packages = set() |
360 extendedPackages = set() | 358 extendedPackages = set() |
361 depPackages = set() | 359 depPackages = set() |
365 importRe = re.compile(r'import\s+(?:static\s+)?([^;]+);') | 363 importRe = re.compile(r'import\s+(?:static\s+)?([^;]+);') |
366 for sourceDir in self.source_dirs(): | 364 for sourceDir in self.source_dirs(): |
367 for root, _, files in os.walk(sourceDir): | 365 for root, _, files in os.walk(sourceDir): |
368 javaSources = [name for name in files if name.endswith('.java')] | 366 javaSources = [name for name in files if name.endswith('.java')] |
369 if len(javaSources) != 0: | 367 if len(javaSources) != 0: |
370 pkg = root[len(sourceDir) + 1:].replace(os.sep,'.') | 368 pkg = root[len(sourceDir) + 1:].replace(os.sep, '.') |
371 if not pkg in depPackages: | 369 if not pkg in depPackages: |
372 packages.add(pkg) | 370 packages.add(pkg) |
373 else: | 371 else: |
374 # A project extends a package already defined by one of it dependencies | 372 # A project extends a package already defined by one of it dependencies |
375 extendedPackages.add(pkg) | 373 extendedPackages.add(pkg) |
376 imports.add(pkg) | 374 imports.add(pkg) |
377 | 375 |
378 for n in javaSources: | 376 for n in javaSources: |
379 with open(join(root, n)) as fp: | 377 with open(join(root, n)) as fp: |
380 content = fp.read() | 378 content = fp.read() |
381 imports.update(importRe.findall(content)) | 379 imports.update(importRe.findall(content)) |
382 self._defined_java_packages = frozenset(packages) | 380 self._defined_java_packages = frozenset(packages) |
383 self._extended_java_packages = frozenset(extendedPackages) | 381 self._extended_java_packages = frozenset(extendedPackages) |
384 | 382 |
385 importedPackages = set() | 383 importedPackages = set() |
386 for imp in imports: | 384 for imp in imports: |
387 name = imp | 385 name = imp |
388 while not name in depPackages and len(name) > 0: | 386 while not name in depPackages and len(name) > 0: |
389 lastDot = name.rfind('.') | 387 lastDot = name.rfind('.') |
392 break | 390 break |
393 name = name[0:lastDot] | 391 name = name[0:lastDot] |
394 if name is not None: | 392 if name is not None: |
395 importedPackages.add(name) | 393 importedPackages.add(name) |
396 self._imported_java_packages = frozenset(importedPackages) | 394 self._imported_java_packages = frozenset(importedPackages) |
397 | 395 |
398 def defined_java_packages(self): | 396 def defined_java_packages(self): |
399 """Get the immutable set of Java packages defined by the Java sources of this project""" | 397 """Get the immutable set of Java packages defined by the Java sources of this project""" |
400 self._init_packages_and_imports() | 398 self._init_packages_and_imports() |
401 return self._defined_java_packages | 399 return self._defined_java_packages |
402 | 400 |
403 def extended_java_packages(self): | 401 def extended_java_packages(self): |
404 """Get the immutable set of Java packages extended by the Java sources of this project""" | 402 """Get the immutable set of Java packages extended by the Java sources of this project""" |
405 self._init_packages_and_imports() | 403 self._init_packages_and_imports() |
406 return self._extended_java_packages | 404 return self._extended_java_packages |
407 | 405 |
415 if not hasattr(self, '_annotationProcessors'): | 413 if not hasattr(self, '_annotationProcessors'): |
416 ap = set() | 414 ap = set() |
417 if hasattr(self, '_declaredAnnotationProcessors'): | 415 if hasattr(self, '_declaredAnnotationProcessors'): |
418 ap = set(self._declaredAnnotationProcessors) | 416 ap = set(self._declaredAnnotationProcessors) |
419 | 417 |
420 # find dependencies that auto-inject themselves as annotation processors to all dependents | 418 # find dependencies that auto-inject themselves as annotation processors to all dependents |
421 allDeps = self.all_deps([], includeLibs=False, includeSelf=False, includeAnnotationProcessors=False) | 419 allDeps = self.all_deps([], includeLibs=False, includeSelf=False, includeAnnotationProcessors=False) |
422 for p in allDeps: | 420 for p in allDeps: |
423 if hasattr(p, 'annotationProcessorForDependents') and p.annotationProcessorForDependents.lower() == 'true': | 421 if hasattr(p, 'annotationProcessorForDependents') and p.annotationProcessorForDependents.lower() == 'true': |
424 ap.add(p.name) | 422 ap.add(p.name) |
425 self._annotationProcessors = list(ap) | 423 self._annotationProcessors = list(ap) |
440 def get_path(self, resolve): | 438 def get_path(self, resolve): |
441 path = self.path | 439 path = self.path |
442 if not isabs(path): | 440 if not isabs(path): |
443 path = join(self.suite.dir, path) | 441 path = join(self.suite.dir, path) |
444 if resolve and self.mustExist and not exists(path): | 442 if resolve and self.mustExist and not exists(path): |
445 assert not len(self.urls) == 0, 'cannot find required library ' + self.name + ' ' + path; | 443 assert not len(self.urls) == 0, 'cannot find required library ' + self.name + ' ' + path |
446 print('Downloading ' + self.name + ' from ' + str(self.urls)) | 444 print('Downloading ' + self.name + ' from ' + str(self.urls)) |
447 download(path, self.urls) | 445 download(path, self.urls) |
448 return path | 446 return path |
449 | 447 |
450 def get_source_path(self, resolve): | 448 def get_source_path(self, resolve): |
460 | 458 |
461 def append_to_classpath(self, cp, resolve): | 459 def append_to_classpath(self, cp, resolve): |
462 path = self.get_path(resolve) | 460 path = self.get_path(resolve) |
463 if exists(path) or not resolve: | 461 if exists(path) or not resolve: |
464 cp.append(path) | 462 cp.append(path) |
465 | 463 |
466 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): | 464 def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): |
467 if not includeLibs or not includeSelf: | 465 if not includeLibs or not includeSelf: |
468 return deps | 466 return deps |
469 deps.append(self) | 467 deps.append(self) |
470 return deps | 468 return deps |
480 self.primary = primary | 478 self.primary = primary |
481 mxDir = join(d, 'mx') | 479 mxDir = join(d, 'mx') |
482 self._load_env(mxDir) | 480 self._load_env(mxDir) |
483 self._load_commands(mxDir) | 481 self._load_commands(mxDir) |
484 self._load_includes(mxDir) | 482 self._load_includes(mxDir) |
485 self.name = d # re-initialized in _load_projects | 483 self.name = d # re-initialized in _load_projects |
486 | 484 |
487 def __str__(self): | 485 def __str__(self): |
488 return self.name | 486 return self.name |
489 | 487 |
490 def _load_projects(self, mxDir): | 488 def _load_projects(self, mxDir): |
491 libsMap = dict() | 489 libsMap = dict() |
492 projsMap = dict() | 490 projsMap = dict() |
493 distsMap = dict() | 491 distsMap = dict() |
494 projectsFile = join(mxDir, 'projects') | 492 projectsFile = join(mxDir, 'projects') |
534 | 532 |
535 for name, attrs in projsMap.iteritems(): | 533 for name, attrs in projsMap.iteritems(): |
536 srcDirs = pop_list(attrs, 'sourceDirs') | 534 srcDirs = pop_list(attrs, 'sourceDirs') |
537 deps = pop_list(attrs, 'dependencies') | 535 deps = pop_list(attrs, 'dependencies') |
538 ap = pop_list(attrs, 'annotationProcessors') | 536 ap = pop_list(attrs, 'annotationProcessors') |
539 #deps += ap | 537 # deps += ap |
540 javaCompliance = attrs.pop('javaCompliance', None) | 538 javaCompliance = attrs.pop('javaCompliance', None) |
541 subDir = attrs.pop('subDir', None) | 539 subDir = attrs.pop('subDir', None) |
542 if subDir is None: | 540 if subDir is None: |
543 d = join(self.dir, name) | 541 d = join(self.dir, name) |
544 else: | 542 else: |
568 path = attrs.pop('path') | 566 path = attrs.pop('path') |
569 deps = pop_list(attrs, 'dependencies') | 567 deps = pop_list(attrs, 'dependencies') |
570 d = Distribution(self, name, path, deps) | 568 d = Distribution(self, name, path, deps) |
571 d.__dict__.update(attrs) | 569 d.__dict__.update(attrs) |
572 self.dists.append(d) | 570 self.dists.append(d) |
573 | 571 |
574 if self.name is None: | 572 if self.name is None: |
575 abort('Missing "suite=<name>" in ' + projectsFile) | 573 abort('Missing "suite=<name>" in ' + projectsFile) |
576 | 574 |
577 def _load_commands(self, mxDir): | 575 def _load_commands(self, mxDir): |
578 commands = join(mxDir, 'commands.py') | 576 commandsPath = join(mxDir, 'commands.py') |
579 if exists(commands): | 577 if exists(commandsPath): |
580 # temporarily extend the Python path | 578 # temporarily extend the Python path |
581 sys.path.insert(0, mxDir) | 579 sys.path.insert(0, mxDir) |
582 mod = __import__('commands') | 580 mod = __import__('commands') |
583 | 581 |
584 self.commands = sys.modules.pop('commands') | 582 self.commands = sys.modules.pop('commands') |
585 sys.modules[join(mxDir, 'commands')] = self.commands | 583 sys.modules[join(mxDir, 'commands')] = self.commands |
586 | 584 |
587 # revert the Python path | 585 # revert the Python path |
588 del sys.path[0] | 586 del sys.path[0] |
589 | 587 |
590 if not hasattr(mod, 'mx_init'): | 588 if not hasattr(mod, 'mx_init'): |
591 abort(commands + ' must define an mx_init(env) function') | 589 abort(commandsPath + ' must define an mx_init(env) function') |
592 if hasattr(mod, 'mx_post_parse_cmd_line'): | 590 if hasattr(mod, 'mx_post_parse_cmd_line'): |
593 self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line | 591 self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line |
594 | 592 |
595 mod.mx_init() | 593 mod.mx_init() |
596 self.commands = mod | 594 self.commands = mod |
630 existing = _libs.get(l.name) | 628 existing = _libs.get(l.name) |
631 if existing is not None: | 629 if existing is not None: |
632 abort('cannot redefine library ' + l.name) | 630 abort('cannot redefine library ' + l.name) |
633 _libs[l.name] = l | 631 _libs[l.name] = l |
634 for d in self.dists: | 632 for d in self.dists: |
635 existing = _dists.get(l.name) | 633 existing = _dists.get(d.name) |
636 if existing is not None: | 634 if existing is not None: |
637 abort('cannot redefine distribution ' + d.name) | 635 abort('cannot redefine distribution ' + d.name) |
638 _dists[d.name] = d | 636 _dists[d.name] = d |
639 if hasattr(self, 'mx_post_parse_cmd_line'): | 637 if hasattr(self, 'mx_post_parse_cmd_line'): |
640 self.mx_post_parse_cmd_line(opts) | 638 self.mx_post_parse_cmd_line(opts) |
641 | 639 |
642 class XMLElement(xml.dom.minidom.Element): | 640 class XMLElement(xml.dom.minidom.Element): |
643 def writexml(self, writer, indent="", addindent="", newl=""): | 641 def writexml(self, writer, indent="", addindent="", newl=""): |
644 writer.write(indent+"<" + self.tagName) | 642 writer.write(indent + "<" + self.tagName) |
645 | 643 |
646 attrs = self._get_attributes() | 644 attrs = self._get_attributes() |
647 a_names = attrs.keys() | 645 a_names = attrs.keys() |
648 a_names.sort() | 646 a_names.sort() |
649 | 647 |
655 if not self.ownerDocument.padTextNodeWithoutSiblings and len(self.childNodes) == 1 and isinstance(self.childNodes[0], xml.dom.minidom.Text): | 653 if not self.ownerDocument.padTextNodeWithoutSiblings and len(self.childNodes) == 1 and isinstance(self.childNodes[0], xml.dom.minidom.Text): |
656 # if the only child of an Element node is a Text node, then the | 654 # if the only child of an Element node is a Text node, then the |
657 # text is printed without any indentation or new line padding | 655 # text is printed without any indentation or new line padding |
658 writer.write(">") | 656 writer.write(">") |
659 self.childNodes[0].writexml(writer) | 657 self.childNodes[0].writexml(writer) |
660 writer.write("</%s>%s" % (self.tagName,newl)) | 658 writer.write("</%s>%s" % (self.tagName, newl)) |
661 else: | 659 else: |
662 writer.write(">%s"%(newl)) | 660 writer.write(">%s" % (newl)) |
663 for node in self.childNodes: | 661 for node in self.childNodes: |
664 node.writexml(writer,indent+addindent,addindent,newl) | 662 node.writexml(writer, indent + addindent, addindent, newl) |
665 writer.write("%s</%s>%s" % (indent,self.tagName,newl)) | 663 writer.write("%s</%s>%s" % (indent, self.tagName, newl)) |
666 else: | 664 else: |
667 writer.write("/>%s"%(newl)) | 665 writer.write("/>%s" % (newl)) |
668 | 666 |
669 class XMLDoc(xml.dom.minidom.Document): | 667 class XMLDoc(xml.dom.minidom.Document): |
670 | 668 |
671 def __init__(self): | 669 def __init__(self): |
672 xml.dom.minidom.Document.__init__(self) | 670 xml.dom.minidom.Document.__init__(self) |
680 return e | 678 return e |
681 | 679 |
682 def comment(self, txt): | 680 def comment(self, txt): |
683 self.current.appendChild(self.createComment(txt)) | 681 self.current.appendChild(self.createComment(txt)) |
684 | 682 |
685 def open(self, tag, attributes={}, data=None): | 683 def open(self, tag, attributes=None, data=None): |
684 if attributes is None: | |
685 attributes = {} | |
686 element = self.createElement(tag) | 686 element = self.createElement(tag) |
687 for key, value in attributes.items(): | 687 for key, value in attributes.items(): |
688 element.setAttribute(key, value) | 688 element.setAttribute(key, value) |
689 self.current.appendChild(element) | 689 self.current.appendChild(element) |
690 self.current = element | 690 self.current = element |
696 assert self.current != self | 696 assert self.current != self |
697 assert tag == self.current.tagName, str(tag) + ' != ' + self.current.tagName | 697 assert tag == self.current.tagName, str(tag) + ' != ' + self.current.tagName |
698 self.current = self.current.parentNode | 698 self.current = self.current.parentNode |
699 return self | 699 return self |
700 | 700 |
701 def element(self, tag, attributes={}, data=None): | 701 def element(self, tag, attributes=None, data=None): |
702 if attributes is None: | |
703 attributes = {} | |
702 return self.open(tag, attributes, data).close(tag) | 704 return self.open(tag, attributes, data).close(tag) |
703 | 705 |
704 def xml(self, indent='', newl='', escape=False, standalone=None): | 706 def xml(self, indent='', newl='', escape=False, standalone=None): |
705 assert self.current == self | 707 assert self.current == self |
706 result = self.toprettyxml(indent, newl, encoding="UTF-8") | 708 result = self.toprettyxml(indent, newl, encoding="UTF-8") |
886 return deps | 888 return deps |
887 | 889 |
888 def _handle_missing_java_home(): | 890 def _handle_missing_java_home(): |
889 if not sys.stdout.isatty(): | 891 if not sys.stdout.isatty(): |
890 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') | 892 abort('Could not find bootstrap JDK. Use --java-home option or ensure JAVA_HOME environment variable is set.') |
891 | 893 |
892 candidateJdks = [] | 894 candidateJdks = [] |
893 if get_os() == 'darwin': | 895 if get_os() == 'darwin': |
894 base = '/Library/Java/JavaVirtualMachines' | 896 base = '/Library/Java/JavaVirtualMachines' |
895 candidateJdks = [join(base, n, 'Contents/Home') for n in os.listdir(base) if exists(join(base, n, 'Contents/Home'))] | 897 candidateJdks = [join(base, n, 'Contents/Home') for n in os.listdir(base) if exists(join(base, n, 'Contents/Home'))] |
896 elif get_os() == 'linux': | 898 elif get_os() == 'linux': |
906 javaHome = None | 908 javaHome = None |
907 if len(candidateJdks) != 0: | 909 if len(candidateJdks) != 0: |
908 javaHome = select_items(candidateJdks + ['<other>'], allowMultiple=False) | 910 javaHome = select_items(candidateJdks + ['<other>'], allowMultiple=False) |
909 if javaHome == '<other>': | 911 if javaHome == '<other>': |
910 javaHome = None | 912 javaHome = None |
911 | 913 |
912 while javaHome is None: | 914 while javaHome is None: |
913 javaHome = raw_input('Enter path of bootstrap JDK: ') | 915 javaHome = raw_input('Enter path of bootstrap JDK: ') |
914 rtJarPath = join(javaHome, 'jre', 'lib', 'rt.jar') | 916 rtJarPath = join(javaHome, 'jre', 'lib', 'rt.jar') |
915 if not exists(rtJarPath): | 917 if not exists(rtJarPath): |
916 log('Does not appear to be a valid JDK as ' + rtJarPath + ' does not exist') | 918 log('Does not appear to be a valid JDK as ' + rtJarPath + ' does not exist') |
917 javaHome = None | 919 javaHome = None |
918 else: | 920 else: |
919 break | 921 break |
920 | 922 |
921 envPath = join(_mainSuite.dir, 'mx', 'env') | 923 envPath = join(_mainSuite.dir, 'mx', 'env') |
922 if ask_yes_no('Persist this setting by adding "JAVA_HOME=' + javaHome + '" to ' + envPath, 'y'): | 924 if ask_yes_no('Persist this setting by adding "JAVA_HOME=' + javaHome + '" to ' + envPath, 'y'): |
923 with open(envPath, 'a') as fp: | 925 with open(envPath, 'a') as fp: |
924 print >> fp, 'JAVA_HOME=' + javaHome | 926 print >> fp, 'JAVA_HOME=' + javaHome |
925 | 927 |
926 return javaHome | 928 return javaHome |
927 | 929 |
928 class ArgParser(ArgumentParser): | 930 class ArgParser(ArgumentParser): |
929 | 931 |
930 # Override parent to append the list of available commands | 932 # Override parent to append the list of available commands |
940 self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') | 942 self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') |
941 self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on <port> for a debugger', metavar='<port>') | 943 self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on <port> for a debugger', metavar='<port>') |
942 self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') | 944 self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') |
943 self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='<arg>') | 945 self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='<arg>') |
944 self.add_argument('--cp-sfx', dest='cp_suffix', help='class path suffix', metavar='<arg>') | 946 self.add_argument('--cp-sfx', dest='cp_suffix', help='class path suffix', metavar='<arg>') |
945 self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@<args>', default=DEFAULT_JAVA_ARGS) | 947 self.add_argument('--J', dest='java_args', help='Java VM arguments (e.g. --J @-dsa)', metavar='@<args>', default='-ea -Xss2m -Xmx1g') |
946 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) | 948 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) |
947 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-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=[]) |
948 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) | 950 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) |
949 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') | 951 self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') |
950 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) | 952 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) |
985 commandAndArgs = opts.__dict__.pop('commandAndArgs') | 987 commandAndArgs = opts.__dict__.pop('commandAndArgs') |
986 return opts, commandAndArgs | 988 return opts, commandAndArgs |
987 | 989 |
988 def _format_commands(): | 990 def _format_commands(): |
989 msg = '\navailable commands:\n\n' | 991 msg = '\navailable commands:\n\n' |
990 for cmd in sorted(commands.iterkeys()): | 992 for cmd in sorted(_commands.iterkeys()): |
991 c, _ = commands[cmd][:2] | 993 c, _ = _commands[cmd][:2] |
992 doc = c.__doc__ | 994 doc = c.__doc__ |
993 if doc is None: | 995 if doc is None: |
994 doc = '' | 996 doc = '' |
995 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) | 997 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) |
996 return msg + '\n' | 998 return msg + '\n' |
1073 for arg in args: | 1075 for arg in args: |
1074 assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg) | 1076 assert isinstance(arg, types.StringTypes), 'argument is not a string: ' + str(arg) |
1075 | 1077 |
1076 if env is None: | 1078 if env is None: |
1077 env = os.environ | 1079 env = os.environ |
1078 | 1080 |
1079 if _opts.verbose: | 1081 if _opts.verbose: |
1080 if _opts.very_verbose: | 1082 if _opts.very_verbose: |
1081 log('Environment variables:') | 1083 log('Environment variables:') |
1082 for key in sorted(env.keys()): | 1084 for key in sorted(env.keys()): |
1083 log(' ' + key + '=' + env[key]) | 1085 log(' ' + key + '=' + env[key]) |
1106 else: | 1108 else: |
1107 def redirect(stream, f): | 1109 def redirect(stream, f): |
1108 for line in iter(stream.readline, ''): | 1110 for line in iter(stream.readline, ''): |
1109 f(line) | 1111 f(line) |
1110 stream.close() | 1112 stream.close() |
1111 stdout=out if not callable(out) else subprocess.PIPE | 1113 stdout = out if not callable(out) else subprocess.PIPE |
1112 stderr=err if not callable(err) else subprocess.PIPE | 1114 stderr = err if not callable(err) else subprocess.PIPE |
1113 p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn, creationflags=creationflags, env=env) | 1115 p = subprocess.Popen(args, cwd=cwd, stdout=stdout, stderr=stderr, preexec_fn=preexec_fn, creationflags=creationflags, env=env) |
1114 _currentSubprocess = (p, args) | 1116 _currentSubprocess = (p, args) |
1115 if callable(out): | 1117 if callable(out): |
1116 t = Thread(target=redirect, args=(p.stdout, out)) | 1118 t = Thread(target=redirect, args=(p.stdout, out)) |
1117 t.daemon = True # thread dies with the program | 1119 t.daemon = True # thread dies with the program |
1118 t.start() | 1120 t.start() |
1119 if callable(err): | 1121 if callable(err): |
1120 t = Thread(target=redirect, args=(p.stderr, err)) | 1122 t = Thread(target=redirect, args=(p.stderr, err)) |
1121 t.daemon = True # thread dies with the program | 1123 t.daemon = True # thread dies with the program |
1122 t.start() | 1124 t.start() |
1123 if timeout is None or timeout == 0: | 1125 if timeout is None or timeout == 0: |
1124 retcode = waitOn(p) | 1126 retcode = waitOn(p) |
1125 else: | 1127 else: |
1126 if get_os() == 'windows': | 1128 if get_os() == 'windows': |
1139 if retcode and nonZeroIsFatal: | 1141 if retcode and nonZeroIsFatal: |
1140 if _opts.verbose: | 1142 if _opts.verbose: |
1141 if _opts.very_verbose: | 1143 if _opts.very_verbose: |
1142 raise subprocess.CalledProcessError(retcode, ' '.join(args)) | 1144 raise subprocess.CalledProcessError(retcode, ' '.join(args)) |
1143 else: | 1145 else: |
1144 log('[exit code: ' + str(retcode)+ ']') | 1146 log('[exit code: ' + str(retcode) + ']') |
1145 abort(retcode) | 1147 abort(retcode) |
1146 | 1148 |
1147 return retcode | 1149 return retcode |
1148 | 1150 |
1149 def exe_suffix(name): | 1151 def exe_suffix(name): |
1156 | 1158 |
1157 def add_lib_prefix(name): | 1159 def add_lib_prefix(name): |
1158 """ | 1160 """ |
1159 Adds the platform specific library prefix to a name | 1161 Adds the platform specific library prefix to a name |
1160 """ | 1162 """ |
1161 os = get_os(); | 1163 os = get_os() |
1162 if os == 'linux' or os == 'solaris' or os == 'darwin': | 1164 if os == 'linux' or os == 'solaris' or os == 'darwin': |
1163 return 'lib' + name | 1165 return 'lib' + name |
1164 return name | 1166 return name |
1165 | 1167 |
1166 def add_lib_suffix(name): | 1168 def add_lib_suffix(name): |
1167 """ | 1169 """ |
1168 Adds the platform specific library suffix to a name | 1170 Adds the platform specific library suffix to a name |
1169 """ | 1171 """ |
1170 os = get_os(); | 1172 os = get_os() |
1171 if os == 'windows': | 1173 if os == 'windows': |
1172 return name + '.dll' | 1174 return name + '.dll' |
1173 if os == 'linux' or os == 'solaris': | 1175 if os == 'linux' or os == 'solaris': |
1174 return name + '.so' | 1176 return name + '.so' |
1175 if os == 'darwin': | 1177 if os == 'darwin': |
1179 """ | 1181 """ |
1180 A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string. | 1182 A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string. |
1181 """ | 1183 """ |
1182 class JavaCompliance: | 1184 class JavaCompliance: |
1183 def __init__(self, ver): | 1185 def __init__(self, ver): |
1184 m = re.match('1\.(\d+).*', ver) | 1186 m = re.match(r'1\.(\d+).*', ver) |
1185 assert m is not None, 'not a recognized version string: ' + ver | 1187 assert m is not None, 'not a recognized version string: ' + ver |
1186 self.value = int(m.group(1)) | 1188 self.value = int(m.group(1)) |
1187 | 1189 |
1188 def __str__ (self): | 1190 def __str__ (self): |
1189 return '1.' + str(self.value) | 1191 return '1.' + str(self.value) |
1191 def __cmp__ (self, other): | 1193 def __cmp__ (self, other): |
1192 if isinstance(other, types.StringType): | 1194 if isinstance(other, types.StringType): |
1193 other = JavaCompliance(other) | 1195 other = JavaCompliance(other) |
1194 | 1196 |
1195 return cmp(self.value, other.value) | 1197 return cmp(self.value, other.value) |
1196 | 1198 |
1197 """ | 1199 """ |
1198 A Java version as defined in JSR-56 | 1200 A Java version as defined in JSR-56 |
1199 """ | 1201 """ |
1200 class JavaVersion: | 1202 class JavaVersion: |
1201 def __init__(self, versionString): | 1203 def __init__(self, versionString): |
1202 validChar = '[\x21-\x25\x27-\x29\x2c\x2f-\x5e\x60-\x7f]' | 1204 validChar = r'[\x21-\x25\x27-\x29\x2c\x2f-\x5e\x60-\x7f]' |
1203 separator = '[.\-_]' | 1205 separator = r'[.\-_]' |
1204 m = re.match(validChar + '+(' + separator + validChar + '+)*', versionString) | 1206 m = re.match(validChar + '+(' + separator + validChar + '+)*', versionString) |
1205 assert m is not None, 'not a recognized version string: ' + versionString | 1207 assert m is not None, 'not a recognized version string: ' + versionString |
1206 self.versionString = versionString; | 1208 self.versionString = versionString |
1207 self.parts = [int(f) if f.isdigit() else f for f in re.split(separator, versionString)] | 1209 self.parts = [int(f) if f.isdigit() else f for f in re.split(separator, versionString)] |
1208 | 1210 |
1209 def __str__(self): | 1211 def __str__(self): |
1210 return self.versionString | 1212 return self.versionString |
1211 | 1213 |
1212 def __cmp__(self, other): | 1214 def __cmp__(self, other): |
1213 return cmp(self.parts, other.parts) | 1215 return cmp(self.parts, other.parts) |
1214 | 1216 |
1215 """ | 1217 """ |
1216 A JavaConfig object encapsulates info on how Java commands are run. | 1218 A JavaConfig object encapsulates info on how Java commands are run. |
1217 """ | 1219 """ |
1218 class JavaConfig: | 1220 class JavaConfig: |
1219 def __init__(self, opts): | 1221 def __init__(self, opts): |
1220 self.jdk = opts.java_home | 1222 self.jdk = opts.java_home |
1221 self.debug_port = opts.java_dbg_port | 1223 self.debug_port = opts.java_dbg_port |
1222 self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) | 1224 self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) |
1223 self.java = exe_suffix(join(self.jdk, 'bin', 'java')) | 1225 self.java = exe_suffix(join(self.jdk, 'bin', 'java')) |
1224 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) | 1226 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) |
1225 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) | 1227 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) |
1226 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) | 1228 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) |
1227 self._bootclasspath = None | 1229 self._bootclasspath = None |
1228 | 1230 |
1296 return value | 1298 return value |
1297 | 1299 |
1298 def logv(msg=None): | 1300 def logv(msg=None): |
1299 if _opts.verbose: | 1301 if _opts.verbose: |
1300 log(msg) | 1302 log(msg) |
1301 | 1303 |
1302 def log(msg=None): | 1304 def log(msg=None): |
1303 """ | 1305 """ |
1304 Write a message to the console. | 1306 Write a message to the console. |
1305 All script output goes through this method thus allowing a subclass | 1307 All script output goes through this method thus allowing a subclass |
1306 to redirect it. | 1308 to redirect it. |
1330 def gmake_cmd(): | 1332 def gmake_cmd(): |
1331 for a in ['make', 'gmake', 'gnumake']: | 1333 for a in ['make', 'gmake', 'gnumake']: |
1332 try: | 1334 try: |
1333 output = subprocess.check_output([a, '--version']) | 1335 output = subprocess.check_output([a, '--version']) |
1334 if 'GNU' in output: | 1336 if 'GNU' in output: |
1335 return a; | 1337 return a |
1336 except: | 1338 except: |
1337 pass | 1339 pass |
1338 abort('Could not find a GNU make executable on the current path.') | 1340 abort('Could not find a GNU make executable on the current path.') |
1339 | 1341 |
1340 def expandvars_in_property(value): | 1342 def expandvars_in_property(value): |
1341 result = expandvars(value) | 1343 result = expandvars(value) |
1342 if '$' in result or '%' in result: | 1344 if '$' in result or '%' in result: |
1343 abort('Property contains an undefined environment variable: ' + value) | 1345 abort('Property contains an undefined environment variable: ' + value) |
1344 return result | 1346 return result |
1345 | 1347 |
1346 | 1348 |
1347 def abort(codeOrMessage): | 1349 def abort(codeOrMessage): |
1348 """ | 1350 """ |
1349 Aborts the program with a SystemExit exception. | 1351 Aborts the program with a SystemExit exception. |
1350 If 'codeOrMessage' is a plain integer, it specifies the system exit status; | 1352 If 'codeOrMessage' is a plain integer, it specifies the system exit status; |
1351 if it is None, the exit status is zero; if it has another type (such as a string), | 1353 if it is None, the exit status is zero; if it has another type (such as a string), |
1352 the object's value is printed and the exit status is one. | 1354 the object's value is printed and the exit status is one. |
1353 """ | 1355 """ |
1354 | 1356 |
1355 #import traceback | 1357 # import traceback |
1356 #traceback.print_stack() | 1358 # traceback.print_stack() |
1357 currentSubprocess = _currentSubprocess | 1359 currentSubprocess = _currentSubprocess |
1358 if currentSubprocess is not None: | 1360 if currentSubprocess is not None: |
1359 p, _ = currentSubprocess | 1361 p, _ = currentSubprocess |
1360 if get_os() == 'windows': | 1362 if get_os() == 'windows': |
1361 p.kill() | 1363 p.kill() |
1362 else: | 1364 else: |
1363 _kill_process_group(p.pid) | 1365 _kill_process_group(p.pid) |
1364 | 1366 |
1365 raise SystemExit(codeOrMessage) | 1367 raise SystemExit(codeOrMessage) |
1366 | 1368 |
1367 def download(path, urls, verbose=False): | 1369 def download(path, urls, verbose=False): |
1368 """ | 1370 """ |
1369 Attempts to downloads content for each URL in a list, stopping after the first successful download. | 1371 Attempts to downloads content for each URL in a list, stopping after the first successful download. |
1449 | 1451 |
1450 with open(path, 'wb') as f: | 1452 with open(path, 'wb') as f: |
1451 f.write(content) | 1453 f.write(content) |
1452 | 1454 |
1453 log(('modified ' if existed else 'created ') + path) | 1455 log(('modified ' if existed else 'created ') + path) |
1454 return True; | 1456 return True |
1455 except IOError as e: | 1457 except IOError as e: |
1456 abort('Error while writing to ' + path + ': ' + str(e)); | 1458 abort('Error while writing to ' + path + ': ' + str(e)) |
1457 | 1459 |
1458 # Builtin commands | 1460 # Builtin commands |
1459 | 1461 |
1460 def build(args, parser=None): | 1462 def build(args, parser=None): |
1461 """compile the Java and C sources, linking the latter | 1463 """compile the Java and C sources, linking the latter |
1485 | 1487 |
1486 if suppliedParser: | 1488 if suppliedParser: |
1487 parser.add_argument('remainder', nargs=REMAINDER, metavar='...') | 1489 parser.add_argument('remainder', nargs=REMAINDER, metavar='...') |
1488 | 1490 |
1489 args = parser.parse_args(args) | 1491 args = parser.parse_args(args) |
1490 | 1492 |
1491 jdtJar = None | 1493 jdtJar = None |
1492 if args.jdt is not None: | 1494 if args.jdt is not None: |
1493 if args.jdt.endswith('.jar'): | 1495 if args.jdt.endswith('.jar'): |
1494 jdtJar=args.jdt | 1496 jdtJar = args.jdt |
1495 if not exists(jdtJar) and os.path.abspath(jdtJar) == os.path.abspath(defaultEcjPath): | 1497 if not exists(jdtJar) and os.path.abspath(jdtJar) == os.path.abspath(defaultEcjPath): |
1496 # Silently ignore JDT if default location is used but not ecj.jar exists there | 1498 # Silently ignore JDT if default location is used but not ecj.jar exists there |
1497 jdtJar = None | 1499 jdtJar = None |
1498 | 1500 |
1499 built = set() | 1501 built = set() |
1504 | 1506 |
1505 if args.only is not None: | 1507 if args.only is not None: |
1506 sortedProjects = [project(name) for name in args.only.split(',')] | 1508 sortedProjects = [project(name) for name in args.only.split(',')] |
1507 else: | 1509 else: |
1508 sortedProjects = sorted_deps(projects, includeAnnotationProcessors=True) | 1510 sortedProjects = sorted_deps(projects, includeAnnotationProcessors=True) |
1509 | 1511 |
1510 for p in sortedProjects: | 1512 for p in sortedProjects: |
1511 if p.native: | 1513 if p.native: |
1512 if args.native: | 1514 if args.native: |
1513 log('Calling GNU make {0}...'.format(p.dir)) | 1515 log('Calling GNU make {0}...'.format(p.dir)) |
1514 | 1516 |
1519 built.add(p.name) | 1521 built.add(p.name) |
1520 continue | 1522 continue |
1521 else: | 1523 else: |
1522 if not args.java: | 1524 if not args.java: |
1523 continue | 1525 continue |
1524 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 1526 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
1525 continue | 1527 continue |
1526 | 1528 |
1527 # skip building this Java project if its Java compliance level is "higher" than the configured JDK | 1529 # skip building this Java project if its Java compliance level is "higher" than the configured JDK |
1528 if javaCompliance < p.javaCompliance: | 1530 if javaCompliance < p.javaCompliance: |
1529 log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) | 1531 log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) |
1618 processorArgs = [] | 1620 processorArgs = [] |
1619 | 1621 |
1620 ap = p.annotation_processors() | 1622 ap = p.annotation_processors() |
1621 if len(ap) > 0: | 1623 if len(ap) > 0: |
1622 processorPath = classpath(ap, resolve=True) | 1624 processorPath = classpath(ap, resolve=True) |
1623 genDir = p.source_gen_dir(); | 1625 genDir = p.source_gen_dir() |
1624 if exists(genDir): | 1626 if exists(genDir): |
1625 shutil.rmtree(genDir) | 1627 shutil.rmtree(genDir) |
1626 os.mkdir(genDir) | 1628 os.mkdir(genDir) |
1627 processorArgs += ['-processorpath', join(processorPath), '-s', genDir] | 1629 processorArgs += ['-processorpath', join(processorPath), '-s', genDir] |
1628 else: | 1630 else: |
1629 processorArgs += ['-proc:none'] | 1631 processorArgs += ['-proc:none'] |
1630 | 1632 |
1631 toBeDeleted = [argfileName] | 1633 toBeDeleted = [argfileName] |
1632 try: | 1634 try: |
1633 compliance = str(p.javaCompliance) if p.javaCompliance is not None else args.compliance | 1635 compliance = str(p.javaCompliance) if p.javaCompliance is not None else args.compliance |
1634 if jdtJar is None: | 1636 if jdtJar is None: |
1635 log('Compiling Java sources for {0} with javac...'.format(p.name)) | 1637 log('Compiling Java sources for {0} with javac...'.format(p.name)) |
1636 | 1638 |
1637 | 1639 |
1638 javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-classpath', cp, '-d', outputDir] | 1640 javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-classpath', cp, '-d', outputDir] |
1639 if java().debug_port is not None: | 1641 if java().debug_port is not None: |
1640 javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] | 1642 javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] |
1641 javacCmd += processorArgs | 1643 javacCmd += processorArgs |
1642 javacCmd += ['@' + argfile.name] | 1644 javacCmd += ['@' + argfile.name] |
1643 | 1645 |
1644 if not args.warnAPI: | 1646 if not args.warnAPI: |
1645 javacCmd.append('-XDignore.symbol.file') | 1647 javacCmd.append('-XDignore.symbol.file') |
1646 run(javacCmd) | 1648 run(javacCmd) |
1647 else: | 1649 else: |
1648 log('Compiling Java sources for {0} with JDT...'.format(p.name)) | 1650 log('Compiling Java sources for {0} with JDT...'.format(p.name)) |
1649 | 1651 |
1650 jdtArgs = [java().java, '-Xmx1g'] | 1652 jdtArgs = [java().java, '-Xmx1g'] |
1651 if java().debug_port is not None: | 1653 if java().debug_port is not None: |
1652 jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] | 1654 jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] |
1653 | 1655 |
1654 jdtArgs += [ '-jar', jdtJar, | 1656 jdtArgs += [ '-jar', jdtJar, |
1655 '-' + compliance, | 1657 '-' + compliance, |
1656 '-cp', cp, '-g', '-enableJavadoc', | 1658 '-cp', cp, '-g', '-enableJavadoc', |
1657 '-d', outputDir] | 1659 '-d', outputDir] |
1658 jdtArgs += processorArgs | 1660 jdtArgs += processorArgs |
1659 | 1661 |
1660 | 1662 |
1661 jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs') | 1663 jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs') |
1662 rootJdtProperties = join(p.suite.dir, 'mx', 'eclipse-settings', 'org.eclipse.jdt.core.prefs') | 1664 rootJdtProperties = join(p.suite.dir, 'mx', 'eclipse-settings', 'org.eclipse.jdt.core.prefs') |
1663 if not exists(jdtProperties) or os.path.getmtime(jdtProperties) < os.path.getmtime(rootJdtProperties): | 1665 if not exists(jdtProperties) or os.path.getmtime(jdtProperties) < os.path.getmtime(rootJdtProperties): |
1664 # Try to fix a missing properties file by running eclipseinit | 1666 # Try to fix a missing properties file by running eclipseinit |
1665 eclipseinit([], buildProcessorJars=False) | 1667 eclipseinit([], buildProcessorJars=False) |
1676 toBeDeleted.append(jdtPropertiesTmp) | 1678 toBeDeleted.append(jdtPropertiesTmp) |
1677 jdtArgs += ['-properties', jdtPropertiesTmp] | 1679 jdtArgs += ['-properties', jdtPropertiesTmp] |
1678 else: | 1680 else: |
1679 jdtArgs += ['-properties', jdtProperties] | 1681 jdtArgs += ['-properties', jdtProperties] |
1680 jdtArgs.append('@' + argfile.name) | 1682 jdtArgs.append('@' + argfile.name) |
1681 | 1683 |
1682 run(jdtArgs) | 1684 run(jdtArgs) |
1683 finally: | 1685 finally: |
1684 for n in toBeDeleted: | 1686 for n in toBeDeleted: |
1685 os.remove(n) | 1687 os.remove(n) |
1686 | 1688 |
1687 for dist in _dists.values(): | 1689 for dist in _dists.values(): |
1688 archive(['@' + dist.name]) | 1690 archive(['@' + dist.name]) |
1689 | 1691 |
1690 if suppliedParser: | 1692 if suppliedParser: |
1691 return args | 1693 return args |
1698 | 1700 |
1699 parser = ArgumentParser(prog='mx eclipseformat') | 1701 parser = ArgumentParser(prog='mx eclipseformat') |
1700 parser.add_argument('-e', '--eclipse-exe', help='location of the Eclipse executable') | 1702 parser.add_argument('-e', '--eclipse-exe', help='location of the Eclipse executable') |
1701 parser.add_argument('-C', '--no-backup', action='store_false', dest='backup', help='do not save backup of modified files') | 1703 parser.add_argument('-C', '--no-backup', action='store_false', dest='backup', help='do not save backup of modified files') |
1702 parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)') | 1704 parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)') |
1703 | 1705 |
1704 args = parser.parse_args(args) | 1706 args = parser.parse_args(args) |
1705 if args.eclipse_exe is None: | 1707 if args.eclipse_exe is None: |
1706 args.eclipse_exe = os.environ.get('ECLIPSE_EXE') | 1708 args.eclipse_exe = os.environ.get('ECLIPSE_EXE') |
1707 if args.eclipse_exe is None: | 1709 if args.eclipse_exe is None: |
1708 abort('Could not find Eclipse executable. Use -e option or ensure ECLIPSE_EXE environment variable is set.') | 1710 abort('Could not find Eclipse executable. Use -e option or ensure ECLIPSE_EXE environment variable is set.') |
1709 | 1711 |
1710 # Maybe an Eclipse installation dir was specified - look for the executable in it | 1712 # Maybe an Eclipse installation dir was specified - look for the executable in it |
1711 if join(args.eclipse_exe, exe_suffix('eclipse')): | 1713 if join(args.eclipse_exe, exe_suffix('eclipse')): |
1712 args.eclipse_exe = join(args.eclipse_exe, exe_suffix('eclipse')) | 1714 args.eclipse_exe = join(args.eclipse_exe, exe_suffix('eclipse')) |
1713 | 1715 |
1714 if not os.path.isfile(args.eclipse_exe) or not os.access(args.eclipse_exe, os.X_OK): | 1716 if not os.path.isfile(args.eclipse_exe) or not os.access(args.eclipse_exe, os.X_OK): |
1715 abort('Not an executable file: ' + args.eclipse_exe) | 1717 abort('Not an executable file: ' + args.eclipse_exe) |
1716 | 1718 |
1717 eclipseinit([], buildProcessorJars=False) | 1719 eclipseinit([], buildProcessorJars=False) |
1718 | 1720 |
1723 | 1725 |
1724 class Batch: | 1726 class Batch: |
1725 def __init__(self, settingsFile): | 1727 def __init__(self, settingsFile): |
1726 self.path = settingsFile | 1728 self.path = settingsFile |
1727 self.javafiles = list() | 1729 self.javafiles = list() |
1728 | 1730 |
1729 def settings(self): | 1731 def settings(self): |
1730 with open(self.path) as fp: | 1732 with open(self.path) as fp: |
1731 return fp.read() | 1733 return fp.read() |
1732 | 1734 |
1733 class FileInfo: | 1735 class FileInfo: |
1742 content = fp.read() | 1744 content = fp.read() |
1743 if self.content != content: | 1745 if self.content != content: |
1744 self.content = content | 1746 self.content = content |
1745 return True | 1747 return True |
1746 os.utime(self.path, self.times) | 1748 os.utime(self.path, self.times) |
1747 | 1749 |
1748 modified = list() | 1750 modified = list() |
1749 batches = dict() # all sources with the same formatting settings are formatted together | 1751 batches = dict() # all sources with the same formatting settings are formatted together |
1750 for p in projects: | 1752 for p in projects: |
1751 if p.native: | 1753 if p.native: |
1752 continue | 1754 continue |
1753 sourceDirs = p.source_dirs() | 1755 sourceDirs = p.source_dirs() |
1754 | 1756 |
1755 batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')) | 1757 batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')) |
1756 | 1758 |
1757 if not exists(batch.path): | 1759 if not exists(batch.path): |
1758 if _opts.verbose: | 1760 if _opts.verbose: |
1759 log('[no Eclipse Code Formatter preferences at {0} - skipping]'.format(batch.path)) | 1761 log('[no Eclipse Code Formatter preferences at {0} - skipping]'.format(batch.path)) |
1774 for batch in batches.itervalues(): | 1776 for batch in batches.itervalues(): |
1775 run([args.eclipse_exe, '-nosplash', '-application', 'org.eclipse.jdt.core.JavaCodeFormatter', '-config', batch.path] + [f.path for f in batch.javafiles]) | 1777 run([args.eclipse_exe, '-nosplash', '-application', 'org.eclipse.jdt.core.JavaCodeFormatter', '-config', batch.path] + [f.path for f in batch.javafiles]) |
1776 for fi in batch.javafiles: | 1778 for fi in batch.javafiles: |
1777 if fi.update(): | 1779 if fi.update(): |
1778 modified.append(fi) | 1780 modified.append(fi) |
1779 | 1781 |
1780 log('{0} files were modified'.format(len(modified))) | 1782 log('{0} files were modified'.format(len(modified))) |
1781 if len(modified) != 0: | 1783 if len(modified) != 0: |
1782 if args.backup: | 1784 if args.backup: |
1783 backup = os.path.abspath('eclipseformat.backup.zip') | 1785 backup = os.path.abspath('eclipseformat.backup.zip') |
1784 arcbase = _mainSuite.dir | 1786 arcbase = _mainSuite.dir |
1790 log('Wrote backup of {0} modified files to {1}'.format(len(modified), backup)) | 1792 log('Wrote backup of {0} modified files to {1}'.format(len(modified), backup)) |
1791 return 1 | 1793 return 1 |
1792 return 0 | 1794 return 0 |
1793 | 1795 |
1794 def processorjars(): | 1796 def processorjars(): |
1795 | 1797 |
1796 projs = set() | 1798 projs = set() |
1797 for p in sorted_deps(): | 1799 for p in sorted_deps(): |
1798 if _isAnnotationProcessorDependency(p): | 1800 if _isAnnotationProcessorDependency(p): |
1799 projs.add(p) | 1801 projs.add(p) |
1800 | 1802 |
1801 if len(projs) < 0: | 1803 if len(projs) < 0: |
1802 return | 1804 return |
1803 | 1805 |
1804 pnames = [p.name for p in projs] | 1806 pnames = [p.name for p in projs] |
1805 build(['--projects', ",".join(pnames)]) | 1807 build(['--projects', ",".join(pnames)]) |
1806 archive(pnames) | 1808 archive(pnames) |
1807 | 1809 |
1808 def archive(args): | 1810 def archive(args): |
1809 """create jar files for projects and distributions""" | 1811 """create jar files for projects and distributions""" |
1810 parser = ArgumentParser(prog='mx archive'); | 1812 parser = ArgumentParser(prog='mx archive') |
1811 parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...') | 1813 parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...') |
1812 args = parser.parse_args(args) | 1814 args = parser.parse_args(args) |
1813 | 1815 |
1814 for name in args.names: | 1816 for name in args.names: |
1815 if name.startswith('@'): | 1817 if name.startswith('@'): |
1816 dname = name[1:] | 1818 dname = name[1:] |
1817 d = distribution(dname) | 1819 d = distribution(dname) |
1818 fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path)) | 1820 fd, tmp = tempfile.mkstemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path)) |
1819 services = tempfile.mkdtemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path)) | 1821 services = tempfile.mkdtemp(suffix='', prefix=basename(d.path) + '.', dir=dirname(d.path)) |
1820 | 1822 |
1821 def overwriteCheck(zf, arcname, source): | 1823 def overwriteCheck(zf, arcname, source): |
1822 if arcname in zf.namelist(): | 1824 if arcname in zf.namelist(): |
1823 log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']') | 1825 log('warning: ' + d.path + ': overwriting ' + arcname + ' [source: ' + source + ']') |
1824 | 1826 |
1825 try: | 1827 try: |
1826 zf = zipfile.ZipFile(tmp, 'w') | 1828 zf = zipfile.ZipFile(tmp, 'w') |
1827 for dep in sorted_deps(d.deps, includeLibs=True): | 1829 for dep in sorted_deps(d.deps, includeLibs=True): |
1828 if dep.isLibrary(): | 1830 if dep.isLibrary(): |
1829 l = dep | 1831 l = dep |
1844 p = dep | 1846 p = dep |
1845 # skip a Java project if its Java compliance level is "higher" than the configured JDK | 1847 # skip a Java project if its Java compliance level is "higher" than the configured JDK |
1846 if java().javaCompliance < p.javaCompliance: | 1848 if java().javaCompliance < p.javaCompliance: |
1847 log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) | 1849 log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) |
1848 continue | 1850 continue |
1849 | 1851 |
1850 logv('[' + d.path + ': adding project ' + p.name + ']') | 1852 logv('[' + d.path + ': adding project ' + p.name + ']') |
1851 outputDir = p.output_dir() | 1853 outputDir = p.output_dir() |
1852 for root, _, files in os.walk(outputDir): | 1854 for root, _, files in os.walk(outputDir): |
1853 relpath = root[len(outputDir) + 1:] | 1855 relpath = root[len(outputDir) + 1:] |
1854 if relpath == join('META-INF', 'services'): | 1856 if relpath == join('META-INF', 'services'): |
1874 zf.close() | 1876 zf.close() |
1875 os.close(fd) | 1877 os.close(fd) |
1876 shutil.rmtree(services) | 1878 shutil.rmtree(services) |
1877 # Atomic on Unix | 1879 # Atomic on Unix |
1878 shutil.move(tmp, d.path) | 1880 shutil.move(tmp, d.path) |
1879 #print time.time(), 'move:', tmp, '->', d.path | 1881 # print time.time(), 'move:', tmp, '->', d.path |
1880 d.notify_updated() | 1882 d.notify_updated() |
1881 finally: | 1883 finally: |
1882 if exists(tmp): | 1884 if exists(tmp): |
1883 os.remove(tmp) | 1885 os.remove(tmp) |
1884 if exists(services): | 1886 if exists(services): |
1922 m = pattern.match(line) | 1924 m = pattern.match(line) |
1923 if m is None: | 1925 if m is None: |
1924 out.write(line + '\n') | 1926 out.write(line + '\n') |
1925 else: | 1927 else: |
1926 p = project(m.group(1)) | 1928 p = project(m.group(1)) |
1927 | 1929 |
1928 for pkg in p.defined_java_packages(): | 1930 for pkg in p.defined_java_packages(): |
1929 if not pkg.startswith(p.name): | 1931 if not pkg.startswith(p.name): |
1930 abort('package in {0} does not have prefix matching project name: {1}'.format(p, pkg)) | 1932 abort('package in {0} does not have prefix matching project name: {1}'.format(p, pkg)) |
1931 | 1933 |
1932 ignoredDeps = set([name for name in p.deps if project(name, False) is not None]) | 1934 ignoredDeps = set([name for name in p.deps if project(name, False) is not None]) |
1933 for pkg in p.imported_java_packages(): | 1935 for pkg in p.imported_java_packages(): |
1934 for name in p.deps: | 1936 for name in p.deps: |
1935 dep = project(name, False) | 1937 dep = project(name, False) |
1936 if dep is None: | 1938 if dep is None: |
1939 if pkg in dep.defined_java_packages(): | 1941 if pkg in dep.defined_java_packages(): |
1940 ignoredDeps.discard(name) | 1942 ignoredDeps.discard(name) |
1941 if pkg in dep.extended_java_packages(): | 1943 if pkg in dep.extended_java_packages(): |
1942 ignoredDeps.discard(name) | 1944 ignoredDeps.discard(name) |
1943 if len(ignoredDeps) != 0: | 1945 if len(ignoredDeps) != 0: |
1944 candidates = set(); | 1946 candidates = set() |
1945 # Compute dependencies based on projects required by p | 1947 # Compute dependencies based on projects required by p |
1946 for d in sorted_deps(): | 1948 for d in sorted_deps(): |
1947 if not d.defined_java_packages().isdisjoint(p.imported_java_packages()): | 1949 if not d.defined_java_packages().isdisjoint(p.imported_java_packages()): |
1948 candidates.add(d) | 1950 candidates.add(d) |
1949 # Remove non-canonical candidates | 1951 # Remove non-canonical candidates |
1950 for c in list(candidates): | 1952 for c in list(candidates): |
1951 candidates.difference_update(c.all_deps([], False, False)) | 1953 candidates.difference_update(c.all_deps([], False, False)) |
1952 candidates = [d.name for d in candidates] | 1954 candidates = [d.name for d in candidates] |
1953 | 1955 |
1954 abort('{0}:{1}: {2} does not use any packages defined in these projects: {3}\nComputed project dependencies: {4}'.format( | 1956 abort('{0}:{1}: {2} does not use any packages defined in these projects: {3}\nComputed project dependencies: {4}'.format( |
1955 projectsFile, lineNo, p, ', '.join(ignoredDeps), ','.join(candidates))) | 1957 projectsFile, lineNo, p, ', '.join(ignoredDeps), ','.join(candidates))) |
1956 | 1958 |
1957 out.write('project@' + m.group(1) + '@dependencies=' + ','.join(p.canonical_deps()) + '\n') | 1959 out.write('project@' + m.group(1) + '@dependencies=' + ','.join(p.canonical_deps()) + '\n') |
1958 lineNo = lineNo + 1 | 1960 lineNo = lineNo + 1 |
1959 content = out.getvalue() | 1961 content = out.getvalue() |
1960 if update_file(projectsFile, content): | 1962 if update_file(projectsFile, content): |
1961 changedFiles += 1 | 1963 changedFiles += 1 |
1962 return changedFiles; | 1964 return changedFiles |
1963 | 1965 |
1964 def checkstyle(args): | 1966 def checkstyle(args): |
1965 """run Checkstyle on the Java sources | 1967 """run Checkstyle on the Java sources |
1966 | 1968 |
1967 Run Checkstyle over the Java sources. Any errors or warnings | 1969 Run Checkstyle over the Java sources. Any errors or warnings |
1969 | 1971 |
1970 parser = ArgumentParser(prog='mx checkstyle') | 1972 parser = ArgumentParser(prog='mx checkstyle') |
1971 | 1973 |
1972 parser.add_argument('-f', action='store_true', dest='force', help='force checking (disables timestamp checking)') | 1974 parser.add_argument('-f', action='store_true', dest='force', help='force checking (disables timestamp checking)') |
1973 args = parser.parse_args(args) | 1975 args = parser.parse_args(args) |
1974 | 1976 |
1975 totalErrors = 0 | 1977 totalErrors = 0 |
1976 for p in sorted_deps(): | 1978 for p in sorted_deps(): |
1977 if p.native: | 1979 if p.native: |
1978 continue | 1980 continue |
1979 sourceDirs = p.source_dirs() | 1981 sourceDirs = p.source_dirs() |
1980 dotCheckstyle = join(p.dir, '.checkstyle') | 1982 dotCheckstyle = join(p.dir, '.checkstyle') |
1981 | 1983 |
1982 if not exists(dotCheckstyle): | 1984 if not exists(dotCheckstyle): |
1983 continue | 1985 continue |
1984 | 1986 |
1985 # skip checking this Java project if its Java compliance level is "higher" than the configured JDK | 1987 # skip checking this Java project if its Java compliance level is "higher" than the configured JDK |
1986 if java().javaCompliance < p.javaCompliance: | 1988 if java().javaCompliance < p.javaCompliance: |
1987 log('Excluding {0} from checking (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) | 1989 log('Excluding {0} from checking (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) |
1988 continue | 1990 continue |
1989 | 1991 |
2072 try: | 2074 try: |
2073 run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + batch, nonZeroIsFatal=False) | 2075 run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + batch, nonZeroIsFatal=False) |
2074 finally: | 2076 finally: |
2075 if exists(auditfileName): | 2077 if exists(auditfileName): |
2076 errors = [] | 2078 errors = [] |
2077 source = None | 2079 source = [None] |
2078 def start_element(name, attrs): | 2080 def start_element(name, attrs): |
2079 if name == 'file': | 2081 if name == 'file': |
2080 global source | 2082 source[0] = attrs['name'] |
2081 source = attrs['name'] | |
2082 elif name == 'error': | 2083 elif name == 'error': |
2083 errors.append('{}:{}: {}'.format(source, attrs['line'], attrs['message'])) | 2084 errors.append('{}:{}: {}'.format(source[0], attrs['line'], attrs['message'])) |
2084 | 2085 |
2085 p = xml.parsers.expat.ParserCreate() | 2086 p = xml.parsers.expat.ParserCreate() |
2086 p.StartElementHandler = start_element | 2087 p.StartElementHandler = start_element |
2087 with open(auditfileName) as fp: | 2088 with open(auditfileName) as fp: |
2088 p.ParseFile(fp) | 2089 p.ParseFile(fp) |
2106 generated images. | 2107 generated images. |
2107 """ | 2108 """ |
2108 | 2109 |
2109 suppliedParser = parser is not None | 2110 suppliedParser = parser is not None |
2110 | 2111 |
2111 parser = parser if suppliedParser else ArgumentParser(prog='mx build'); | 2112 parser = parser if suppliedParser else ArgumentParser(prog='mx build') |
2112 parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects') | 2113 parser.add_argument('--no-native', action='store_false', dest='native', help='do not clean native projects') |
2113 parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects') | 2114 parser.add_argument('--no-java', action='store_false', dest='java', help='do not clean Java projects') |
2114 | 2115 |
2115 args = parser.parse_args(args) | 2116 args = parser.parse_args(args) |
2116 | 2117 |
2118 if p.native: | 2119 if p.native: |
2119 if args.native: | 2120 if args.native: |
2120 run([gmake_cmd(), '-C', p.dir, 'clean']) | 2121 run([gmake_cmd(), '-C', p.dir, 'clean']) |
2121 else: | 2122 else: |
2122 if args.java: | 2123 if args.java: |
2123 genDir = p.source_gen_dir(); | 2124 genDir = p.source_gen_dir() |
2124 if genDir != '' and exists(genDir): | 2125 if genDir != '' and exists(genDir): |
2125 log('Clearing {0}...'.format(genDir)) | 2126 log('Clearing {0}...'.format(genDir)) |
2126 for f in os.listdir(genDir): | 2127 for f in os.listdir(genDir): |
2127 shutil.rmtree(join(genDir, f)) | 2128 shutil.rmtree(join(genDir, f)) |
2128 | 2129 |
2129 | 2130 |
2130 outputDir = p.output_dir() | 2131 outputDir = p.output_dir() |
2131 if outputDir != '' and exists(outputDir): | 2132 if outputDir != '' and exists(outputDir): |
2132 log('Removing {0}...'.format(outputDir)) | 2133 log('Removing {0}...'.format(outputDir)) |
2133 shutil.rmtree(outputDir) | 2134 shutil.rmtree(outputDir) |
2134 | 2135 |
2148 if len(args) == 0: | 2149 if len(args) == 0: |
2149 _argParser.print_help() | 2150 _argParser.print_help() |
2150 return | 2151 return |
2151 | 2152 |
2152 name = args[0] | 2153 name = args[0] |
2153 if not commands.has_key(name): | 2154 if not _commands.has_key(name): |
2154 hits = [c for c in commands.iterkeys() if c.startswith(name)] | 2155 hits = [c for c in _commands.iterkeys() if c.startswith(name)] |
2155 if len(hits) == 1: | 2156 if len(hits) == 1: |
2156 name = hits[0] | 2157 name = hits[0] |
2157 elif len(hits) == 0: | 2158 elif len(hits) == 0: |
2158 abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(name, _format_commands())) | 2159 abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(name, _format_commands())) |
2159 else: | 2160 else: |
2160 abort('mx: command \'{0}\' is ambiguous\n {1}'.format(name, ' '.join(hits))) | 2161 abort('mx: command \'{0}\' is ambiguous\n {1}'.format(name, ' '.join(hits))) |
2161 | 2162 |
2162 value = commands[name] | 2163 value = _commands[name] |
2163 (func, usage) = value[:2] | 2164 (func, usage) = value[:2] |
2164 doc = func.__doc__ | 2165 doc = func.__doc__ |
2165 if len(value) > 2: | 2166 if len(value) > 2: |
2166 docArgs = value[2:] | 2167 docArgs = value[2:] |
2167 fmtArgs = [] | 2168 fmtArgs = [] |
2204 | 2205 |
2205 slm.close('sourceContainers') | 2206 slm.close('sourceContainers') |
2206 slm.close('sourceLookupDirector') | 2207 slm.close('sourceLookupDirector') |
2207 return slm | 2208 return slm |
2208 | 2209 |
2209 def make_eclipse_attach(hostname, port, name=None, deps=[]): | 2210 def make_eclipse_attach(hostname, port, name=None, deps=None): |
2210 """ | 2211 """ |
2211 Creates an Eclipse launch configuration file for attaching to a Java process. | 2212 Creates an Eclipse launch configuration file for attaching to a Java process. |
2212 """ | 2213 """ |
2214 if deps is None: | |
2215 deps = [] | |
2213 slm = _source_locator_memento(deps) | 2216 slm = _source_locator_memento(deps) |
2214 launch = XMLDoc() | 2217 launch = XMLDoc() |
2215 launch.open('launchConfiguration', {'type' : 'org.eclipse.jdt.launching.remoteJavaApplication'}) | 2218 launch.open('launchConfiguration', {'type' : 'org.eclipse.jdt.launching.remoteJavaApplication'}) |
2216 launch.element('stringAttribute', {'key' : 'org.eclipse.debug.core.source_locator_id', 'value' : 'org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector'}) | 2219 launch.element('stringAttribute', {'key' : 'org.eclipse.debug.core.source_locator_id', 'value' : 'org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector'}) |
2217 launch.element('stringAttribute', {'key' : 'org.eclipse.debug.core.source_locator_memento', 'value' : '%s'}) | 2220 launch.element('stringAttribute', {'key' : 'org.eclipse.debug.core.source_locator_memento', 'value' : '%s'}) |
2230 eclipseLaunches = join('mx', 'eclipse-launches') | 2233 eclipseLaunches = join('mx', 'eclipse-launches') |
2231 if not exists(eclipseLaunches): | 2234 if not exists(eclipseLaunches): |
2232 os.makedirs(eclipseLaunches) | 2235 os.makedirs(eclipseLaunches) |
2233 return update_file(join(eclipseLaunches, name + '.launch'), launch) | 2236 return update_file(join(eclipseLaunches, name + '.launch'), launch) |
2234 | 2237 |
2235 def make_eclipse_launch(javaArgs, jre, name=None, deps=[]): | 2238 def make_eclipse_launch(javaArgs, jre, name=None, deps=None): |
2236 """ | 2239 """ |
2237 Creates an Eclipse launch configuration file for running/debugging a Java command. | 2240 Creates an Eclipse launch configuration file for running/debugging a Java command. |
2238 """ | 2241 """ |
2242 if deps is None: | |
2243 deps = [] | |
2239 mainClass = None | 2244 mainClass = None |
2240 vmArgs = [] | 2245 vmArgs = [] |
2241 appArgs = [] | 2246 appArgs = [] |
2242 cp = None | 2247 cp = None |
2243 argsCopy = list(reversed(javaArgs)) | 2248 argsCopy = list(reversed(javaArgs)) |
2300 def eclipseinit(args, suite=None, buildProcessorJars=True): | 2305 def eclipseinit(args, suite=None, buildProcessorJars=True): |
2301 """(re)generate Eclipse project configurations and working sets""" | 2306 """(re)generate Eclipse project configurations and working sets""" |
2302 | 2307 |
2303 if suite is None: | 2308 if suite is None: |
2304 suite = _mainSuite | 2309 suite = _mainSuite |
2305 | 2310 |
2306 if buildProcessorJars: | 2311 if buildProcessorJars: |
2307 processorjars() | 2312 processorjars() |
2308 | 2313 |
2309 projToDist = dict() | 2314 projToDist = dict() |
2310 for dist in _dists.values(): | 2315 for dist in _dists.values(): |
2327 if not exists(srcDir): | 2332 if not exists(srcDir): |
2328 os.mkdir(srcDir) | 2333 os.mkdir(srcDir) |
2329 out.element('classpathentry', {'kind' : 'src', 'path' : src}) | 2334 out.element('classpathentry', {'kind' : 'src', 'path' : src}) |
2330 | 2335 |
2331 if len(p.annotation_processors()) > 0: | 2336 if len(p.annotation_processors()) > 0: |
2332 genDir = p.source_gen_dir(); | 2337 genDir = p.source_gen_dir() |
2333 if not exists(genDir): | 2338 if not exists(genDir): |
2334 os.mkdir(genDir) | 2339 os.mkdir(genDir) |
2335 out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) | 2340 out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) |
2336 | 2341 |
2337 # Every Java program depends on the JRE | 2342 # Every Java program depends on the JRE |
2338 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}) | 2343 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}) |
2339 | 2344 |
2340 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 2345 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
2341 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) | 2346 out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) |
2342 | 2347 |
2343 for dep in p.all_deps([], True): | 2348 for dep in p.all_deps([], True): |
2344 if dep == p: | 2349 if dep == p: |
2345 continue; | 2350 continue |
2346 | 2351 |
2347 if dep.isLibrary(): | 2352 if dep.isLibrary(): |
2348 if hasattr(dep, 'eclipse.container'): | 2353 if hasattr(dep, 'eclipse.container'): |
2349 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) | 2354 out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : getattr(dep, 'eclipse.container')}) |
2350 elif hasattr(dep, 'eclipse.project'): | 2355 elif hasattr(dep, 'eclipse.project'): |
2417 if exists(csConfig): | 2422 if exists(csConfig): |
2418 out.open('buildCommand') | 2423 out.open('buildCommand') |
2419 out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') | 2424 out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') |
2420 out.element('arguments', data='') | 2425 out.element('arguments', data='') |
2421 out.close('buildCommand') | 2426 out.close('buildCommand') |
2422 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 2427 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
2423 for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: | 2428 for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: |
2424 out.open('buildCommand') | 2429 out.open('buildCommand') |
2425 out.element('name', data=buildCommand) | 2430 out.element('name', data=buildCommand) |
2426 out.element('arguments', data='') | 2431 out.element('arguments', data='') |
2427 out.close('buildCommand') | 2432 out.close('buildCommand') |
2428 | 2433 |
2429 if _isAnnotationProcessorDependency(p): | 2434 if _isAnnotationProcessorDependency(p): |
2430 _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False, xmlIndent='', xmlStandalone='no') | 2435 _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no') |
2431 _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh = True, async = True) | 2436 _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True) |
2432 | 2437 |
2433 if projToDist.has_key(p.name): | 2438 if projToDist.has_key(p.name): |
2434 dist, distDeps = projToDist[p.name] | 2439 dist, distDeps = projToDist[p.name] |
2435 _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True) | 2440 _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True) |
2436 | 2441 |
2437 out.close('buildSpec') | 2442 out.close('buildSpec') |
2438 out.open('natures') | 2443 out.open('natures') |
2439 out.element('nature', data='org.eclipse.jdt.core.javanature') | 2444 out.element('nature', data='org.eclipse.jdt.core.javanature') |
2440 if exists(csConfig): | 2445 if exists(csConfig): |
2441 out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') | 2446 out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') |
2442 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 2447 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
2443 out.element('nature', data='org.eclipse.pde.PluginNature') | 2448 out.element('nature', data='org.eclipse.pde.PluginNature') |
2444 out.close('natures') | 2449 out.close('natures') |
2445 out.close('projectDescription') | 2450 out.close('projectDescription') |
2446 update_file(join(p.dir, '.project'), out.xml(indent='\t', newl='\n')) | 2451 update_file(join(p.dir, '.project'), out.xml(indent='\t', newl='\n')) |
2447 | 2452 |
2460 content = f.read() | 2465 content = f.read() |
2461 content = content.replace('${javaCompliance}', str(p.javaCompliance)) | 2466 content = content.replace('${javaCompliance}', str(p.javaCompliance)) |
2462 if len(p.annotation_processors()) > 0: | 2467 if len(p.annotation_processors()) > 0: |
2463 content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') | 2468 content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') |
2464 update_file(join(settingsDir, name), content) | 2469 update_file(join(settingsDir, name), content) |
2465 | 2470 |
2466 if len(p.annotation_processors()) > 0: | 2471 if len(p.annotation_processors()) > 0: |
2467 out = XMLDoc() | 2472 out = XMLDoc() |
2468 out.open('factorypath') | 2473 out.open('factorypath') |
2469 out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) | 2474 out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) |
2470 for ap in p.annotation_processors(): | 2475 for ap in p.annotation_processors(): |
2493 Determines if a given project is part of an annotation processor. | 2498 Determines if a given project is part of an annotation processor. |
2494 """ | 2499 """ |
2495 return p in sorted_deps(annotation_processors()) | 2500 return p in sorted_deps(annotation_processors()) |
2496 | 2501 |
2497 def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None): | 2502 def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None): |
2498 launchOut = XMLDoc(); | 2503 launchOut = XMLDoc() |
2499 consoleOn = 'true' if logToConsole else 'false' | 2504 consoleOn = 'true' if logToConsole else 'false' |
2500 launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) | 2505 launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) |
2501 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) | 2506 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) |
2502 launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'}) | 2507 launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'}) |
2503 launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk}) | 2508 launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk}) |
2504 launchOut.close('mapAttribute') | 2509 launchOut.close('mapAttribute') |
2505 | 2510 |
2506 if refresh: | 2511 if refresh: |
2507 launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) | 2512 launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) |
2508 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': consoleOn}) | 2513 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': consoleOn}) |
2509 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true' if async else 'false'}) | 2514 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true' if async else 'false'}) |
2510 | 2515 |
2511 baseDir = dirname(dirname(os.path.abspath(__file__))) | 2516 baseDir = dirname(dirname(os.path.abspath(__file__))) |
2512 | 2517 |
2513 cmd = 'mx.sh' | 2518 cmd = 'mx.sh' |
2514 if get_os() == 'windows': | 2519 if get_os() == 'windows': |
2515 cmd = 'mx.cmd' | 2520 cmd = 'mx.cmd' |
2516 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': join(baseDir, cmd) }) | 2521 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': join(baseDir, cmd) }) |
2517 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'}) | 2522 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'}) |
2518 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': mxCommand}) | 2523 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': mxCommand}) |
2519 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED','value': 'true'}) | 2524 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'}) |
2520 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': p.suite.dir}) | 2525 launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': p.suite.dir}) |
2521 | 2526 |
2522 | 2527 |
2523 launchOut.close('launchConfiguration') | 2528 launchOut.close('launchConfiguration') |
2524 | 2529 |
2525 externalToolDir = join(p.dir, '.externalToolBuilders') | 2530 externalToolDir = join(p.dir, '.externalToolBuilders') |
2526 | 2531 |
2527 if not exists(externalToolDir): | 2532 if not exists(externalToolDir): |
2528 os.makedirs(externalToolDir) | 2533 os.makedirs(externalToolDir) |
2529 update_file(join(externalToolDir, name), launchOut.xml(indent=xmlIndent, standalone=xmlStandalone, newl='\n')) | 2534 update_file(join(externalToolDir, name), launchOut.xml(indent=xmlIndent, standalone=xmlStandalone, newl='\n')) |
2530 | 2535 |
2531 dotProjectDoc.open('buildCommand') | 2536 dotProjectDoc.open('buildCommand') |
2532 dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') | 2537 dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') |
2533 dotProjectDoc.element('triggers', data='auto,full,incremental,') | 2538 dotProjectDoc.element('triggers', data='auto,full,incremental,') |
2534 dotProjectDoc.open('arguments') | 2539 dotProjectDoc.open('arguments') |
2535 dotProjectDoc.open('dictionary') | 2540 dotProjectDoc.open('dictionary') |
2536 dotProjectDoc.element('key', data = 'LaunchConfigHandle') | 2541 dotProjectDoc.element('key', data='LaunchConfigHandle') |
2537 dotProjectDoc.element('value', data = '<project>/.externalToolBuilders/' + name) | 2542 dotProjectDoc.element('value', data='<project>/.externalToolBuilders/' + name) |
2538 dotProjectDoc.close('dictionary') | 2543 dotProjectDoc.close('dictionary') |
2539 dotProjectDoc.open('dictionary') | 2544 dotProjectDoc.open('dictionary') |
2540 dotProjectDoc.element('key', data = 'incclean') | 2545 dotProjectDoc.element('key', data='incclean') |
2541 dotProjectDoc.element('value', data = 'true') | 2546 dotProjectDoc.element('value', data='true') |
2542 dotProjectDoc.close('dictionary') | 2547 dotProjectDoc.close('dictionary') |
2543 dotProjectDoc.close('arguments') | 2548 dotProjectDoc.close('arguments') |
2544 dotProjectDoc.close('buildCommand') | 2549 dotProjectDoc.close('buildCommand') |
2545 | 2550 |
2546 def generate_eclipse_workingsets(suite): | 2551 def generate_eclipse_workingsets(suite): |
2547 """ | 2552 """ |
2548 Populate the workspace's working set configuration with working sets generated from project data. | 2553 Populate the workspace's working set configuration with working sets generated from project data. |
2549 If the workspace already contains working set definitions, the existing ones will be retained and extended. | 2554 If the workspace already contains working set definitions, the existing ones will be retained and extended. |
2550 In case mx/env does not contain a WORKSPACE definition pointing to the workspace root directory, the Graal project root directory will be assumed. | 2555 In case mx/env does not contain a WORKSPACE definition pointing to the workspace root directory, the Graal project root directory will be assumed. |
2551 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. | 2556 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. |
2552 """ | 2557 """ |
2553 | 2558 |
2554 # identify the location where to look for workingsets.xml | 2559 # identify the location where to look for workingsets.xml |
2555 wsfilename = 'workingsets.xml' | 2560 wsfilename = 'workingsets.xml' |
2556 wsroot = suite.dir | 2561 wsroot = suite.dir |
2557 if os.environ.has_key('WORKSPACE'): | 2562 if os.environ.has_key('WORKSPACE'): |
2558 wsroot = os.environ['WORKSPACE'] | 2563 wsroot = os.environ['WORKSPACE'] |
2559 wsdir = join(wsroot, '.metadata/.plugins/org.eclipse.ui.workbench') | 2564 wsdir = join(wsroot, '.metadata/.plugins/org.eclipse.ui.workbench') |
2560 if not exists(wsdir): | 2565 if not exists(wsdir): |
2561 wsdir = wsroot | 2566 wsdir = wsroot |
2562 wspath = join(wsdir, wsfilename) | 2567 wspath = join(wsdir, wsfilename) |
2563 | 2568 |
2564 # gather working set info from project data | 2569 # gather working set info from project data |
2565 workingSets = dict() | 2570 workingSets = dict() |
2566 for p in projects(): | 2571 for p in projects(): |
2567 if p.workingSets is None: | 2572 if p.workingSets is None: |
2568 continue | 2573 continue |
2569 for w in p.workingSets.split(","): | 2574 for w in p.workingSets.split(","): |
2570 if not workingSets.has_key(w): | 2575 if not workingSets.has_key(w): |
2571 workingSets[w] = [p.name] | 2576 workingSets[w] = [p.name] |
2572 else: | 2577 else: |
2573 workingSets[w].append(p.name) | 2578 workingSets[w].append(p.name) |
2574 | 2579 |
2575 if exists(wspath): | 2580 if exists(wspath): |
2576 wsdoc = _copy_workingset_xml(wspath, workingSets) | 2581 wsdoc = _copy_workingset_xml(wspath, workingSets) |
2577 else: | 2582 else: |
2578 wsdoc = _make_workingset_xml(workingSets) | 2583 wsdoc = _make_workingset_xml(workingSets) |
2579 | 2584 |
2580 update_file(wspath, wsdoc.xml(newl='\n')) | 2585 update_file(wspath, wsdoc.xml(newl='\n')) |
2581 | 2586 |
2582 def _make_workingset_xml(workingSets): | 2587 def _make_workingset_xml(workingSets): |
2583 wsdoc = XMLDoc() | 2588 wsdoc = XMLDoc() |
2584 wsdoc.open('workingSetManager') | 2589 wsdoc.open('workingSetManager') |
2585 | 2590 |
2586 for w in sorted(workingSets.keys()): | 2591 for w in sorted(workingSets.keys()): |
2587 _workingset_open(wsdoc, w) | 2592 _workingset_open(wsdoc, w) |
2588 for p in workingSets[w]: | 2593 for p in workingSets[w]: |
2589 _workingset_element(wsdoc, p) | 2594 _workingset_element(wsdoc, p) |
2590 wsdoc.close('workingSet') | 2595 wsdoc.close('workingSet') |
2591 | 2596 |
2592 wsdoc.close('workingSetManager') | 2597 wsdoc.close('workingSetManager') |
2593 return wsdoc | 2598 return wsdoc |
2594 | 2599 |
2595 def _copy_workingset_xml(wspath, workingSets): | 2600 def _copy_workingset_xml(wspath, workingSets): |
2596 target = XMLDoc() | 2601 target = XMLDoc() |
2597 target.open('workingSetManager') | 2602 target.open('workingSetManager') |
2598 | 2603 |
2599 parser = xml.parsers.expat.ParserCreate() | 2604 parser = xml.parsers.expat.ParserCreate() |
2600 | 2605 |
2601 class ParserState(object): | 2606 class ParserState(object): |
2602 def __init__(self): | 2607 def __init__(self): |
2603 self.current_ws_name = 'none yet' | 2608 self.current_ws_name = 'none yet' |
2604 self.current_ws = None | 2609 self.current_ws = None |
2605 self.seen_ws = list() | 2610 self.seen_ws = list() |
2606 self.seen_projects = list() | 2611 self.seen_projects = list() |
2607 | 2612 |
2608 ps = ParserState() | 2613 ps = ParserState() |
2609 | 2614 |
2610 # parsing logic | 2615 # parsing logic |
2611 def _ws_start(name, attributes): | 2616 def _ws_start(name, attributes): |
2612 if name == 'workingSet': | 2617 if name == 'workingSet': |
2613 ps.current_ws_name = attributes['name'] | 2618 ps.current_ws_name = attributes['name'] |
2614 if workingSets.has_key(ps.current_ws_name): | 2619 if workingSets.has_key(ps.current_ws_name): |
2617 ps.seen_projects = list() | 2622 ps.seen_projects = list() |
2618 else: | 2623 else: |
2619 ps.current_ws = None | 2624 ps.current_ws = None |
2620 target.open(name, attributes) | 2625 target.open(name, attributes) |
2621 parser.StartElementHandler = _ws_item | 2626 parser.StartElementHandler = _ws_item |
2622 | 2627 |
2623 def _ws_end(name): | 2628 def _ws_end(name): |
2624 if name == 'workingSet': | 2629 if name == 'workingSet': |
2625 if not ps.current_ws is None: | 2630 if not ps.current_ws is None: |
2626 for p in ps.current_ws: | 2631 for p in ps.current_ws: |
2627 if not p in ps.seen_projects: | 2632 if not p in ps.seen_projects: |
2634 if not w in ps.seen_ws: | 2639 if not w in ps.seen_ws: |
2635 _workingset_open(target, w) | 2640 _workingset_open(target, w) |
2636 for p in workingSets[w]: | 2641 for p in workingSets[w]: |
2637 _workingset_element(target, p) | 2642 _workingset_element(target, p) |
2638 target.close('workingSet') | 2643 target.close('workingSet') |
2639 | 2644 |
2640 def _ws_item(name, attributes): | 2645 def _ws_item(name, attributes): |
2641 if name == 'item': | 2646 if name == 'item': |
2642 if ps.current_ws is None: | 2647 if ps.current_ws is None: |
2643 target.element(name, attributes) | 2648 target.element(name, attributes) |
2644 else: | 2649 else: |
2645 p_name = attributes['elementID'][1:] # strip off the leading '=' | 2650 p_name = attributes['elementID'][1:] # strip off the leading '=' |
2646 _workingset_element(target, p_name) | 2651 _workingset_element(target, p_name) |
2647 ps.seen_projects.append(p_name) | 2652 ps.seen_projects.append(p_name) |
2648 | 2653 |
2649 # process document | 2654 # process document |
2650 parser.StartElementHandler = _ws_start | 2655 parser.StartElementHandler = _ws_start |
2651 parser.EndElementHandler = _ws_end | 2656 parser.EndElementHandler = _ws_end |
2652 with open(wspath, 'r') as wsfile: | 2657 with open(wspath, 'r') as wsfile: |
2653 parser.ParseFile(wsfile) | 2658 parser.ParseFile(wsfile) |
2654 | 2659 |
2655 target.close('workingSetManager') | 2660 target.close('workingSetManager') |
2656 return target | 2661 return target |
2657 | 2662 |
2658 def _workingset_open(wsdoc, ws): | 2663 def _workingset_open(wsdoc, ws): |
2659 wsdoc.open('workingSet', {'editPageID': 'org.eclipse.jdt.ui.JavaWorkingSetPage', 'factoryID': 'org.eclipse.ui.internal.WorkingSetFactory', 'id': 'wsid_' + ws, 'label': ws, 'name': ws}) | 2664 wsdoc.open('workingSet', {'editPageID': 'org.eclipse.jdt.ui.JavaWorkingSetPage', 'factoryID': 'org.eclipse.ui.internal.WorkingSetFactory', 'id': 'wsid_' + ws, 'label': ws, 'name': ws}) |
2660 | 2665 |
2661 def _workingset_element(wsdoc, p): | 2666 def _workingset_element(wsdoc, p): |
2662 wsdoc.element('item', {'elementID': '=' + p, 'factoryID': 'org.eclipse.jdt.ui.PersistableJavaElementFactory'}) | 2667 wsdoc.element('item', {'elementID': '=' + p, 'factoryID': 'org.eclipse.jdt.ui.PersistableJavaElementFactory'}) |
2663 | 2668 |
2664 def netbeansinit(args, suite=None): | 2669 def netbeansinit(args, suite=None): |
2665 """(re)generate NetBeans project configurations""" | 2670 """(re)generate NetBeans project configurations""" |
2666 | 2671 |
2667 if suite is None: | 2672 if suite is None: |
2668 suite = _mainSuite | 2673 suite = _mainSuite |
2669 | |
2670 def println(out, obj): | |
2671 out.write(str(obj) + '\n') | |
2672 | 2674 |
2673 updated = False | 2675 updated = False |
2674 for p in projects(): | 2676 for p in projects(): |
2675 if p.native: | 2677 if p.native: |
2676 continue | 2678 continue |
2677 | 2679 |
2678 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project | 2680 if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project |
2679 continue | 2681 continue |
2680 | 2682 |
2681 if not exists(join(p.dir, 'nbproject')): | 2683 if not exists(join(p.dir, 'nbproject')): |
2682 os.makedirs(join(p.dir, 'nbproject')) | 2684 os.makedirs(join(p.dir, 'nbproject')) |
2683 | 2685 |
2713 out.close('data') | 2715 out.close('data') |
2714 | 2716 |
2715 firstDep = True | 2717 firstDep = True |
2716 for dep in p.all_deps([], True): | 2718 for dep in p.all_deps([], True): |
2717 if dep == p: | 2719 if dep == p: |
2718 continue; | 2720 continue |
2719 | 2721 |
2720 if not dep.isLibrary(): | 2722 if not dep.isLibrary(): |
2721 n = dep.name.replace('.', '_') | 2723 n = dep.name.replace('.', '_') |
2722 if firstDep: | 2724 if firstDep: |
2723 out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'}) | 2725 out.open('references', {'xmlns' : 'http://www.netbeans.org/ns/ant-project-references/1'}) |
2832 mainSrc = False | 2834 mainSrc = False |
2833 else: | 2835 else: |
2834 print >> out, 'src.' + src + '.dir=${' + ref + '}' | 2836 print >> out, 'src.' + src + '.dir=${' + ref + '}' |
2835 | 2837 |
2836 javacClasspath = [] | 2838 javacClasspath = [] |
2837 | 2839 |
2838 deps = p.all_deps([], True) | 2840 deps = p.all_deps([], True) |
2839 annotationProcessorOnlyDeps = [] | 2841 annotationProcessorOnlyDeps = [] |
2840 if len(p.annotation_processors()) > 0: | 2842 if len(p.annotation_processors()) > 0: |
2841 for ap in p.annotation_processors(): | 2843 for ap in p.annotation_processors(): |
2842 apDep = dependency(ap) | 2844 apDep = dependency(ap) |
2843 if not apDep in deps: | 2845 if not apDep in deps: |
2844 deps.append(apDep) | 2846 deps.append(apDep) |
2845 annotationProcessorOnlyDeps.append(apDep) | 2847 annotationProcessorOnlyDeps.append(apDep) |
2846 | 2848 |
2847 annotationProcessorReferences = []; | 2849 annotationProcessorReferences = [] |
2848 | 2850 |
2849 for dep in deps: | 2851 for dep in deps: |
2850 if dep == p: | 2852 if dep == p: |
2851 continue; | 2853 continue |
2852 | 2854 |
2853 if dep.isLibrary(): | 2855 if dep.isLibrary(): |
2854 if not dep.mustExist: | 2856 if not dep.mustExist: |
2855 continue | 2857 continue |
2856 path = dep.get_path(resolve=True) | 2858 path = dep.get_path(resolve=True) |
2868 | 2870 |
2869 if not dep in annotationProcessorOnlyDeps: | 2871 if not dep in annotationProcessorOnlyDeps: |
2870 javacClasspath.append('${' + ref + '}') | 2872 javacClasspath.append('${' + ref + '}') |
2871 else: | 2873 else: |
2872 annotationProcessorReferences.append('${' + ref + '}') | 2874 annotationProcessorReferences.append('${' + ref + '}') |
2873 annotationProcessorReferences += ":\\\n ${" + ref + "}" | 2875 annotationProcessorReferences += ":\\\n ${" + ref + "}" |
2874 | 2876 |
2875 print >> out, 'javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath) | 2877 print >> out, 'javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath) |
2876 print >> out, 'javac.test.processorpath=${javac.test.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) | 2878 print >> out, 'javac.test.processorpath=${javac.test.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) |
2877 print >> out, 'javac.processorpath=${javac.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) | 2879 print >> out, 'javac.processorpath=${javac.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) |
2878 | 2880 |
2879 updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated | 2881 updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated |
2880 out.close() | 2882 out.close() |
2881 | 2883 |
2882 if updated: | 2884 if updated: |
2883 log('If using NetBeans:') | 2885 log('If using NetBeans:') |
2904 rm(join(p.dir, 'eclipse-build.xml')) | 2906 rm(join(p.dir, 'eclipse-build.xml')) |
2905 try: | 2907 try: |
2906 rm(join(p.dir, p.name + '.jar')) | 2908 rm(join(p.dir, p.name + '.jar')) |
2907 except: | 2909 except: |
2908 log("Error removing {0}".format(p.name + '.jar')) | 2910 log("Error removing {0}".format(p.name + '.jar')) |
2909 | 2911 |
2910 | 2912 |
2911 def ideinit(args, suite=None): | 2913 def ideinit(args, suite=None): |
2912 """(re)generate Eclipse and NetBeans project configurations""" | 2914 """(re)generate Eclipse and NetBeans project configurations""" |
2913 eclipseinit(args, suite) | 2915 eclipseinit(args, suite) |
2914 netbeansinit(args, suite) | 2916 netbeansinit(args, suite) |
2987 assess_candidate(d, projects) | 2989 assess_candidate(d, projects) |
2988 if not assess_candidate(p, projects): | 2990 if not assess_candidate(p, projects): |
2989 logv('[package-list file exists - skipping {0}]'.format(p.name)) | 2991 logv('[package-list file exists - skipping {0}]'.format(p.name)) |
2990 | 2992 |
2991 | 2993 |
2992 def find_packages(sourceDirs, pkgs=set()): | 2994 def find_packages(sourceDirs, pkgs=None): |
2995 if pkgs is None: | |
2996 pkgs = set() | |
2993 for sourceDir in sourceDirs: | 2997 for sourceDir in sourceDirs: |
2994 for root, _, files in os.walk(sourceDir): | 2998 for root, _, files in os.walk(sourceDir): |
2995 if len([name for name in files if name.endswith('.java')]) != 0: | 2999 if len([name for name in files if name.endswith('.java')]) != 0: |
2996 pkg = root[len(sourceDir) + 1:].replace(os.sep,'.') | 3000 pkg = root[len(sourceDir) + 1:].replace(os.sep, '.') |
2997 if len(packages) == 0 or pkg in packages: | 3001 if len(packages) == 0 or pkg in packages: |
2998 if len(exclude_packages) == 0 or not pkg in exclude_packages: | 3002 if len(exclude_packages) == 0 or not pkg in exclude_packages: |
2999 pkgs.add(pkg) | 3003 pkgs.add(pkg) |
3000 return pkgs | 3004 return pkgs |
3001 | 3005 |
3009 | 3013 |
3010 if not args.unified: | 3014 if not args.unified: |
3011 for p in projects: | 3015 for p in projects: |
3012 # The project must be built to ensure javadoc can find class files for all referenced classes | 3016 # The project must be built to ensure javadoc can find class files for all referenced classes |
3013 build(['--no-native', '--projects', p.name]) | 3017 build(['--no-native', '--projects', p.name]) |
3014 | 3018 |
3015 pkgs = find_packages(p.source_dirs(), set()) | 3019 pkgs = find_packages(p.source_dirs(), set()) |
3016 deps = p.all_deps([], includeLibs=False, includeSelf=False) | 3020 deps = p.all_deps([], includeLibs=False, includeSelf=False) |
3017 links = ['-link', 'http://docs.oracle.com/javase/' + str(p.javaCompliance.value) + '/docs/api/'] | 3021 links = ['-link', 'http://docs.oracle.com/javase/' + str(p.javaCompliance.value) + '/docs/api/'] |
3018 out = outDir(p) | 3022 out = outDir(p) |
3019 for d in deps: | 3023 for d in deps: |
3047 list(pkgs)) | 3051 list(pkgs)) |
3048 log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) | 3052 log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) |
3049 finally: | 3053 finally: |
3050 if delOverviewFile: | 3054 if delOverviewFile: |
3051 os.remove(overviewFile) | 3055 os.remove(overviewFile) |
3052 | 3056 |
3053 else: | 3057 else: |
3054 # The projects must be built to ensure javadoc can find class files for all referenced classes | 3058 # The projects must be built to ensure javadoc can find class files for all referenced classes |
3055 build(['--no-native']) | 3059 build(['--no-native']) |
3056 | 3060 |
3057 pkgs = set() | 3061 pkgs = set() |
3058 sp = [] | 3062 sp = [] |
3059 names = [] | 3063 names = [] |
3060 for p in projects: | 3064 for p in projects: |
3061 find_packages(p.source_dirs(), pkgs) | 3065 find_packages(p.source_dirs(), pkgs) |
3105 else: | 3109 else: |
3106 rindex = lindex + len(self.ldelim) | 3110 rindex = lindex + len(self.ldelim) |
3107 rdelimLen = 0 | 3111 rdelimLen = 0 |
3108 old = content[lindex:rindex + rdelimLen] | 3112 old = content[lindex:rindex + rdelimLen] |
3109 return content.replace(old, repl) | 3113 return content.replace(old, repl) |
3110 | 3114 |
3111 # Post-process an overview-summary.html file to move the | 3115 # Post-process an overview-summary.html file to move the |
3112 # complete overview to the top of the page | 3116 # complete overview to the top of the page |
3113 def _fix_overview_summary(path, topLink): | 3117 def _fix_overview_summary(path, topLink): |
3114 """ | 3118 """ |
3115 Processes an "overview-summary.html" generated by javadoc to put the complete | 3119 Processes an "overview-summary.html" generated by javadoc to put the complete |
3137 <!-- ======= START OF BOTTOM NAVBAR ====== -->""") | 3141 <!-- ======= START OF BOTTOM NAVBAR ====== -->""") |
3138 | 3142 |
3139 assert chunk1.text, 'Could not find header section in ' + path | 3143 assert chunk1.text, 'Could not find header section in ' + path |
3140 assert chunk2.text, 'Could not find footer section in ' + path | 3144 assert chunk2.text, 'Could not find footer section in ' + path |
3141 | 3145 |
3142 content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text +'</div></div></div>') | 3146 content = chunk1.replace(content, '<div class="header"><div class="subTitle"><div class="block">' + topLink + chunk2.text + '</div></div></div>') |
3143 content = chunk2.replace(content, '') | 3147 content = chunk2.replace(content, '') |
3144 | 3148 |
3145 with open(path, 'w') as fp: | 3149 with open(path, 'w') as fp: |
3146 fp.write(content) | 3150 fp.write(content) |
3147 | 3151 |
3169 <!-- ======= START OF BOTTOM NAVBAR ====== -->""") | 3173 <!-- ======= START OF BOTTOM NAVBAR ====== -->""") |
3170 | 3174 |
3171 if chunk1.text: | 3175 if chunk1.text: |
3172 if chunk2.text: | 3176 if chunk2.text: |
3173 repl = re.sub(r'<h2 title=(.*) Description</h2>', r'<h1 title=\1</h1>', chunk2.text, 1) | 3177 repl = re.sub(r'<h2 title=(.*) Description</h2>', r'<h1 title=\1</h1>', chunk2.text, 1) |
3174 content = chunk1.replace(content, '<div class="header">' + repl +'</div></div>') | 3178 content = chunk1.replace(content, '<div class="header">' + repl + '</div></div>') |
3175 content = chunk2.replace(content, '') | 3179 content = chunk2.replace(content, '') |
3176 | 3180 |
3177 with open(path, 'w') as fp: | 3181 with open(path, 'w') as fp: |
3178 fp.write(content) | 3182 fp.write(content) |
3179 else: | 3183 else: |
3180 log('warning: Could not find package description detail section in ' + path) | 3184 log('warning: Could not find package description detail section in ' + path) |
3181 | 3185 |
3233 <caption><span>Projects</span><span class="tabEnd"> </span></caption> | 3237 <caption><span>Projects</span><span class="tabEnd"> </span></caption> |
3234 <tr><th class="colFirst" scope="col">Project</th><th class="colLast" scope="col"> </th></tr> | 3238 <tr><th class="colFirst" scope="col">Project</th><th class="colLast" scope="col"> </th></tr> |
3235 <tbody>""" | 3239 <tbody>""" |
3236 color = 'row' | 3240 color = 'row' |
3237 for p in projects: | 3241 for p in projects: |
3238 print >> fp2, '<tr class="{1}Color"><td class="colFirst"><a href="../{0}/javadoc/index.html", target = "_top">{0}</a></td><td class="colLast"> </td></tr>'.format(p.name, color) | 3242 print >> fp2, '<tr class="{1}Color"><td class="colFirst"><a href="../{0}/javadoc/index.html",target = "_top">{0}</a></td><td class="colLast"> </td></tr>'.format(p.name, color) |
3239 color = 'row' if color == 'alt' else 'alt' | 3243 color = 'row' if color == 'alt' else 'alt' |
3240 | 3244 |
3241 print >> fp2, '</tbody></table></div>' | 3245 print >> fp2, '</tbody></table></div>' |
3242 print >> fp2, content[idx:] | 3246 print >> fp2, content[idx:] |
3243 | 3247 |
3244 title = args.title if args.title is not None else args.name | 3248 title = args.title if args.title is not None else args.name |
3245 javadoc(['--base', tmpbase, | 3249 javadoc(['--base', tmpbase, |
3246 '--unified', | 3250 '--unified', |
3247 '--arg', '@-windowtitle', '--arg', '@' + title, | 3251 '--arg', '@-windowtitle', '--arg', '@' + title, |
3248 '--arg', '@-doctitle', '--arg', '@' + title, | 3252 '--arg', '@-doctitle', '--arg', '@' + title, |
3254 dotErr = None | 3258 dotErr = None |
3255 try: | 3259 try: |
3256 if not 'version' in subprocess.check_output(['dot', '-V'], stderr=subprocess.STDOUT): | 3260 if not 'version' in subprocess.check_output(['dot', '-V'], stderr=subprocess.STDOUT): |
3257 dotErr = 'dot -V does not print a string containing "version"' | 3261 dotErr = 'dot -V does not print a string containing "version"' |
3258 except subprocess.CalledProcessError as e: | 3262 except subprocess.CalledProcessError as e: |
3259 dotErr = 'error calling "dot -V": {}'.format(e) | 3263 dotErr = 'error calling "dot -V": {}'.format(e) |
3260 except OSError as e: | 3264 except OSError as e: |
3261 dotErr = 'error calling "dot -V": {}'.format(e) | 3265 dotErr = 'error calling "dot -V": {}'.format(e) |
3262 | 3266 |
3263 if dotErr != None: | 3267 if dotErr != None: |
3264 abort('cannot generate dependency graph: ' + dotErr) | 3268 abort('cannot generate dependency graph: ' + dotErr) |
3265 | 3269 |
3266 dot = join(tmpbase, 'all', str(args.dot_output_base) + '.dot') | 3270 dot = join(tmpbase, 'all', str(args.dot_output_base) + '.dot') |
3267 svg = join(tmpbase, 'all', str(args.dot_output_base) + '.svg') | 3271 svg = join(tmpbase, 'all', str(args.dot_output_base) + '.svg') |
3271 dim = len(projects) | 3275 dim = len(projects) |
3272 print >> fp, 'digraph projects {' | 3276 print >> fp, 'digraph projects {' |
3273 print >> fp, 'rankdir=BT;' | 3277 print >> fp, 'rankdir=BT;' |
3274 print >> fp, 'size = "' + str(dim) + ',' + str(dim) + '";' | 3278 print >> fp, 'size = "' + str(dim) + ',' + str(dim) + '";' |
3275 print >> fp, 'node [shape=rect, fontcolor="blue"];' | 3279 print >> fp, 'node [shape=rect, fontcolor="blue"];' |
3276 #print >> fp, 'edge [color="green"];' | 3280 # print >> fp, 'edge [color="green"];' |
3277 for p in projects: | 3281 for p in projects: |
3278 print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]' | 3282 print >> fp, '"' + p.name + '" [URL = "../' + p.name + '/javadoc/index.html", target = "_top"]' |
3279 for dep in p.canonical_deps(): | 3283 for dep in p.canonical_deps(): |
3280 if dep in [proj.name for proj in projects]: | 3284 if dep in [proj.name for proj in projects]: |
3281 print >> fp, '"' + p.name + '" -> "' + dep + '"' | 3285 print >> fp, '"' + p.name + '" -> "' + dep + '"' |
3282 depths = dict() | 3286 depths = dict() |
3283 for p in projects: | 3287 for p in projects: |
3284 d = p.max_depth() | 3288 d = p.max_depth() |
3285 depths.setdefault(d, list()).append(p.name) | 3289 depths.setdefault(d, list()).append(p.name) |
3286 print >> fp, '}' | 3290 print >> fp, '}' |
3287 | 3291 |
3288 run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, dot]) | 3292 run(['dot', '-Tsvg', '-o' + svg, '-Tjpg', '-o' + jpg, dot]) |
3289 | 3293 |
3290 # Post-process generated SVG to remove title elements which most browsers | 3294 # Post-process generated SVG to remove title elements which most browsers |
3291 # render as redundant (and annoying) tooltips. | 3295 # render as redundant (and annoying) tooltips. |
3292 with open(svg, 'r') as fp: | 3296 with open(svg, 'r') as fp: |
3293 content = fp.read() | 3297 content = fp.read() |
3294 content = re.sub('<title>.*</title>', '', content) | 3298 content = re.sub('<title>.*</title>', '', content) |
3295 content = re.sub('xlink:title="[^"]*"', '', content) | 3299 content = re.sub('xlink:title="[^"]*"', '', content) |
3296 with open(svg, 'w') as fp: | 3300 with open(svg, 'w') as fp: |
3297 fp.write(content) | 3301 fp.write(content) |
3298 | 3302 |
3299 # Create HTML that embeds the svg file in an <object> frame | 3303 # Create HTML that embeds the svg file in an <object> frame |
3300 with open(html, 'w') as fp: | 3304 with open(html, 'w') as fp: |
3301 print >> fp, '<html><body><object data="{}.svg" type="image/svg+xml"></object></body></html>'.format(args.dot_output_base) | 3305 print >> fp, '<html><body><object data="{}.svg" type="image/svg+xml"></object></body></html>'.format(args.dot_output_base) |
3302 | 3306 |
3303 top = join(tmpbase, 'all', 'overview-summary.html') | 3307 top = join(tmpbase, 'all', 'overview-summary.html') |
3344 return matches | 3348 return matches |
3345 | 3349 |
3346 def select_items(items, descriptions=None, allowMultiple=True): | 3350 def select_items(items, descriptions=None, allowMultiple=True): |
3347 """ | 3351 """ |
3348 Presents a command line interface for selecting one or more (if allowMultiple is true) items. | 3352 Presents a command line interface for selecting one or more (if allowMultiple is true) items. |
3349 | 3353 |
3350 """ | 3354 """ |
3351 if len(items) <= 1: | 3355 if len(items) <= 1: |
3352 return items | 3356 return items |
3353 else: | 3357 else: |
3354 if allowMultiple: | 3358 if allowMultiple: |
3368 try: | 3372 try: |
3369 s = [int(x) for x in s] | 3373 s = [int(x) for x in s] |
3370 except: | 3374 except: |
3371 log('Selection contains non-numeric characters: "' + ' '.join(s) + '"') | 3375 log('Selection contains non-numeric characters: "' + ' '.join(s) + '"') |
3372 continue | 3376 continue |
3373 | 3377 |
3374 if allowMultiple and 0 in s: | 3378 if allowMultiple and 0 in s: |
3375 return items | 3379 return items |
3376 | 3380 |
3377 indexes = [] | 3381 indexes = [] |
3378 for n in s: | 3382 for n in s: |
3379 if n not in range(1, len(items) + 1): | 3383 if n not in range(1, len(items) + 1): |
3380 log('Invalid selection: ' + str(n)) | 3384 log('Invalid selection: ' + str(n)) |
3381 continue | 3385 continue |
3388 return None | 3392 return None |
3389 | 3393 |
3390 def javap(args): | 3394 def javap(args): |
3391 """disassemble classes matching given pattern with javap""" | 3395 """disassemble classes matching given pattern with javap""" |
3392 | 3396 |
3393 javap = java().javap | 3397 javapExe = java().javap |
3394 if not exists(javap): | 3398 if not exists(javapExe): |
3395 abort('The javap executable does not exists: ' + javap) | 3399 abort('The javap executable does not exists: ' + javapExe) |
3396 else: | 3400 else: |
3397 candidates = findclass(args, logToConsole=False) | 3401 candidates = findclass(args, logToConsole=False) |
3398 if len(candidates) == 0: | 3402 if len(candidates) == 0: |
3399 log('no matches') | 3403 log('no matches') |
3400 selection = select_items(candidates) | 3404 selection = select_items(candidates) |
3401 run([javap, '-private', '-verbose', '-classpath', classpath()] + selection) | 3405 run([javapExe, '-private', '-verbose', '-classpath', classpath()] + selection) |
3402 | 3406 |
3403 def show_projects(args): | 3407 def show_projects(args): |
3404 """show all loaded projects""" | 3408 """show all loaded projects""" |
3405 for s in suites(): | 3409 for s in suites(): |
3406 projectsFile = join(s.dir, 'mx', 'projects') | 3410 projectsFile = join(s.dir, 'mx', 'projects') |
3407 if exists(projectsFile): | 3411 if exists(projectsFile): |
3408 log(projectsFile) | 3412 log(projectsFile) |
3409 for p in s.projects: | 3413 for p in s.projects: |
3410 log('\t' + p.name) | 3414 log('\t' + p.name) |
3411 | 3415 |
3412 def ask_yes_no(question, default=None): | 3416 def ask_yes_no(question, default=None): |
3413 """""" | 3417 """""" |
3414 assert not default or default == 'y' or default == 'n' | 3418 assert not default or default == 'y' or default == 'n' |
3415 if not sys.stdout.isatty(): | 3419 if not sys.stdout.isatty(): |
3416 if default: | 3420 if default: |
3435 # Table of commands in alphabetical order. | 3439 # Table of commands in alphabetical order. |
3436 # Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...] | 3440 # Keys are command names, value are lists: [<function>, <usage msg>, <format args to doc string of function>...] |
3437 # If any of the format args are instances of Callable, then they are called with an 'env' are before being | 3441 # If any of the format args are instances of Callable, then they are called with an 'env' are before being |
3438 # used in the call to str.format(). | 3442 # used in the call to str.format(). |
3439 # Extensions should update this table directly | 3443 # Extensions should update this table directly |
3440 commands = { | 3444 _commands = { |
3441 'about': [about, ''], | 3445 'about': [about, ''], |
3442 'build': [build, '[options]'], | 3446 'build': [build, '[options]'], |
3443 'checkstyle': [checkstyle, ''], | 3447 'checkstyle': [checkstyle, ''], |
3444 'canonicalizeprojects': [canonicalizeprojects, ''], | 3448 'canonicalizeprojects': [canonicalizeprojects, ''], |
3445 'clean': [clean, ''], | 3449 'clean': [clean, ''], |
3500 return | 3504 return |
3501 | 3505 |
3502 command = commandAndArgs[0] | 3506 command = commandAndArgs[0] |
3503 command_args = commandAndArgs[1:] | 3507 command_args = commandAndArgs[1:] |
3504 | 3508 |
3505 if not commands.has_key(command): | 3509 if not _commands.has_key(command): |
3506 hits = [c for c in commands.iterkeys() if c.startswith(command)] | 3510 hits = [c for c in _commands.iterkeys() if c.startswith(command)] |
3507 if len(hits) == 1: | 3511 if len(hits) == 1: |
3508 command = hits[0] | 3512 command = hits[0] |
3509 elif len(hits) == 0: | 3513 elif len(hits) == 0: |
3510 abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(command, _format_commands())) | 3514 abort('mx: unknown command \'{0}\'\n{1}use "mx help" for more options'.format(command, _format_commands())) |
3511 else: | 3515 else: |
3512 abort('mx: command \'{0}\' is ambiguous\n {1}'.format(command, ' '.join(hits))) | 3516 abort('mx: command \'{0}\' is ambiguous\n {1}'.format(command, ' '.join(hits))) |
3513 | 3517 |
3514 c, _ = commands[command][:2] | 3518 c, _ = _commands[command][:2] |
3515 def term_handler(signum, frame): | 3519 def term_handler(signum, frame): |
3516 abort(1) | 3520 abort(1) |
3517 signal.signal(signal.SIGTERM, term_handler) | 3521 signal.signal(signal.SIGTERM, term_handler) |
3518 try: | 3522 try: |
3519 if opts.timeout != 0: | 3523 if opts.timeout != 0: |