Mercurial > hg > graal-jvmci-8
comparison mxtool/mx.py @ 21976:36e37644f91e
mx: improve first usage experience:
Create mx.ask_persist_env to handle env file modifications, make it deal with files missing final newline
Use mx.ask_persist_env to persist the DEFAULT_VM
Make mx_graal specify its version restrictions when asking for the default JDK
When selecting versions manually or automatically, use JDKs from JAVA_HOME first, then from EXTRA_JAVA_HOMES, then from standard locations, then sort by version.
Even if EXTRA_JAVA_HOMES is already defained, let the user decide which JAVA_HOME to use
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Fri, 12 Jun 2015 16:51:32 +0200 |
parents | 290a87b718e1 |
children | a6425aa8f70c |
comparison
equal
deleted
inserted
replaced
21975:290a87b718e1 | 21976:36e37644f91e |
---|---|
1785 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) | 1785 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) |
1786 return msg + '\n' | 1786 return msg + '\n' |
1787 | 1787 |
1788 _canceled_java_requests = set() | 1788 _canceled_java_requests = set() |
1789 | 1789 |
1790 def java(requiredCompliance=None, purpose=None, cancel=None): | 1790 def java(versionCheck=None, purpose=None, cancel=None, versionDescription=None, defaultJdk=None): |
1791 """ | 1791 """ |
1792 Get a JavaConfig object containing Java commands launch details. | 1792 Get a JavaConfig object containing Java commands launch details. |
1793 If requiredCompliance is None, the compliance level specified by --java-home/JAVA_HOME | 1793 """ |
1794 is returned. Otherwise, the JavaConfig exactly matching requiredCompliance is returned | 1794 |
1795 or None if there is no exact match. | 1795 if defaultJdk is None: |
1796 """ | 1796 defaultJdk = versionCheck is None and not purpose |
1797 | 1797 |
1798 global _default_java_home | 1798 # interpret string and compliance as compliance check |
1799 if cancel and (requiredCompliance, purpose) in _canceled_java_requests: | 1799 if isinstance(versionCheck, types.StringTypes): |
1800 requiredCompliance = JavaCompliance(versionCheck) | |
1801 versionCheck, versionDescription = _convert_complicance_to_version_check(requiredCompliance) | |
1802 elif isinstance(versionCheck, JavaCompliance): | |
1803 versionCheck, versionDescription = _convert_complicance_to_version_check(versionCheck) | |
1804 | |
1805 global _default_java_home, _extra_java_homes | |
1806 if cancel and (versionDescription, purpose) in _canceled_java_requests: | |
1800 return None | 1807 return None |
1801 | 1808 |
1802 if not requiredCompliance: | 1809 if defaultJdk: |
1803 if not _default_java_home: | 1810 if not _default_java_home: |
1804 _default_java_home = _find_jdk(purpose=purpose, cancel=cancel) | 1811 _default_java_home = _find_jdk(versionCheck=versionCheck, versionDescription=versionDescription, purpose=purpose, cancel=cancel, isDefaultJdk=True) |
1805 if not _default_java_home: | 1812 if not _default_java_home: |
1806 assert cancel | 1813 assert cancel and (versionDescription or purpose) |
1807 _canceled_java_requests.add((requiredCompliance, purpose)) | 1814 _canceled_java_requests.add((versionDescription, purpose)) |
1808 return _default_java_home | 1815 return _default_java_home |
1809 | 1816 |
1810 if _opts.strict_compliance: | |
1811 complianceCheck = requiredCompliance.exactMatch | |
1812 desc = str(requiredCompliance) | |
1813 else: | |
1814 compVersion = VersionSpec(str(requiredCompliance)) | |
1815 complianceCheck = lambda version: version >= compVersion | |
1816 desc = '>=' + str(requiredCompliance) | |
1817 | |
1818 for java in _extra_java_homes: | 1817 for java in _extra_java_homes: |
1819 if complianceCheck(java.version): | 1818 if not versionCheck or versionCheck(java.version): |
1820 return java | 1819 return java |
1821 | 1820 |
1822 jdk = _find_jdk(versionCheck=complianceCheck, versionDescription=desc, purpose=purpose, cancel=cancel) | 1821 jdk = _find_jdk(versionCheck=versionCheck, versionDescription=versionDescription, purpose=purpose, cancel=cancel, isDefaultJdk=False) |
1823 if jdk: | 1822 if jdk: |
1824 assert jdk not in _extra_java_homes | 1823 assert jdk not in _extra_java_homes |
1825 _extra_java_homes.append(jdk) | 1824 _extra_java_homes = _sorted_unique_jdk_configs(_extra_java_homes + [jdk]) |
1826 else: | 1825 else: |
1827 assert cancel | 1826 assert cancel and (versionDescription or purpose) |
1828 _canceled_java_requests.add((requiredCompliance, purpose)) | 1827 _canceled_java_requests.add((versionDescription, purpose)) |
1829 return jdk | 1828 return jdk |
1830 | 1829 |
1831 def java_version(versionCheck, versionDescription=None, purpose=None): | 1830 def _convert_complicance_to_version_check(requiredCompliance): |
1832 if _default_java_home and versionCheck(_default_java_home.version): | 1831 if _opts.strict_compliance: |
1833 return _default_java_home | 1832 versionDesc = str(requiredCompliance) |
1834 for java in _extra_java_homes: | 1833 versionCheck = requiredCompliance.exactMatch |
1835 if versionCheck(java.version): | |
1836 return java | |
1837 jdk = _find_jdk(versionCheck, versionDescription, purpose) | |
1838 assert jdk not in _extra_java_homes | |
1839 _extra_java_homes.append(jdk) | |
1840 return jdk | |
1841 | |
1842 def _find_jdk(versionCheck=None, versionDescription=None, purpose=None, cancel=None): | |
1843 assert not versionDescription or versionCheck | |
1844 if not versionCheck and not purpose: | |
1845 isDefaultJdk = True | |
1846 else: | 1834 else: |
1847 isDefaultJdk = False | 1835 versionDesc = '>=' + str(requiredCompliance) |
1836 compVersion = VersionSpec(str(requiredCompliance)) | |
1837 versionCheck = lambda version: version >= compVersion | |
1838 return (versionCheck, versionDesc) | |
1839 | |
1840 def _find_jdk(versionCheck=None, versionDescription=None, purpose=None, cancel=None, isDefaultJdk=False): | |
1841 assert (versionDescription and versionCheck) or (not versionDescription and not versionCheck) | |
1848 if not versionCheck: | 1842 if not versionCheck: |
1849 versionCheck = lambda v: True | 1843 versionCheck = lambda v: True |
1850 | 1844 |
1851 candidateJdks = [] | 1845 candidateJdks = [] |
1852 source = '' | 1846 source = '' |
1870 candidateJdks += os.environ.get('EXTRA_JAVA_HOMES').split(os.pathsep) | 1864 candidateJdks += os.environ.get('EXTRA_JAVA_HOMES').split(os.pathsep) |
1871 source = 'EXTRA_JAVA_HOMES' | 1865 source = 'EXTRA_JAVA_HOMES' |
1872 | 1866 |
1873 result = _find_jdk_in_candidates(candidateJdks, versionCheck, warn=True, source=source) | 1867 result = _find_jdk_in_candidates(candidateJdks, versionCheck, warn=True, source=source) |
1874 if not result: | 1868 if not result: |
1875 candidateJdks = [] | 1869 configs = _find_available_jdks(versionCheck) |
1876 source = '' | 1870 elif isDefaultJdk: # we found something in EXTRA_JAVA_HOMES but we want to set JAVA_HOME, look for further options |
1877 | 1871 configs = [result] + _find_available_jdks(versionCheck) |
1878 if get_os() == 'darwin': | |
1879 base = '/Library/Java/JavaVirtualMachines' | |
1880 if exists(base): | |
1881 candidateJdks = [join(base, n, 'Contents/Home') for n in os.listdir(base)] | |
1882 elif get_os() == 'linux': | |
1883 base = '/usr/lib/jvm' | |
1884 if exists(base): | |
1885 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1886 base = '/usr/java' | |
1887 if exists(base): | |
1888 candidateJdks += [join(base, n) for n in os.listdir(base)] | |
1889 elif get_os() == 'solaris': | |
1890 base = '/usr/jdk/instances' | |
1891 if exists(base): | |
1892 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1893 elif get_os() == 'windows': | |
1894 base = r'C:\Program Files\Java' | |
1895 if exists(base): | |
1896 candidateJdks = [join(base, n) for n in os.listdir(base)] | |
1897 | |
1898 configs = _filtered_jdk_configs(candidateJdks, versionCheck) | |
1899 else: | 1872 else: |
1900 if not isDefaultJdk: | 1873 if not isDefaultJdk: |
1901 return result | 1874 return result |
1902 configs = [result] | 1875 configs = [result] |
1876 | |
1877 configs = _sorted_unique_jdk_configs(configs) | |
1903 | 1878 |
1904 if len(configs) > 1: | 1879 if len(configs) > 1: |
1905 if not is_interactive(): | 1880 if not is_interactive(): |
1906 msg = "Multiple possible choices for a JDK" | 1881 msg = "Multiple possible choices for a JDK" |
1907 if purpose: | 1882 if purpose: |
1924 msg += '(version ' + versionDescription + ')' | 1899 msg += '(version ' + versionDescription + ')' |
1925 log(msg) | 1900 log(msg) |
1926 choices = configs + ['<other>'] | 1901 choices = configs + ['<other>'] |
1927 if cancel: | 1902 if cancel: |
1928 choices.append('Cancel (' + cancel + ')') | 1903 choices.append('Cancel (' + cancel + ')') |
1904 | |
1929 selected = select_items(choices, allowMultiple=False) | 1905 selected = select_items(choices, allowMultiple=False) |
1930 if isinstance(selected, types.StringTypes) and selected == '<other>': | 1906 if isinstance(selected, types.StringTypes) and selected == '<other>': |
1931 selected = None | 1907 selected = None |
1932 if isinstance(selected, types.StringTypes) and selected == 'Cancel (' + cancel + ')': | 1908 if isinstance(selected, types.StringTypes) and selected == 'Cancel (' + cancel + ')': |
1933 return None | 1909 return None |
1953 selected = None | 1929 selected = None |
1954 | 1930 |
1955 while not selected: | 1931 while not selected: |
1956 jdkLocation = raw_input('Enter path of JDK: ') | 1932 jdkLocation = raw_input('Enter path of JDK: ') |
1957 selected = _find_jdk_in_candidates([jdkLocation], versionCheck, warn=True) | 1933 selected = _find_jdk_in_candidates([jdkLocation], versionCheck, warn=True) |
1934 if not selected: | |
1935 assert versionDescription | |
1936 log("Error: JDK at '" + jdkLocation + "' is not compatible with version " + versionDescription) | |
1958 | 1937 |
1959 varName = 'JAVA_HOME' if isDefaultJdk else 'EXTRA_JAVA_HOMES' | 1938 varName = 'JAVA_HOME' if isDefaultJdk else 'EXTRA_JAVA_HOMES' |
1960 allowMultiple = not isDefaultJdk | 1939 allowMultiple = not isDefaultJdk |
1940 valueSeparator = os.pathsep if allowMultiple else None | |
1941 ask_persist_env(varName, selected.jdk, valueSeparator) | |
1942 | |
1943 os.environ[varName] = selected.jdk | |
1944 | |
1945 return selected | |
1946 | |
1947 def ask_persist_env(varName, value, valueSeparator=None): | |
1961 envPath = join(_primary_suite.mxDir, 'env') | 1948 envPath = join(_primary_suite.mxDir, 'env') |
1962 if is_interactive() and ask_yes_no('Persist this setting by adding "{0}={1}" to {2}'.format(varName, selected.jdk, envPath), 'y'): | 1949 if is_interactive() and ask_yes_no('Persist this setting by adding "{0}={1}" to {2}'.format(varName, value, envPath), 'y'): |
1963 envLines = [] | 1950 envLines = [] |
1964 if exists(envPath): | 1951 if exists(envPath): |
1965 with open(envPath) as fp: | 1952 with open(envPath) as fp: |
1966 append = True | 1953 append = True |
1967 for line in fp: | 1954 for line in fp: |
1968 if line.rstrip().startswith(varName): | 1955 if line.rstrip().startswith(varName): |
1969 _, currentValue = line.split('=', 1) | 1956 _, currentValue = line.split('=', 1) |
1970 currentValue = currentValue.strip() | 1957 currentValue = currentValue.strip() |
1971 if not allowMultiple and currentValue: | 1958 if not valueSeparator and currentValue: |
1972 if not ask_yes_no('{0} is already set to {1}, overwrite with {2}?'.format(varName, currentValue, selected.jdk), 'n'): | 1959 if not ask_yes_no('{0} is already set to {1}, overwrite with {2}?'.format(varName, currentValue, value), 'n'): |
1973 return selected | 1960 return |
1974 else: | 1961 else: |
1975 line = varName + '=' + selected.jdk + os.linesep | 1962 line = varName + '=' + value + os.linesep |
1976 else: | 1963 else: |
1977 line = line.rstrip() | 1964 line = line.rstrip() |
1978 if currentValue: | 1965 if currentValue: |
1979 line += os.pathsep | 1966 line += valueSeparator |
1980 line += selected.jdk + os.linesep | 1967 line += value + os.linesep |
1981 append = False | 1968 append = False |
1969 if not line.endswith(os.linesep): | |
1970 line += os.linesep | |
1982 envLines.append(line) | 1971 envLines.append(line) |
1983 else: | 1972 else: |
1984 append = True | 1973 append = True |
1985 | 1974 |
1986 if append: | 1975 if append: |
1987 envLines.append(varName + '=' + selected.jdk + os.linesep) | 1976 envLines.append(varName + '=' + value + os.linesep) |
1988 | 1977 |
1989 with open(envPath, 'w') as fp: | 1978 with open(envPath, 'w') as fp: |
1990 for line in envLines: | 1979 for line in envLines: |
1991 fp.write(line) | 1980 fp.write(line) |
1992 | 1981 |
1993 if varName == 'JAVA_HOME': | 1982 _os_jdk_locations = { |
1994 os.environ['JAVA_HOME'] = selected.jdk | 1983 'darwin': { |
1995 | 1984 'bases': ['/Library/Java/JavaVirtualMachines'], |
1996 return selected | 1985 'suffix': 'Contents/Home' |
1986 }, | |
1987 'linux': { | |
1988 'bases': [ | |
1989 '/usr/lib/jvm', | |
1990 '/usr/java' | |
1991 ] | |
1992 }, | |
1993 'solaris': { | |
1994 'bases': ['/usr/jdk/instances'] | |
1995 }, | |
1996 'windows': { | |
1997 'bases': [r'C:\Program Files\Java'] | |
1998 }, | |
1999 } | |
2000 | |
2001 def _find_available_jdks(versionCheck): | |
2002 candidateJdks = [] | |
2003 os_name = get_os() | |
2004 if os_name in _os_jdk_locations: | |
2005 jdkLocations = _os_jdk_locations[os_name] | |
2006 for base in jdkLocations['bases']: | |
2007 if exists(base): | |
2008 if 'suffix' in jdkLocations: | |
2009 suffix = jdkLocations['suffix'] | |
2010 candidateJdks += [join(base, n, suffix) for n in os.listdir(base)] | |
2011 else: | |
2012 candidateJdks += [join(base, n) for n in os.listdir(base)] | |
2013 | |
2014 return _filtered_jdk_configs(candidateJdks, versionCheck) | |
2015 | |
2016 def _sorted_unique_jdk_configs(configs): | |
2017 path_seen = set() | |
2018 unique_configs = [c for c in configs if c.jdk not in path_seen and not path_seen.add(c.jdk)] | |
2019 | |
2020 def _compare_configs(c1, c2): | |
2021 if c1 == _default_java_home: | |
2022 if c2 != _default_java_home: | |
2023 return 1 | |
2024 elif c2 == _default_java_home: | |
2025 return -1 | |
2026 if c1 in _extra_java_homes: | |
2027 if c2 not in _extra_java_homes: | |
2028 return 1 | |
2029 elif c2 in _extra_java_homes: | |
2030 return -1 | |
2031 return VersionSpec.__cmp__(c1.version, c2.version) | |
2032 return sorted(unique_configs, cmp=_compare_configs, reverse=True) | |
1997 | 2033 |
1998 def is_interactive(): | 2034 def is_interactive(): |
1999 return sys.__stdin__.isatty() | 2035 return sys.__stdin__.isatty() |
2000 | 2036 |
2001 def _filtered_jdk_configs(candidates, versionCheck, warn=False, source=None): | 2037 def _filtered_jdk_configs(candidates, versionCheck, warn=False, source=None): |
2391 | 2427 |
2392 def __hash__(self): | 2428 def __hash__(self): |
2393 return hash(self.jdk) | 2429 return hash(self.jdk) |
2394 | 2430 |
2395 def __cmp__(self, other): | 2431 def __cmp__(self, other): |
2432 if other is None: | |
2433 return False | |
2396 if isinstance(other, JavaConfig): | 2434 if isinstance(other, JavaConfig): |
2397 compilanceCmp = cmp(self.javaCompliance, other.javaCompliance) | 2435 compilanceCmp = cmp(self.javaCompliance, other.javaCompliance) |
2398 if compilanceCmp: | 2436 if compilanceCmp: |
2399 return compilanceCmp | 2437 return compilanceCmp |
2400 versionCmp = cmp(self.version, other.version) | 2438 versionCmp = cmp(self.version, other.version) |