|
| 1 | +import os |
| 2 | +import platform |
| 3 | +import subprocess |
| 4 | +import sys |
| 5 | +from pathlib import Path |
| 6 | +import re |
| 7 | +from typing import List |
| 8 | + |
| 9 | +import os_release |
| 10 | + |
| 11 | + |
| 12 | +def log_debug(msg): |
| 13 | + if 'CCM_JAVA8_DEBUG' in os.environ: |
| 14 | + print(msg, file=sys.stderr) |
| 15 | + |
| 16 | + |
| 17 | +def get_java_env(): |
| 18 | + (java_bin_path, loc) = (f'{os.environ["JAVA_HOME"]}/bin/java', 'in JAVA_HOME') if 'JAVA_HOME' in os.environ else ('java', 'on PATH') |
| 19 | + |
| 20 | + try: |
| 21 | + current_version = subprocess.check_output([java_bin_path, '-version'], stderr=subprocess.STDOUT).decode('utf-8').split('\n')[0] |
| 22 | + if 'version "1.8.' in current_version: |
| 23 | + return {} |
| 24 | + |
| 25 | + log_debug(f'Java {loc} is: {current_version}.') |
| 26 | + |
| 27 | + except (subprocess.CalledProcessError, FileNotFoundError): |
| 28 | + log_debug(f'Java not found {loc}') |
| 29 | + pass |
| 30 | + |
| 31 | + system = platform.system() |
| 32 | + |
| 33 | + if system == 'Darwin': # ie, macOS (for all intents and purposes) |
| 34 | + return { |
| 35 | + 'JAVA_HOME': subprocess.check_output(['/usr/libexec/java_home', '-v', '1.8']).decode('utf-8').strip() |
| 36 | + } |
| 37 | + |
| 38 | + elif system == 'Linux': |
| 39 | + current_release = os_release.current_release() |
| 40 | + |
| 41 | + def handle_jvms(jvms: List, type) -> dict: |
| 42 | + jvms = [str(jvm) for jvm in jvms] |
| 43 | + |
| 44 | + if len(jvms) > 1: |
| 45 | + log_debug(f'Found multiple Java 8 {type}s: {dict(enumerate(jvms, start=1))}. Using the first {type}.') |
| 46 | + |
| 47 | + elif len(jvms) == 0: |
| 48 | + raise Exception(f'Java 8 {type} not found.') |
| 49 | + |
| 50 | + return { |
| 51 | + 'JAVA_HOME': jvms[0] |
| 52 | + } |
| 53 | + |
| 54 | + if current_release.is_like('arch'): # Arch Linux (and derivatives) |
| 55 | + installs = list(Path('/usr/lib/jvm').glob("java-8*")) |
| 56 | + |
| 57 | + return handle_jvms(installs, 'installation') |
| 58 | + |
| 59 | + elif current_release.is_like('debian'): # Debian-based distros (any that uses `update-alternatives`) |
| 60 | + alternatives = subprocess.check_output(['update-alternatives', '--list', 'java']).decode('utf-8').split('\n') |
| 61 | + alternatives = [alt.strip('/bin/java') for alt in alternatives if "-8-" in alt] |
| 62 | + |
| 63 | + return handle_jvms(alternatives, 'alternative') |
| 64 | + |
| 65 | + elif current_release.is_like('rhel'): # RHEL-based distros |
| 66 | + alternatives = subprocess.check_output(['alternatives', '--display', 'java']).decode('utf-8').split('\n') |
| 67 | + |
| 68 | + regex = re.compile(r'^(?P<path>/usr/lib/jvm/.*(-8-|-1.8.0-).*)/bin/java.*') |
| 69 | + |
| 70 | + alternatives = [match.group('path') for match in filter(None, map(regex.match, alternatives))] |
| 71 | + |
| 72 | + return handle_jvms(alternatives, 'alternative') |
| 73 | + |
| 74 | + else: |
| 75 | + raise Exception(f'Automatic Java 8 environment configuration not available for this distribution ({current_release.id}).') |
| 76 | + |
| 77 | + # TODO: implement other platform support here |
| 78 | + |
| 79 | + else: |
| 80 | + raise Exception(f'Automatic Java 8 environment configuration not available for this platform ({system}).') |
| 81 | + |
| 82 | + |
| 83 | +def set_java_env(): |
| 84 | + env = get_java_env() |
| 85 | + log_debug(f'New Java 8 environment: {env}') |
| 86 | + os.environ.update(env) |
| 87 | + |
| 88 | + |
| 89 | +if __name__ == '__main__': |
| 90 | + os.environ['CCM_JAVA8_DEBUG'] = 'please' |
| 91 | + set_java_env() |
0 commit comments