Skip to content

Commit

Permalink
[GR-46197] Added remove_jdks.py.
Browse files Browse the repository at this point in the history
PullRequest: mx/1614
  • Loading branch information
dougxc committed May 23, 2023
2 parents 62001df + 2ef98fb commit a2aa0ae
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 59 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ eclipse-launches
/java/*/.checkstyle
/java/*/.factorypath
/java/*.dist/
/.src-rev
2 changes: 1 addition & 1 deletion mx.py
Original file line number Diff line number Diff line change
Expand Up @@ -18446,7 +18446,7 @@ def alarm_handler(signum, frame):
abort(1, killsig=signal.SIGINT)

# The version must be updated for every PR (checked in CI) and the comment should reflect the PR's issue
version = VersionSpec("6.23.7") # GR-45977: Add --deferred-tty option to mx benchmark to print output only at the end of the command.
version = VersionSpec("6.23.8") # GR-46197 - add remove_jdks.py

currentUmask = None
_mx_start_datetime = datetime.utcnow()
Expand Down
59 changes: 59 additions & 0 deletions remove_jdks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
# ----------------------------------------------------------------------------------------------------
#
# Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# ----------------------------------------------------------------------------------------------------

from argparse import ArgumentParser
import os, shutil
import select_jdk

if __name__ == '__main__':
parser = ArgumentParser(prog='remove_jdks', usage='%(prog)s [options]' + """
Removes JDKs available to the select_jdk command.""")

parser.add_argument('-f', '--force', action='store_true', help='remove selected JDKs without confirmation')
args = parser.parse_args()

jdks = select_jdk.choose_jdks()
if jdks:
for jdk in jdks:
jdk_base = jdk.java_home
if jdk_base.endswith('/Contents/Home'):
jdk_base = jdk_base[0:-len('/Contents/Home')]
if not args.force:
answer = input(f'Remove {jdk_base}? [Yn]> ')
if answer not in ('', 'Y', 'y'):
continue
tmp_jdk_base = f'{jdk_base}.{os.getpid()}'
try:
# Move the directory to a new name to make the
# removal as atomic as possible from the perspective
# of other processes.
os.rename(jdk_base, tmp_jdk_base)
except OSError as e:
print(e)
continue
print(f'Removing {jdk_base}... ', end='')
shutil.rmtree(tmp_jdk_base)
print(' done')
123 changes: 65 additions & 58 deletions select_jdk.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# ----------------------------------------------------------------------------------------------------
#
# Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -29,6 +29,8 @@
from os.path import exists, expanduser, join, isdir, isfile, realpath, dirname, abspath, basename, getmtime
from io import StringIO

default_jdk_cache_path = join(expanduser('~'), '.mx', 'jdk_cache')

def is_valid_jdk(jdk):
"""
Determines if `jdk` looks like a valid JDK directory.
Expand Down Expand Up @@ -243,6 +245,64 @@ def sort_key(self):
def __lt__(self, other):
return self.sort_key() < other.sort_key()

def choose_jdks(jdk_cache_path=default_jdk_cache_path, only_list=False):
jdks = {}
if exists(jdk_cache_path):
with open(jdk_cache_path) as fp:
line_num = 1
for line in fp.readlines():
jdk = JDKInfo.load_from_jdk_cache(line.strip(), jdk_cache_path, line_num)
line_num += 1
if jdk:
jdks[jdk.java_home] = jdk
base_dir = dirname(jdk.java_home)
if base_dir.endswith('/Contents/Home'):
base_dir = base_dir[0:-len('/Contents/Home')]
for java_home in find_jdks_in(base_dir):
if java_home not in jdks:
jdks[java_home] = JDKInfo.for_java_home(java_home)
for java_home in find_system_jdks():
if java_home not in jdks:
jdks[java_home] = JDKInfo.for_java_home(java_home)

sorted_jdks = sorted(jdks.values())
choices = list(enumerate(sorted_jdks))
col2_width = max(((len(jdk.name + '-' + jdk.java_specification_version)) for jdk in sorted_jdks)) + 1
col3_width = max(((len(jdk.java_vm_version)) for jdk in sorted_jdks)) + 1
if choices:
tmp_cache_path_fd, tmp_cache_path = tempfile.mkstemp(dir=dirname(jdk_cache_path))
# Windows will complain about tmp_cache_path being in use by another process
# when calling os.rename if we don't close the file descriptor.
os.close(tmp_cache_path_fd)

java_home = os.environ.get('JAVA_HOME', '')
extra_java_homes = os.environ.get('EXTRA_JAVA_HOMES', '').split(os.pathsep)
with open(tmp_cache_path, 'w') as fp:
for index, jdk in choices:
col1 = f'[{index}]'
col2 = f'{jdk.name}-{jdk.java_specification_version}'
col3 = jdk.java_vm_version
col4 = jdk.java_home
if only_list:
print(f'{col2:{col2_width}} {col3:{col3_width}} {col4}')
else:
line = f'{col1:>5} {col2:{col2_width}} {col3:{col3_width}} {col4}'
if jdk.java_home == java_home:
line = colorize(f'{line} {{JAVA_HOME}}', 'green')
elif jdk.java_home in extra_java_homes:
line = colorize(f'{line} {{EXTRA_JAVA_HOMES[{extra_java_homes.index(jdk.java_home)}]}}', 'cyan')
print(line)
print(f'{jdk.as_jdk_cache_line()}', file=fp)
if only_list:
os.unlink(tmp_cache_path)
else:
os.unlink(jdk_cache_path)
os.rename(tmp_cache_path, jdk_cache_path)
choices = {str(index):jdk for index, jdk in choices}
jdks = [choices[n] for n in input('Select JDK(s) (separate multiple choices by whitespace)> ').split() if n in choices]
if jdks:
return jdks

if __name__ == '__main__':
parser = ArgumentParser(prog='select_jdk', usage='%(prog)s [options] [<primary jdk> [<secondary jdk>...]]' + """
Selects values for the JAVA_HOME, EXTRA_JAVA_HOMES and PATH environment variables based on
Expand Down Expand Up @@ -297,7 +357,7 @@ def __lt__(self, other):
else:
args.shell = 'sh'

jdk_cache_path = join(expanduser('~'), '.mx', 'jdk_cache')
jdk_cache_path = default_jdk_cache_path
if len(args.jdks) != 0:
if args.list:
print('warning: ignore --list option since JDKs were specified on the command line')
Expand All @@ -313,59 +373,6 @@ def __lt__(self, other):
print(f'{jdk.as_jdk_cache_line()}', file=fp)
apply_selection(args, abspath(args.jdks[0]), [abspath(a) for a in args.jdks[1:]])
else:
jdks = {}
if exists(jdk_cache_path):
with open(jdk_cache_path) as fp:
line_num = 1
for line in fp.readlines():
jdk = JDKInfo.load_from_jdk_cache(line.strip(), jdk_cache_path, line_num)
line_num += 1
if jdk:
jdks[jdk.java_home] = jdk
base_dir = dirname(jdk.java_home)
if base_dir.endswith('/Contents/Home'):
base_dir = base_dir[0:-len('/Contents/Home')]
for java_home in find_jdks_in(base_dir):
if java_home not in jdks:
jdks[java_home] = JDKInfo.for_java_home(java_home)
for java_home in find_system_jdks():
if java_home not in jdks:
jdks[java_home] = JDKInfo.for_java_home(java_home)

sorted_jdks = sorted(jdks.values())
choices = list(enumerate(sorted_jdks))
col2_width = max(((len(jdk.name + '-' + jdk.java_specification_version)) for jdk in sorted_jdks)) + 1
col3_width = max(((len(jdk.java_vm_version)) for jdk in sorted_jdks)) + 1
if choices:
tmp_cache_path_fd, tmp_cache_path = tempfile.mkstemp(dir=dirname(jdk_cache_path))
# Windows will complain about tmp_cache_path being in use by another process
# when calling os.rename if we don't close the file descriptor.
os.close(tmp_cache_path_fd)

java_home = os.environ.get('JAVA_HOME', '')
extra_java_homes = os.environ.get('EXTRA_JAVA_HOMES', '').split(os.pathsep)
with open(tmp_cache_path, 'w') as fp:
for index, jdk in choices:
col1 = f'[{index}]'
col2 = f'{jdk.name}-{jdk.java_specification_version}'
col3 = jdk.java_vm_version
col4 = jdk.java_home
if args.list:
print(f'{col2:{col2_width}} {col3:{col3_width}} {col4}')
else:
line = f'{col1:>5} {col2:{col2_width}} {col3:{col3_width}} {col4}'
if jdk.java_home == java_home:
line = colorize(f'{line} {{JAVA_HOME}}', 'green')
elif jdk.java_home in extra_java_homes:
line = colorize(f'{line} {{EXTRA_JAVA_HOMES[{extra_java_homes.index(jdk.java_home)}]}}', 'cyan')
print(line)
print(f'{jdk.as_jdk_cache_line()}', file=fp)
if args.list:
os.unlink(tmp_cache_path)
else:
os.unlink(jdk_cache_path)
os.rename(tmp_cache_path, jdk_cache_path)
choices = {str(index):jdk for index, jdk in choices}
jdks = [choices[n] for n in input('Select JDK(s) (separate multiple choices by whitespace)> ').split() if n in choices]
if jdks:
apply_selection(args, jdks[0].java_home, [jdk.java_home for jdk in jdks[1:]])
jdks = choose_jdks(jdk_cache_path, args.list)
if jdks:
apply_selection(args, jdks[0].java_home, [jdk.java_home for jdk in jdks[1:]])

0 comments on commit a2aa0ae

Please sign in to comment.