Mercurial > hg > truffle
comparison mxtool/mx.py @ 21180:c2f5dc4418d0
Merge
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Sat, 02 May 2015 14:40:49 -0700 |
parents | f383ff4c9af8 |
children | fbe449ca9707 |
comparison
equal
deleted
inserted
replaced
21179:fab864299d96 | 21180:c2f5dc4418d0 |
---|---|
45 from collections import Callable | 45 from collections import Callable |
46 from threading import Thread | 46 from threading import Thread |
47 from argparse import ArgumentParser, REMAINDER | 47 from argparse import ArgumentParser, REMAINDER |
48 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile | 48 from os.path import join, basename, dirname, exists, getmtime, isabs, expandvars, isdir, isfile |
49 | 49 |
50 # needed to work around https://bugs.python.org/issue1927 | |
51 import readline | |
52 #then make pylint happy.. | |
53 readline.get_line_buffer() | |
54 | |
50 # Support for Python 2.6 | 55 # Support for Python 2.6 |
51 def check_output(*popenargs, **kwargs): | 56 def check_output(*popenargs, **kwargs): |
52 process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) | 57 process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) |
53 output, _ = process.communicate() | 58 output, _ = process.communicate() |
54 retcode = process.poll() | 59 retcode = process.poll() |
92 _suites = dict() | 97 _suites = dict() |
93 _annotationProcessors = None | 98 _annotationProcessors = None |
94 _primary_suite_path = None | 99 _primary_suite_path = None |
95 _primary_suite = None | 100 _primary_suite = None |
96 _opts = None | 101 _opts = None |
97 _java_homes = None | 102 _extra_java_homes = [] |
103 _default_java_home = None | |
98 _warn = False | 104 _warn = False |
99 | 105 |
100 """ | 106 """ |
101 A distribution is a jar or zip file containing the output from one or more Java projects. | 107 A distribution is a jar or zip file containing the output from one or more Java projects. |
102 """ | 108 """ |
210 p = dep | 216 p = dep |
211 | 217 |
212 if self.javaCompliance: | 218 if self.javaCompliance: |
213 if p.javaCompliance > self.javaCompliance: | 219 if p.javaCompliance > self.javaCompliance: |
214 abort("Compliance level doesn't match: Distribution {0} requires {1}, but {2} is {3}.".format(self.name, self.javaCompliance, p.name, p.javaCompliance)) | 220 abort("Compliance level doesn't match: Distribution {0} requires {1}, but {2} is {3}.".format(self.name, self.javaCompliance, p.name, p.javaCompliance)) |
215 | |
216 # skip a Java project if its Java compliance level is "higher" than the configured JDK | |
217 jdk = java(p.javaCompliance) | |
218 assert jdk | |
219 | 221 |
220 logv('[' + self.path + ': adding project ' + p.name + ']') | 222 logv('[' + self.path + ': adding project ' + p.name + ']') |
221 outputDir = p.output_dir() | 223 outputDir = p.output_dir() |
222 for root, _, files in os.walk(outputDir): | 224 for root, _, files in os.walk(outputDir): |
223 relpath = root[len(outputDir) + 1:] | 225 relpath = root[len(outputDir) + 1:] |
304 | 306 |
305 # The annotation processors defined by this project | 307 # The annotation processors defined by this project |
306 self.definedAnnotationProcessors = None | 308 self.definedAnnotationProcessors = None |
307 self.definedAnnotationProcessorsDist = None | 309 self.definedAnnotationProcessorsDist = None |
308 | 310 |
309 | |
310 # Verify that a JDK exists for this project if its compliance level is | |
311 # less than the compliance level of the default JDK | |
312 jdk = java(self.javaCompliance) | |
313 if jdk is None and self.javaCompliance < java().javaCompliance: | |
314 abort('Cannot find ' + str(self.javaCompliance) + ' JDK required by ' + name + '. ' + | |
315 'Specify it with --extra-java-homes option or EXTRA_JAVA_HOMES environment variable.') | |
316 | |
317 # Create directories for projects that don't yet exist | 311 # Create directories for projects that don't yet exist |
318 if not exists(d): | 312 if not exists(d): |
319 os.mkdir(d) | 313 os.mkdir(d) |
320 for s in self.source_dirs(): | 314 for s in self.source_dirs(): |
321 if not exists(s): | 315 if not exists(s): |
753 def get_path(self, resolve): | 747 def get_path(self, resolve): |
754 path = _make_absolute(self.path, self.suite.dir) | 748 path = _make_absolute(self.path, self.suite.dir) |
755 sha1path = path + '.sha1' | 749 sha1path = path + '.sha1' |
756 | 750 |
757 includedInJDK = getattr(self, 'includedInJDK', None) | 751 includedInJDK = getattr(self, 'includedInJDK', None) |
752 # TODO since we don't know which JDK will be used, this check is dubious | |
758 if includedInJDK and java().javaCompliance >= JavaCompliance(includedInJDK): | 753 if includedInJDK and java().javaCompliance >= JavaCompliance(includedInJDK): |
759 return None | 754 return None |
760 | 755 |
761 bootClassPathAgent = getattr(self, 'bootClassPathAgent').lower() == 'true' if hasattr(self, 'bootClassPathAgent') else False | 756 bootClassPathAgent = getattr(self, 'bootClassPathAgent').lower() == 'true' if hasattr(self, 'bootClassPathAgent') else False |
762 | 757 |
1228 if not path: | 1223 if not path: |
1229 logv('[omitting optional library {0} as {1} does not exist]'.format(d, d.path)) | 1224 logv('[omitting optional library {0} as {1} does not exist]'.format(d, d.path)) |
1230 del _libs[d.name] | 1225 del _libs[d.name] |
1231 self.libs.remove(d) | 1226 self.libs.remove(d) |
1232 elif d.isProject(): | 1227 elif d.isProject(): |
1233 if java(d.javaCompliance) is None: | 1228 if java(d.javaCompliance, cancel='some projects will be omitted which may result in errrors') is None: |
1234 logv('[omitting project {0} as Java compliance {1} cannot be satisfied by configured JDKs]'.format(d, d.javaCompliance)) | 1229 logv('[omitting project {0} as Java compliance {1} cannot be satisfied by configured JDKs]'.format(d, d.javaCompliance)) |
1235 del _projects[d.name] | 1230 del _projects[d.name] |
1236 self.projects.remove(d) | 1231 self.projects.remove(d) |
1237 else: | 1232 else: |
1238 for name in list(d.deps): | 1233 for name in list(d.deps): |
1654 deps = [] | 1649 deps = [] |
1655 for p in projects: | 1650 for p in projects: |
1656 p.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors) | 1651 p.all_deps(deps, includeLibs=includeLibs, includeJreLibs=includeJreLibs, includeAnnotationProcessors=includeAnnotationProcessors) |
1657 return deps | 1652 return deps |
1658 | 1653 |
1659 def _handle_lookup_java_home(jdk): | |
1660 return _handle_lookup_jdk(jdk, 'JAVA_HOME', '--java-home', False) | |
1661 | |
1662 def _handle_lookup_extra_java_homes(jdk): | |
1663 return _handle_lookup_jdk(jdk, 'EXTRA_JAVA_HOMES', '--extra-java-homes', True) | |
1664 | |
1665 def _handle_lookup_jdk(jdk, varName, flagName, allowMultiple): | |
1666 if jdk != None and jdk != '': | |
1667 return jdk | |
1668 jdk = os.environ.get(varName) | |
1669 if jdk != None and jdk != '': | |
1670 return jdk | |
1671 | |
1672 if not sys.stdout.isatty(): | |
1673 abort('Could not find bootstrap {0}. Use {1} option or ensure {2} environment variable is set.'.format(varName, flagName, varName)) | |
1674 | |
1675 candidateJdks = [] | |
1676 if get_os() == 'darwin': | |
1677 base = '/Library/Java/JavaVirtualMachines' | |
1678 if exists(base): | |
1679 candidateJdks = [join(base, n, 'Contents/Home') for n in os.listdir(base) if exists(join(base, n, 'Contents/Home'))] | |
1680 elif get_os() == 'linux': | |
1681 base = '/usr/lib/jvm' | |
1682 if exists(base): | |
1683 candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] | |
1684 base = '/usr/java' | |
1685 if exists(base): | |
1686 candidateJdks += [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] | |
1687 elif get_os() == 'solaris': | |
1688 base = '/usr/jdk/instances' | |
1689 if exists(base): | |
1690 candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] | |
1691 elif get_os() == 'windows': | |
1692 base = r'C:\Program Files\Java' | |
1693 if exists(base): | |
1694 candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, r'jre\lib\rt.jar'))] | |
1695 | |
1696 javaHome = None | |
1697 if len(candidateJdks) != 0: | |
1698 log('Missing value for {0}.'.format(varName)) | |
1699 javaHome = select_items(candidateJdks + ['<other>'], allowMultiple=allowMultiple) | |
1700 if javaHome == '<other>': | |
1701 javaHome = None | |
1702 if javaHome != None and allowMultiple: | |
1703 javaHome = os.pathsep.join(javaHome) | |
1704 | |
1705 while javaHome is None: | |
1706 javaHome = raw_input('Enter path of JDK for {0}: '.format(varName)) | |
1707 rtJarPath = join(javaHome, 'jre', 'lib', 'rt.jar') | |
1708 if not exists(rtJarPath): | |
1709 log('Does not appear to be a valid JDK as ' + rtJarPath + ' does not exist') | |
1710 javaHome = None | |
1711 else: | |
1712 break | |
1713 | |
1714 envPath = join(_primary_suite.mxDir, 'env') | |
1715 if ask_yes_no('Persist this setting by adding "{0}={1}" to {2}'.format(varName, javaHome, envPath), 'y'): | |
1716 with open(envPath, 'a') as fp: | |
1717 print >> fp, varName + '=' + javaHome | |
1718 | |
1719 return javaHome | |
1720 | |
1721 class ArgParser(ArgumentParser): | 1654 class ArgParser(ArgumentParser): |
1722 # Override parent to append the list of available commands | 1655 # Override parent to append the list of available commands |
1723 def format_help(self): | 1656 def format_help(self): |
1724 return ArgumentParser.format_help(self) + _format_commands() | 1657 return ArgumentParser.format_help(self) + _format_commands() |
1725 | 1658 |
1742 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) | 1675 self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) |
1743 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) | 1676 self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) |
1744 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) | 1677 self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) |
1745 self.add_argument('--java-home', help='primary JDK directory (must be JDK 7 or later)', metavar='<path>') | 1678 self.add_argument('--java-home', help='primary JDK directory (must be JDK 7 or later)', metavar='<path>') |
1746 self.add_argument('--extra-java-homes', help='secondary JDK directories separated by "' + os.pathsep + '"', metavar='<path>') | 1679 self.add_argument('--extra-java-homes', help='secondary JDK directories separated by "' + os.pathsep + '"', metavar='<path>') |
1680 self.add_argument('--strict-compliance', action='store_true', dest='strict_compliance', help='Projects of a certain compliance will only be built with a JDK of this exact compliance', default=False) | |
1747 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) | 1681 self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) |
1748 self.add_argument('--kill-with-sigquit', action='store_true', dest='killwithsigquit', help='send sigquit first before killing child processes') | 1682 self.add_argument('--kill-with-sigquit', action='store_true', dest='killwithsigquit', help='send sigquit first before killing child processes') |
1749 if get_os() != 'windows': | 1683 if get_os() != 'windows': |
1750 # Time outs are (currently) implemented with Unix specific functionality | 1684 # Time outs are (currently) implemented with Unix specific functionality |
1751 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') | 1685 self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='<secs>') |
1767 opts.__dict__.setdefault('ptimeout', 0) | 1701 opts.__dict__.setdefault('ptimeout', 0) |
1768 | 1702 |
1769 if opts.very_verbose: | 1703 if opts.very_verbose: |
1770 opts.verbose = True | 1704 opts.verbose = True |
1771 | 1705 |
1772 opts.java_home = _handle_lookup_java_home(opts.java_home) | |
1773 opts.extra_java_homes = _handle_lookup_extra_java_homes(opts.extra_java_homes) | |
1774 | |
1775 if opts.user_home is None or opts.user_home == '': | 1706 if opts.user_home is None or opts.user_home == '': |
1776 abort('Could not find user home. Use --user-home option or ensure HOME environment variable is set.') | 1707 abort('Could not find user home. Use --user-home option or ensure HOME environment variable is set.') |
1777 | 1708 |
1778 os.environ['JAVA_HOME'] = opts.java_home | 1709 if opts.java_home: |
1710 os.environ['JAVA_HOME'] = opts.java_home | |
1779 os.environ['HOME'] = opts.user_home | 1711 os.environ['HOME'] = opts.user_home |
1712 | |
1713 if os.environ.get('STRICT_COMPLIANCE'): | |
1714 _opts.strict_compliance = True | |
1780 | 1715 |
1781 opts.ignored_projects = opts.ignored_projects + os.environ.get('IGNORED_PROJECTS', '').split(',') | 1716 opts.ignored_projects = opts.ignored_projects + os.environ.get('IGNORED_PROJECTS', '').split(',') |
1782 | 1717 |
1783 commandAndArgs = opts.__dict__.pop('commandAndArgs') | 1718 commandAndArgs = opts.__dict__.pop('commandAndArgs') |
1784 return opts, commandAndArgs | 1719 return opts, commandAndArgs |
1794 if doc is None: | 1729 if doc is None: |
1795 doc = '' | 1730 doc = '' |
1796 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) | 1731 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) |
1797 return msg + '\n' | 1732 return msg + '\n' |
1798 | 1733 |
1799 def java(requiredCompliance=None): | 1734 _canceled_java_requests = set() |
1735 | |
1736 def java(requiredCompliance=None, purpose=None, cancel=None): | |
1800 """ | 1737 """ |
1801 Get a JavaConfig object containing Java commands launch details. | 1738 Get a JavaConfig object containing Java commands launch details. |
1802 If requiredCompliance is None, the compliance level specified by --java-home/JAVA_HOME | 1739 If requiredCompliance is None, the compliance level specified by --java-home/JAVA_HOME |
1803 is returned. Otherwise, the JavaConfig exactly matching requiredCompliance is returned | 1740 is returned. Otherwise, the JavaConfig exactly matching requiredCompliance is returned |
1804 or None if there is no exact match. | 1741 or None if there is no exact match. |
1805 """ | 1742 """ |
1806 assert _java_homes | 1743 |
1744 global _default_java_home | |
1745 if cancel and (requiredCompliance, purpose) in _canceled_java_requests: | |
1746 return None | |
1747 | |
1807 if not requiredCompliance: | 1748 if not requiredCompliance: |
1808 return _java_homes[0] | 1749 if not _default_java_home: |
1809 for java in _java_homes: | 1750 _default_java_home = _find_jdk(purpose=purpose, cancel=cancel) |
1810 if java.javaCompliance == requiredCompliance: | 1751 if not _default_java_home: |
1752 assert cancel | |
1753 _canceled_java_requests.add((requiredCompliance, purpose)) | |
1754 return _default_java_home | |
1755 | |
1756 if _opts.strict_compliance: | |
1757 complianceCheck = requiredCompliance.exactMatch | |
1758 desc = str(requiredCompliance) | |
1759 else: | |
1760 compVersion = VersionSpec(str(requiredCompliance)) | |
1761 complianceCheck = lambda version: version >= compVersion | |
1762 desc = '>=' + str(requiredCompliance) | |
1763 | |
1764 for java in _extra_java_homes: | |
1765 if complianceCheck(java.version): | |
1811 return java | 1766 return java |
1767 | |
1768 jdk = _find_jdk(versionCheck=complianceCheck, versionDescription=desc, purpose=purpose, cancel=cancel) | |
1769 if jdk: | |
1770 assert jdk not in _extra_java_homes | |
1771 _extra_java_homes.append(jdk) | |
1772 else: | |
1773 assert cancel | |
1774 _canceled_java_requests.add((requiredCompliance, purpose)) | |
1775 return jdk | |
1776 | |
1777 def java_version(versionCheck, versionDescription=None, purpose=None): | |
1778 if _default_java_home and versionCheck(_default_java_home.version): | |
1779 return _default_java_home | |
1780 for java in _extra_java_homes: | |
1781 if versionCheck(java.version): | |
1782 return java | |
1783 jdk = _find_jdk(versionCheck, versionDescription, purpose) | |
1784 assert jdk not in _extra_java_homes | |
1785 _extra_java_homes.append(jdk) | |
1786 return jdk | |
1787 | |
1788 def _find_jdk(versionCheck=None, versionDescription=None, purpose=None, cancel=None): | |
1789 if not versionCheck: | |
1790 versionCheck = lambda v: True | |
1791 assert not versionDescription or versionCheck | |
1792 if not versionCheck and not purpose: | |
1793 isDefaultJdk = True | |
1794 else: | |
1795 isDefaultJdk = False | |
1796 | |
1797 candidateJdks = [] | |
1798 source = '' | |
1799 if _opts.java_home: | |
1800 candidateJdks.append(_opts.java_home) | |
1801 source = '--java-home' | |
1802 elif os.environ.get('JAVA_HOME'): | |
1803 candidateJdks.append(os.environ.get('JAVA_HOME')) | |
1804 source = 'JAVA_HOME' | |
1805 | |
1806 result = _find_jdk_in_candidates(candidateJdks, versionCheck, warn=True, source=source) | |
1807 if result: | |
1808 return result | |
1809 | |
1810 candidateJdks = [] | |
1811 | |
1812 if _opts.extra_java_homes: | |
1813 candidateJdks += _opts.extra_java_homes.split(os.pathsep) | |
1814 source = '--extra-java-homes' | |
1815 elif os.environ.get('EXTRA_JAVA_HOMES'): | |
1816 candidateJdks += os.environ.get('EXTRA_JAVA_HOMES').split(os.pathsep) | |
1817 source = 'EXTRA_JAVA_HOMES' | |
1818 | |
1819 result = _find_jdk_in_candidates(candidateJdks, versionCheck, warn=True, source=source) | |
1820 if not result: | |
1821 candidateJdks = [] | |
1822 source = '' | |
1823 | |
1824 if get_os() == 'darwin': | |
1825 base = '/Library/Java/JavaVirtualMachines' | |
1826 if exists(base): | |
1827 candidateJdks = [join(base, n, 'Contents/Home') for n in os.listdir(base)] | |
1828 elif get_os() == 'linux': | |
1829 base = '/usr/lib/jvm' | |
1830 if exists(base): | |
1831 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1832 base = '/usr/java' | |
1833 if exists(base): | |
1834 candidateJdks += [join(base, n) for n in os.listdir(base)] | |
1835 elif get_os() == 'solaris': | |
1836 base = '/usr/jdk/instances' | |
1837 if exists(base): | |
1838 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1839 elif get_os() == 'windows': | |
1840 base = r'C:\Program Files\Java' | |
1841 if exists(base): | |
1842 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1843 | |
1844 configs = _filtered_jdk_configs(candidateJdks, versionCheck) | |
1845 else: | |
1846 if not isDefaultJdk: | |
1847 return result | |
1848 configs = [result] | |
1849 | |
1850 if len(configs) > 1: | |
1851 if not is_interactive(): | |
1852 msg = "Multiple possible choices for a JDK" | |
1853 if purpose: | |
1854 msg += ' for' + purpose | |
1855 msg += ': ' | |
1856 if versionDescription: | |
1857 msg += '(' + versionDescription + ')' | |
1858 selected = configs[0] | |
1859 msg += ". Selecting " + str(selected) | |
1860 log(msg) | |
1861 else: | |
1862 msg = 'Please select a ' | |
1863 if isDefaultJdk: | |
1864 msg += 'default ' | |
1865 msg += 'JDK' | |
1866 if purpose: | |
1867 msg += ' for' + purpose | |
1868 msg += ': ' | |
1869 if versionDescription: | |
1870 msg += '(' + versionDescription + ')' | |
1871 log(msg) | |
1872 choices = configs + ['<other>'] | |
1873 if cancel: | |
1874 choices.append('Cancel (' + cancel + ')') | |
1875 selected = select_items(choices, allowMultiple=False) | |
1876 if isinstance(selected, types.StringTypes) and selected == '<other>': | |
1877 selected = None | |
1878 if isinstance(selected, types.StringTypes) and selected == 'Cancel (' + cancel + ')': | |
1879 return None | |
1880 elif len(configs) == 1: | |
1881 selected = configs[0] | |
1882 msg = 'Selected ' + str(selected) + ' as ' | |
1883 if isDefaultJdk: | |
1884 msg += 'default' | |
1885 msg += 'JDK' | |
1886 if versionDescription: | |
1887 msg = msg + ' ' + versionDescription | |
1888 if purpose: | |
1889 msg += ' for' + purpose | |
1890 log(msg) | |
1891 else: | |
1892 msg = 'Could not find any JDK' | |
1893 if purpose: | |
1894 msg += ' for' + purpose | |
1895 msg += ' ' | |
1896 if versionDescription: | |
1897 msg = msg + '(' + versionDescription + ')' | |
1898 log(msg) | |
1899 selected = None | |
1900 | |
1901 while not selected: | |
1902 jdkLocation = raw_input('Enter path of JDK: ') | |
1903 selected = _find_jdk_in_candidates([jdkLocation], versionCheck, warn=True) | |
1904 | |
1905 varName = 'JAVA_HOME' if isDefaultJdk else 'EXTRA_JAVA_HOMES' | |
1906 allowMultiple = not isDefaultJdk | |
1907 envPath = join(_primary_suite.mxDir, 'env') | |
1908 if is_interactive() and ask_yes_no('Persist this setting by adding "{0}={1}" to {2}'.format(varName, selected.jdk, envPath), 'y'): | |
1909 envLines = [] | |
1910 with open(envPath) as fp: | |
1911 append = True | |
1912 for line in fp: | |
1913 if line.rstrip().startswith(varName): | |
1914 _, currentValue = line.split('=', 1) | |
1915 currentValue = currentValue.strip() | |
1916 if not allowMultiple and currentValue: | |
1917 if not ask_yes_no('{0} is already set to {1}, overwrite with {2}?'.format(varName, currentValue, selected.jdk), 'n'): | |
1918 return selected | |
1919 else: | |
1920 line = varName + '=' + selected.jdk + os.linesep | |
1921 else: | |
1922 line = line.rstrip() | |
1923 if currentValue: | |
1924 line += os.pathsep | |
1925 line += selected.jdk + os.linesep | |
1926 append = False | |
1927 envLines.append(line) | |
1928 if append: | |
1929 envLines.append(varName + '=' + selected.jdk) | |
1930 | |
1931 with open(envPath, 'w') as fp: | |
1932 for line in envLines: | |
1933 fp.write(line) | |
1934 | |
1935 if varName == 'JAVA_HOME': | |
1936 os.environ['JAVA_HOME'] = selected.jdk | |
1937 | |
1938 return selected | |
1939 | |
1940 def is_interactive(): | |
1941 return sys.__stdin__.isatty() | |
1942 | |
1943 def _filtered_jdk_configs(candidates, versionCheck, warn=False, source=None): | |
1944 filtered = [] | |
1945 for candidate in candidates: | |
1946 try: | |
1947 config = JavaConfig(candidate) | |
1948 if versionCheck(config.version): | |
1949 filtered.append(config) | |
1950 except JavaConfigException as e: | |
1951 if warn: | |
1952 log('Path in ' + source + "' is not pointing to a JDK (" + e.message + ")") | |
1953 return filtered | |
1954 | |
1955 def _find_jdk_in_candidates(candidates, versionCheck, warn=False, source=None): | |
1956 filtered = _filtered_jdk_configs(candidates, versionCheck, warn, source) | |
1957 if filtered: | |
1958 return filtered[0] | |
1812 return None | 1959 return None |
1813 | 1960 |
1814 | 1961 |
1815 def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, addDefaultArgs=True, javaConfig=None): | 1962 def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, addDefaultArgs=True, javaConfig=None): |
1816 if not javaConfig: | 1963 if not javaConfig: |
2077 return cmp(self.value, other.value) | 2224 return cmp(self.value, other.value) |
2078 | 2225 |
2079 def __hash__(self): | 2226 def __hash__(self): |
2080 return self.value.__hash__() | 2227 return self.value.__hash__() |
2081 | 2228 |
2229 def exactMatch(self, version): | |
2230 assert isinstance(version, VersionSpec) | |
2231 return len(version.parts) > 1 and version.parts[0] == 1 and version.parts[1] == self.value | |
2232 | |
2082 """ | 2233 """ |
2083 A version specification as defined in JSR-56 | 2234 A version specification as defined in JSR-56 |
2084 """ | 2235 """ |
2085 class VersionSpec: | 2236 class VersionSpec: |
2086 def __init__(self, versionString): | 2237 def __init__(self, versionString): |
2100 def _filter_non_existant_paths(paths): | 2251 def _filter_non_existant_paths(paths): |
2101 if paths: | 2252 if paths: |
2102 return os.pathsep.join([path for path in _separatedCygpathW2U(paths).split(os.pathsep) if exists(path)]) | 2253 return os.pathsep.join([path for path in _separatedCygpathW2U(paths).split(os.pathsep) if exists(path)]) |
2103 return None | 2254 return None |
2104 | 2255 |
2256 class JavaConfigException(Exception): | |
2257 def __init__(self, value): | |
2258 Exception.__init__(self, value) | |
2259 | |
2105 """ | 2260 """ |
2106 A JavaConfig object encapsulates info on how Java commands are run. | 2261 A JavaConfig object encapsulates info on how Java commands are run. |
2107 """ | 2262 """ |
2108 class JavaConfig: | 2263 class JavaConfig: |
2109 def __init__(self, java_home, java_dbg_port): | 2264 def __init__(self, java_home): |
2110 self.jdk = java_home | 2265 self.jdk = java_home |
2111 self.debug_port = java_dbg_port | |
2112 self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) | 2266 self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) |
2113 self.java = exe_suffix(join(self.jdk, 'bin', 'java')) | 2267 self.java = exe_suffix(join(self.jdk, 'bin', 'java')) |
2114 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) | 2268 self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) |
2115 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) | 2269 self.javap = exe_suffix(join(self.jdk, 'bin', 'javap')) |
2116 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) | 2270 self.javadoc = exe_suffix(join(self.jdk, 'bin', 'javadoc')) |
2120 self._bootclasspath = None | 2274 self._bootclasspath = None |
2121 self._extdirs = None | 2275 self._extdirs = None |
2122 self._endorseddirs = None | 2276 self._endorseddirs = None |
2123 | 2277 |
2124 if not exists(self.java): | 2278 if not exists(self.java): |
2125 abort('Java launcher does not exist: ' + self.java) | 2279 raise JavaConfigException('Java launcher does not exist: ' + self.java) |
2126 | 2280 |
2127 def delAtAndSplit(s): | 2281 def delAtAndSplit(s): |
2128 return shlex.split(s.lstrip('@')) | 2282 return shlex.split(s.lstrip('@')) |
2129 | 2283 |
2130 self.java_args = delAtAndSplit(_opts.java_args) if _opts.java_args else [] | 2284 self.java_args = delAtAndSplit(_opts.java_args) if _opts.java_args else [] |
2137 self.java_args = ['-d64'] + self.java_args | 2291 self.java_args = ['-d64'] + self.java_args |
2138 except subprocess.CalledProcessError as e: | 2292 except subprocess.CalledProcessError as e: |
2139 try: | 2293 try: |
2140 output = subprocess.check_output([self.java, '-version'], stderr=subprocess.STDOUT) | 2294 output = subprocess.check_output([self.java, '-version'], stderr=subprocess.STDOUT) |
2141 except subprocess.CalledProcessError as e: | 2295 except subprocess.CalledProcessError as e: |
2142 print e.output | 2296 raise JavaConfigException(e.returncode + " :" + e.output) |
2143 abort(e.returncode) | |
2144 | 2297 |
2145 def _checkOutput(out): | 2298 def _checkOutput(out): |
2146 return 'version' in out | 2299 return 'version' in out |
2147 | 2300 |
2148 # hotspot can print a warning, e.g. if there's a .hotspot_compiler file in the cwd | 2301 # hotspot can print a warning, e.g. if there's a .hotspot_compiler file in the cwd |
2154 version = o | 2307 version = o |
2155 | 2308 |
2156 self.version = VersionSpec(version.split()[2].strip('"')) | 2309 self.version = VersionSpec(version.split()[2].strip('"')) |
2157 self.javaCompliance = JavaCompliance(self.version.versionString) | 2310 self.javaCompliance = JavaCompliance(self.version.versionString) |
2158 | 2311 |
2159 if self.debug_port is not None: | 2312 if _opts.java_dbg_port is not None: |
2160 self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(self.debug_port)] | 2313 self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(_opts.java_dbg_port)] |
2161 | 2314 |
2162 def _init_classpaths(self): | 2315 def _init_classpaths(self): |
2163 if not self._classpaths_initialized: | 2316 if not self._classpaths_initialized: |
2164 myDir = dirname(__file__) | 2317 myDir = dirname(__file__) |
2165 outDir = join(dirname(__file__), '.jdk' + str(self.version)) | 2318 outDir = join(dirname(__file__), '.jdk' + str(self.version)) |
2178 self._extdirs = _filter_non_existant_paths(self._extdirs) | 2331 self._extdirs = _filter_non_existant_paths(self._extdirs) |
2179 self._endorseddirs = _filter_non_existant_paths(self._endorseddirs) | 2332 self._endorseddirs = _filter_non_existant_paths(self._endorseddirs) |
2180 self._classpaths_initialized = True | 2333 self._classpaths_initialized = True |
2181 | 2334 |
2182 def __repr__(self): | 2335 def __repr__(self): |
2183 return "JavaConfig(" + str(self.jdk) + ", " + str(self.debug_port) + ")" | 2336 return "JavaConfig(" + str(self.jdk) + ")" |
2184 | 2337 |
2185 def __str__(self): | 2338 def __str__(self): |
2186 return "Java " + str(self.version) + " (" + str(self.javaCompliance) + ") from " + str(self.jdk) | 2339 return "Java " + str(self.version) + " (" + str(self.javaCompliance) + ") from " + str(self.jdk) |
2187 | 2340 |
2188 def __hash__(self): | 2341 def __hash__(self): |
2473 if not args.error_prone: | 2626 if not args.error_prone: |
2474 javac = args.alt_javac if args.alt_javac else mainJava.javac | 2627 javac = args.alt_javac if args.alt_javac else mainJava.javac |
2475 self.logCompilation('javac' if not args.alt_javac else args.alt_javac) | 2628 self.logCompilation('javac' if not args.alt_javac else args.alt_javac) |
2476 javacCmd = [javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] | 2629 javacCmd = [javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] |
2477 jdk.javacLibOptions(javacCmd) | 2630 jdk.javacLibOptions(javacCmd) |
2478 if jdk.debug_port is not None: | 2631 if _opts.java_dbg_port is not None: |
2479 javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] | 2632 javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(_opts.java_dbg_port)] |
2480 javacCmd += processorArgs | 2633 javacCmd += processorArgs |
2481 javacCmd += ['@' + _cygpathU2W(argfile.name)] | 2634 javacCmd += ['@' + _cygpathU2W(argfile.name)] |
2482 | 2635 |
2483 if not args.warnAPI: | 2636 if not args.warnAPI: |
2484 javacCmd.append('-XDignore.symbol.file') | 2637 javacCmd.append('-XDignore.symbol.file') |
2634 continue | 2787 continue |
2635 | 2788 |
2636 # skip building this Java project if its Java compliance level is "higher" than the configured JDK | 2789 # skip building this Java project if its Java compliance level is "higher" than the configured JDK |
2637 requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None | 2790 requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None |
2638 jdk = java(requiredCompliance) | 2791 jdk = java(requiredCompliance) |
2639 assert jdk | |
2640 | 2792 |
2641 outputDir = p.output_dir() | 2793 outputDir = p.output_dir() |
2642 | 2794 |
2643 sourceDirs = p.source_dirs() | 2795 sourceDirs = p.source_dirs() |
2644 buildReason = None | 2796 buildReason = None |
2938 | 3090 |
2939 class Batch: | 3091 class Batch: |
2940 def __init__(self, settingsDir, javaCompliance): | 3092 def __init__(self, settingsDir, javaCompliance): |
2941 self.path = join(settingsDir, 'org.eclipse.jdt.core.prefs') | 3093 self.path = join(settingsDir, 'org.eclipse.jdt.core.prefs') |
2942 self.javaCompliance = javaCompliance | 3094 self.javaCompliance = javaCompliance |
2943 self.javafiles = list() | |
2944 with open(join(settingsDir, 'org.eclipse.jdt.ui.prefs')) as fp: | 3095 with open(join(settingsDir, 'org.eclipse.jdt.ui.prefs')) as fp: |
2945 jdtUiPrefs = fp.read() | 3096 jdtUiPrefs = fp.read() |
2946 self.removeTrailingWhitespace = 'sp_cleanup.remove_trailing_whitespaces_all=true' in jdtUiPrefs | 3097 self.removeTrailingWhitespace = 'sp_cleanup.remove_trailing_whitespaces_all=true' in jdtUiPrefs |
2947 if self.removeTrailingWhitespace: | 3098 if self.removeTrailingWhitespace: |
2948 assert 'sp_cleanup.remove_trailing_whitespaces=true' in jdtUiPrefs and 'sp_cleanup.remove_trailing_whitespaces_ignore_empty=false' in jdtUiPrefs | 3099 assert 'sp_cleanup.remove_trailing_whitespaces=true' in jdtUiPrefs and 'sp_cleanup.remove_trailing_whitespaces_ignore_empty=false' in jdtUiPrefs |
2949 | 3100 self.cachedHash = None |
2950 def settings(self): | 3101 |
3102 def __hash__(self): | |
3103 if not self.cachedHash: | |
3104 with open(self.path) as fp: | |
3105 self.cachedHash = (fp.read(), self.javaCompliance, self.removeTrailingWhitespace).__hash__() | |
3106 return self.cachedHash | |
3107 | |
3108 def __eq__(self, other): | |
3109 if not isinstance(other, Batch): | |
3110 return False | |
3111 if self.removeTrailingWhitespace != other.removeTrailingWhitespace: | |
3112 return False | |
3113 if self.javaCompliance != other.javaCompliance: | |
3114 return False | |
3115 if self.path == other.path: | |
3116 return True | |
2951 with open(self.path) as fp: | 3117 with open(self.path) as fp: |
2952 return fp.read() + java(self.javaCompliance).java + str(self.removeTrailingWhitespace) | 3118 with open(other.path) as ofp: |
3119 if fp.read() != ofp.read(): | |
3120 return False | |
3121 return True | |
2953 | 3122 |
2954 class FileInfo: | 3123 class FileInfo: |
2955 def __init__(self, path): | 3124 def __init__(self, path): |
2956 self.path = path | 3125 self.path = path |
2957 with open(path) as fp: | 3126 with open(path) as fp: |
2990 | 3159 |
2991 if not exists(batch.path): | 3160 if not exists(batch.path): |
2992 if _opts.verbose: | 3161 if _opts.verbose: |
2993 log('[no Eclipse Code Formatter preferences at {0} - skipping]'.format(batch.path)) | 3162 log('[no Eclipse Code Formatter preferences at {0} - skipping]'.format(batch.path)) |
2994 continue | 3163 continue |
2995 | 3164 javafiles = [] |
2996 for sourceDir in sourceDirs: | 3165 for sourceDir in sourceDirs: |
2997 for root, _, files in os.walk(sourceDir): | 3166 for root, _, files in os.walk(sourceDir): |
2998 for f in [join(root, name) for name in files if name.endswith('.java')]: | 3167 for f in [join(root, name) for name in files if name.endswith('.java')]: |
2999 batch.javafiles.append(FileInfo(f)) | 3168 javafiles.append(FileInfo(f)) |
3000 if len(batch.javafiles) == 0: | 3169 if len(javafiles) == 0: |
3001 logv('[no Java sources in {0} - skipping]'.format(p.name)) | 3170 logv('[no Java sources in {0} - skipping]'.format(p.name)) |
3002 continue | 3171 continue |
3003 | 3172 |
3004 res = batches.setdefault(batch.settings(), batch) | 3173 res = batches.setdefault(batch, javafiles) |
3005 if res is not batch: | 3174 if res is not javafiles: |
3006 res.javafiles = res.javafiles + batch.javafiles | 3175 res.extend(javafiles) |
3007 | 3176 |
3008 log("we have: " + str(len(batches)) + " batches") | 3177 log("we have: " + str(len(batches)) + " batches") |
3009 for batch in batches.itervalues(): | 3178 for batch, javafiles in batches.iteritems(): |
3010 for chunk in _chunk_files_for_command_line(batch.javafiles, pathFunction=lambda f: f.path): | 3179 for chunk in _chunk_files_for_command_line(javafiles, pathFunction=lambda f: f.path): |
3011 run([args.eclipse_exe, | 3180 run([args.eclipse_exe, |
3012 '-nosplash', | 3181 '-nosplash', |
3013 '-application', | 3182 '-application', |
3014 'org.eclipse.jdt.core.JavaCodeFormatter', | 3183 'org.eclipse.jdt.core.JavaCodeFormatter', |
3015 '-vm', java(batch.javaCompliance).java, | 3184 '-vm', java(batch.javaCompliance).java, |
4719 if not refreshOnly: | 4888 if not refreshOnly: |
4720 fsckprojects([]) | 4889 fsckprojects([]) |
4721 | 4890 |
4722 def fsckprojects(args): | 4891 def fsckprojects(args): |
4723 """find directories corresponding to deleted Java projects and delete them""" | 4892 """find directories corresponding to deleted Java projects and delete them""" |
4724 if not sys.stdout.isatty(): | 4893 if not is_interactive(): |
4725 log('fsckprojects command must be run in an interactive shell') | 4894 log('fsckprojects command must be run in an interactive shell') |
4726 return | 4895 return |
4727 hg = HgConfig() | 4896 hg = HgConfig() |
4728 for suite in suites(True): | 4897 for suite in suites(True): |
4729 projectDirs = [p.dir for p in suite.projects] | 4898 projectDirs = [p.dir for p in suite.projects] |
4744 if len(indicators) != 0: | 4913 if len(indicators) != 0: |
4745 indicators = [os.path.relpath(join(dirpath, i), suite.dir) for i in indicators] | 4914 indicators = [os.path.relpath(join(dirpath, i), suite.dir) for i in indicators] |
4746 indicatorsInHg = hg.locate(suite.dir, indicators) | 4915 indicatorsInHg = hg.locate(suite.dir, indicators) |
4747 # Only proceed if there are indicator files that are not under HG | 4916 # Only proceed if there are indicator files that are not under HG |
4748 if len(indicators) > len(indicatorsInHg): | 4917 if len(indicators) > len(indicatorsInHg): |
4749 if not sys.stdout.isatty() or ask_yes_no(dirpath + ' looks like a removed project -- delete it', 'n'): | 4918 if not is_interactive() or ask_yes_no(dirpath + ' looks like a removed project -- delete it', 'n'): |
4750 shutil.rmtree(dirpath) | 4919 shutil.rmtree(dirpath) |
4751 log('Deleted ' + dirpath) | 4920 log('Deleted ' + dirpath) |
4752 | 4921 |
4753 def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=True): | 4922 def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=True): |
4754 """generate javadoc for some/all Java projects""" | 4923 """generate javadoc for some/all Java projects""" |
4863 projectJava = java(p.javaCompliance) | 5032 projectJava = java(p.javaCompliance) |
4864 | 5033 |
4865 # Once https://bugs.openjdk.java.net/browse/JDK-8041628 is fixed, | 5034 # Once https://bugs.openjdk.java.net/browse/JDK-8041628 is fixed, |
4866 # this should be reverted to: | 5035 # this should be reverted to: |
4867 # javadocExe = java().javadoc | 5036 # javadocExe = java().javadoc |
5037 # we can then also respect _opts.relatex_compliance | |
4868 javadocExe = projectJava.javadoc | 5038 javadocExe = projectJava.javadoc |
4869 | 5039 |
4870 run([javadocExe, memory, | 5040 run([javadocExe, memory, |
4871 '-XDignore.symbol.file', | 5041 '-XDignore.symbol.file', |
4872 '-classpath', cp, | 5042 '-classpath', cp, |
5083 | 5253 |
5084 """ | 5254 """ |
5085 if len(items) <= 1: | 5255 if len(items) <= 1: |
5086 return items | 5256 return items |
5087 else: | 5257 else: |
5258 assert is_interactive() | |
5259 numlen = str(len(str(len(items)))) | |
5088 if allowMultiple: | 5260 if allowMultiple: |
5089 log('[0] <all>') | 5261 log(('[{0:>' + numlen + '}] <all>').format(0)) |
5090 for i in range(0, len(items)): | 5262 for i in range(0, len(items)): |
5091 if descriptions is None: | 5263 if descriptions is None: |
5092 log('[{0}] {1}'.format(i + 1, items[i])) | 5264 log(('[{0:>' + numlen + '}] {1}').format(i + 1, items[i])) |
5093 else: | 5265 else: |
5094 assert len(items) == len(descriptions) | 5266 assert len(items) == len(descriptions) |
5095 wrapper = textwrap.TextWrapper(subsequent_indent=' ') | 5267 wrapper = textwrap.TextWrapper(subsequent_indent=' ') |
5096 log('\n'.join(wrapper.wrap('[{0}] {1} - {2}'.format(i + 1, items[i], descriptions[i])))) | 5268 log('\n'.join(wrapper.wrap(('[{0:>' + numlen + '}] {1} - {2}').format(i + 1, items[i], descriptions[i])))) |
5097 while True: | 5269 while True: |
5098 if allowMultiple: | 5270 if allowMultiple: |
5099 s = raw_input('Enter number(s) of selection (separate multiple choices with spaces): ').split() | 5271 s = raw_input('Enter number(s) of selection (separate multiple choices with spaces): ').split() |
5100 else: | 5272 else: |
5101 s = [raw_input('Enter number of selection: ')] | 5273 s = [raw_input('Enter number of selection: ')] |
5263 _show_section('distributions', s.dists) | 5435 _show_section('distributions', s.dists) |
5264 | 5436 |
5265 def ask_yes_no(question, default=None): | 5437 def ask_yes_no(question, default=None): |
5266 """""" | 5438 """""" |
5267 assert not default or default == 'y' or default == 'n' | 5439 assert not default or default == 'y' or default == 'n' |
5268 if not sys.stdout.isatty(): | 5440 if not is_interactive(): |
5269 if default: | 5441 if default: |
5270 return default | 5442 return default |
5271 else: | 5443 else: |
5272 abort("Can not answer '" + question + "?' if stdout is not a tty") | 5444 abort("Can not answer '" + question + "?' if stdout is not a tty") |
5273 questionMark = '? [yn]: ' | 5445 questionMark = '? [yn]: ' |
5393 abort('no primary suite found') | 5565 abort('no primary suite found') |
5394 | 5566 |
5395 opts, commandAndArgs = _argParser._parse_cmd_line() | 5567 opts, commandAndArgs = _argParser._parse_cmd_line() |
5396 assert _opts == opts | 5568 assert _opts == opts |
5397 | 5569 |
5398 global _java_homes | |
5399 defaultJdk = JavaConfig(opts.java_home, opts.java_dbg_port) | |
5400 _java_homes = [defaultJdk] | |
5401 if opts.extra_java_homes: | |
5402 for java_home in opts.extra_java_homes.split(os.pathsep): | |
5403 extraJdk = JavaConfig(java_home, opts.java_dbg_port) | |
5404 if extraJdk.javaCompliance > defaultJdk.javaCompliance: | |
5405 abort('Secondary JDK ' + extraJdk.jdk + ' has higher compliance level than default JDK ' + defaultJdk.jdk) | |
5406 _java_homes.append(extraJdk) | |
5407 | |
5408 for s in suites(): | 5570 for s in suites(): |
5409 s._post_init(opts) | 5571 s._post_init(opts) |
5410 | 5572 |
5411 if len(commandAndArgs) == 0: | 5573 if len(commandAndArgs) == 0: |
5412 _argParser.print_help() | 5574 _argParser.print_help() |