diff --git a/jps-builder/tests/org/elixir_lang/jps/BuilderTest.java b/jps-builder/tests/org/elixir_lang/jps/BuilderTest.java index 77d149ba7..dc2a4b1f3 100644 --- a/jps-builder/tests/org/elixir_lang/jps/BuilderTest.java +++ b/jps-builder/tests/org/elixir_lang/jps/BuilderTest.java @@ -21,6 +21,9 @@ import java.io.File; import java.io.IOException; +import java.io.BufferedReader; +import java.io.InputStreamReader; + /** * Created by zyuyou on 15/7/17. @@ -28,12 +31,52 @@ public class BuilderTest extends JpsBuildTestCase { private static final String TEST_MODULE_NAME = "m"; private JpsSdk elixirSdk; - + private static String otpReleaseVersion = null; + + /** + * Retrieves the OTP Release version, eg 24.3.4.6 + * This method first checks for an environment variable OTP_RELEASE (used in CI). + * If not set, it attempts to infer the version path from the erl command. + * + * @return A String representing the OTP Release version. + * @throws AssertionError if ERLANG_SDK_HOME is not set and cannot be inferred from PATH. + */ private static String otpRelease() { + if (otpReleaseVersion != null) { + return otpReleaseVersion; + } + String otpRelease = System.getenv("OTP_RELEASE"); + if (otpRelease != null && !otpRelease.isEmpty()) { + otpReleaseVersion = otpRelease; + return otpRelease; + } - assertNotNull("OTP_RELEASE is not set", otpRelease); + try { + Process process = Runtime.getRuntime().exec(new String[]{ + "erl", + "-eval", + "{ok, Version} = file:read_file(filename:join([code:root_dir(), \"releases\", erlang:system_info(otp_release), \"OTP_VERSION\"])), io:fwrite(Version), halt().", + "-noshell" + }); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + otpRelease = reader.readLine(); + } + + int exitCode = process.waitFor(); + if (exitCode != 0) { + throw new RuntimeException("Failed to get OTP release. Exit code: " + exitCode); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException("Failed to get OTP release", e); + } + if (otpRelease == null || otpRelease.isEmpty()) { + throw new RuntimeException("Failed to get OTP release"); + } + + otpReleaseVersion = otpRelease; return otpRelease; } @@ -42,11 +85,45 @@ private static String elixirSdkHome() { return sdkHomeFromEbinDirectory(ebinDirectory()); } + /** + * Retrieves the Erlang SDK home directory. + * This method first checks for an environment variable ERLANG_SDK_HOME. + * If not set, it attempts to infer the SDK home from the erl command. + * + * @return A String representing the path to the Erlang SDK home directory. + * @throws AssertionError if ERLANG_SDK_HOME is not set and cannot be retrieved from the erl command. + */ @NotNull private static String erlangSdkHome() { String erlangSdkHome = System.getenv("ERLANG_SDK_HOME"); - assertNotNull("ERLANG_SDK_HOME is not set", erlangSdkHome); + if (erlangSdkHome != null && !erlangSdkHome.isEmpty()) { + return erlangSdkHome; + } + + try { + Process process = Runtime.getRuntime().exec(new String[]{ + "erl", + "-eval", + "io:format(\"~s~n\", [code:root_dir()]), halt().", + "-noshell" + }); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + erlangSdkHome = reader.readLine(); + } + + int exitCode = process.waitFor(); + if (exitCode != 0) { + throw new RuntimeException("Failed to get Erlang SDK home. Exit code: " + exitCode); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException("Failed to get Erlang SDK home", e); + } + + if (erlangSdkHome == null || erlangSdkHome.isEmpty()) { + throw new RuntimeException("Failed to get Erlang SDK home"); + } return erlangSdkHome; }