Skip to content

Commit

Permalink
jdk is now an optional dependency; when install-jdk is not installed,…
Browse files Browse the repository at this point in the history
… RNAlysis searches for java in PATH by default
  • Loading branch information
GuyTeichman committed Jan 11, 2025
1 parent f71b935 commit 3054302
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 35 deletions.
73 changes: 43 additions & 30 deletions rnalysis/utils/installs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,69 @@
import platform
import shutil
import subprocess
import warnings
from pathlib import Path
from shutil import copyfileobj
from typing import Union, Literal
from urllib.request import urlopen

import jdk

from rnalysis.utils import io

PICARD_JAR = Path(os.environ.get('PICARDTOOLS_JAR', io.get_data_dir().joinpath('picard.jar')))
JDK_ROOT = io.get_data_dir().joinpath('jdk17')


def get_jdk_path():
# List all files and directories in the given directory
items = os.listdir(JDK_ROOT)

# Filter for directories starting with 'jdk-'
jdk_directories = sorted([item for item in items if
item.startswith('jdk-') and os.path.isdir(os.path.join(JDK_ROOT, item))], reverse=True)
if len(jdk_directories) == 0:
raise FileNotFoundError('No JDK directory found')
try:
import jdk
except ImportError: # pragma: no cover
warnings.warn("'install-jdk' not found. To use PicardTools, you would need to install JDK manually.")

base_dir = JDK_ROOT.joinpath(f'{jdk_directories[0]}')

if platform.system() == 'Windows':
pattern = "java.exe"
else:
pattern = "java"
class jdk: # pragma: no cover
@staticmethod
def install(version):
warnings.warn("Cannot install JDK.")

# Filter for files starting with 'java' or 'java.exe'
matches = list(base_dir.rglob(pattern))
if len(matches) == 0:
raise FileNotFoundError(f'No java executable found in {base_dir}')
PICARD_JAR = Path(os.environ.get('PICARDTOOLS_JAR', io.get_data_dir().joinpath('picard.jar')))
JDK_VERSION = "21"
JDK_ROOT = io.get_data_dir().joinpath(f'jdk{JDK_VERSION}')

return matches[0].parent

def get_jdk_path():
try:
if platform.system() == 'Windows':
pattern = "java.exe"
else:
pattern = "java"
# List all files and directories in the given directory
items = os.listdir(JDK_ROOT)
# Filter for directories starting with 'jdk-'
jdk_directories = sorted([item for item in items if
item.startswith('jdk-') and os.path.isdir(os.path.join(JDK_ROOT, item))],
reverse=True)
if len(jdk_directories) == 0:
raise FileNotFoundError('No JDK directory found')
base_dir = JDK_ROOT.joinpath(f'{jdk_directories[0]}')

# Filter for files starting with 'java' or 'java.exe'
matches = list(base_dir.rglob(pattern))
if len(matches) == 0:
raise FileNotFoundError(f'No java executable found in {base_dir}')
return matches[0].parent
except FileNotFoundError:
# find jdk installation in PATH
return ""

def is_jdk_installed():
try:
if not JDK_ROOT.exists():
return False
# Run the "java -version" command and capture the output
jdk_path = get_jdk_path()
output = subprocess.check_output([f'{jdk_path}/java', "-version"], stderr=subprocess.STDOUT, text=True)
# Check if the output contains "version 17" or "17." (for Java 17)
if "version 17" in output or " 17." in output:
output = subprocess.check_output(
[Path(jdk_path).joinpath("java").as_posix(), "-version"],
stderr=subprocess.STDOUT, text=True)
# Check if the output contains "version X" or "X." (for Java X)
if f"version {JDK_VERSION}" in output or f" {JDK_VERSION}." in output:
return True
except (subprocess.CalledProcessError, FileNotFoundError):
# If the "java -version" command returns an error, Java 17 is not installed.
# If the "java -version" command returns an error, Java X is not installed.
return False
return False

Expand All @@ -62,7 +75,7 @@ def install_jdk():
if JDK_ROOT.exists():
shutil.rmtree(JDK_ROOT)
JDK_ROOT.mkdir(parents=True, exist_ok=True)
jdk.install('17', path=JDK_ROOT.as_posix())
jdk.install(str(JDK_VERSION), path=JDK_ROOT.as_posix())
print('Done')


Expand Down
10 changes: 5 additions & 5 deletions tests/test_installs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from rnalysis.utils.installs import *

# Constants for mocking
MOCK_JDK_DIRS = ['jdk-17.0.1', 'jdk-16', 'jdk-15']
MOCK_JDK_VERSION_OUTPUT = "java version 17"
MOCK_JDK_DIRS = [f'jdk-{installs.JDK_VERSION}.0.1', 'jdk-16', 'jdk-15']
MOCK_JDK_VERSION_OUTPUT = f"java version {installs.JDK_VERSION}"


@pytest.fixture
Expand All @@ -28,8 +28,7 @@ def test_get_jdk_path_success(monkeypatch):

def test_get_jdk_path_failure(monkeypatch):
monkeypatch.setattr('os.listdir', lambda x: [])
with pytest.raises(FileNotFoundError):
get_jdk_path()
assert get_jdk_path() == ""


# Test is_jdk_installed
Expand All @@ -44,7 +43,8 @@ def test_is_jdk_installed_failure_no_dir(monkeypatch):

def test_is_jdk_installed_failure_wrong_version(monkeypatch):
monkeypatch.setattr('pathlib.Path.exists', lambda self: True)
monkeypatch.setattr('subprocess.check_output', lambda *args, **kwargs: MOCK_JDK_VERSION_OUTPUT.replace('17', '15'))
monkeypatch.setattr('subprocess.check_output',
lambda *args, **kwargs: MOCK_JDK_VERSION_OUTPUT.replace(str(installs.JDK_VERSION), '15'))
assert not is_jdk_installed()


Expand Down

0 comments on commit 3054302

Please sign in to comment.