From 4eb4af55dbbf88d8135d7adf8b88cfce39655340 Mon Sep 17 00:00:00 2001 From: tgodzik Date: Thu, 12 Dec 2024 16:34:44 +0100 Subject: [PATCH] improvement: Allow to override mtals java home Peviously, if use had JAVA_HOME and java on PATH pointing to JDK 11, we would download JDK 17 using coursier. This however might not work if there is no internet and there was no way to work around that. Now, we allow users to specify an override for those cases. Fixes https://github.com/scalameta/metals-vscode/issues/1558 --- .../src/detectLaunchConfigurationChanges.ts | 1 + .../src/interfaces/UserConfiguration.ts | 4 ++++ packages/metals-languageclient/src/setupCoursier.ts | 12 +++++++++--- packages/metals-vscode/package.json | 5 +++++ packages/metals-vscode/src/extension.ts | 2 ++ packages/metals-vscode/src/util.ts | 7 +++++++ 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/metals-languageclient/src/detectLaunchConfigurationChanges.ts b/packages/metals-languageclient/src/detectLaunchConfigurationChanges.ts index 5d12a9ae..8f809714 100644 --- a/packages/metals-languageclient/src/detectLaunchConfigurationChanges.ts +++ b/packages/metals-languageclient/src/detectLaunchConfigurationChanges.ts @@ -17,6 +17,7 @@ export function detectLaunchConfigurationChanges( UserConfiguration.ServerVersion, UserConfiguration.ServerProperties, UserConfiguration.JavaVersion, + UserConfiguration.MetalsJavaHome, UserConfiguration.CustomRepositories, UserConfiguration.CoursierMirror, ...additionalRestartKeys, diff --git a/packages/metals-languageclient/src/interfaces/UserConfiguration.ts b/packages/metals-languageclient/src/interfaces/UserConfiguration.ts index 8bef69ab..a0bcc38e 100644 --- a/packages/metals-languageclient/src/interfaces/UserConfiguration.ts +++ b/packages/metals-languageclient/src/interfaces/UserConfiguration.ts @@ -16,6 +16,10 @@ export enum UserConfiguration { * Java version. Can be one of 8, 11, 17, 21. */ JavaVersion = "javaVersion", + /** + * Java Home to be used by Metals instead of it inferring using javaVersion. + */ + MetalsJavaHome = "metalsJavaHome", /** * Additional repositories that can be used to download dependencies. * https://get-coursier.io/docs/other-repositories diff --git a/packages/metals-languageclient/src/setupCoursier.ts b/packages/metals-languageclient/src/setupCoursier.ts index 54cc3195..d00acf90 100644 --- a/packages/metals-languageclient/src/setupCoursier.ts +++ b/packages/metals-languageclient/src/setupCoursier.ts @@ -23,6 +23,7 @@ const coursierCommit = "11b428f35ca84a598ca30cce1c35ae4f375e5ee3"; export async function setupCoursier( javaVersion: JavaVersion, + javaHomeOverride: string | undefined, coursierFetchPath: string, extensionPath: string, output: OutputChannel, @@ -106,7 +107,13 @@ export async function setupCoursier( } output.appendLine(`Using coursier located at ${coursier}`); - var javaHome = await getJavaHome(javaVersion, output); + var javaHome: JavaHome | undefined; + + if (javaHomeOverride) { + javaHome = await validateJavaVersion(javaHomeOverride, javaVersion, output); + } else { + javaHome = await getJavaHome(javaVersion, output); + } if (!javaHome && coursier) { output.appendLine( @@ -136,8 +143,7 @@ export async function setupCoursier( else throw Error( `Cannot resolve Java home or coursier, JAVA_HOME should exist with a version of at least ${javaVersion}.` + - `Alternatively, you can reduce the requirement using "metals.javaVersion" setting.` - ); + `Alternatively, you can reduce the requirement using "metals.javaVersion" setting override the path using metals.metalsJavaHome setting." } export async function validateCoursier( diff --git a/packages/metals-vscode/package.json b/packages/metals-vscode/package.json index 20960297..ce352455 100644 --- a/packages/metals-vscode/package.json +++ b/packages/metals-vscode/package.json @@ -279,6 +279,11 @@ "scope": "machine-overridable", "markdownDescription": "Optional path to the Java home directory that will be used for compiling the project.\n\nDefaults to JDK used by Metals's server (look: Java Version).\n\nThis Java version should be lower or equal to JDK version used by the Metals's server." }, + "metals.metalsJavaHome": { + "type": "string", + "scope": "machine", + "markdownDescription": "Optional path to the Java home directory that will be used for the running Metals server.\n\nBy default Metals will try to infer it using the version specified in metals.javaVersion.\n\nThis Java version should be higher than 17." + }, "metals.javaVersion": { "type": "string", "default": "17", diff --git a/packages/metals-vscode/src/extension.ts b/packages/metals-vscode/src/extension.ts index c17d2547..2f4be6d3 100644 --- a/packages/metals-vscode/src/extension.ts +++ b/packages/metals-vscode/src/extension.ts @@ -86,6 +86,7 @@ import { decodeAndShowFile, MetalsFileProvider } from "./metalsContentProvider"; import { currentWorkspaceFolder, getJavaVersionFromConfig, + getJavaVersionOverride, getTextDocumentPositionParams, getValueFromConfig, metalsDir, @@ -230,6 +231,7 @@ async function fetchAndLaunchMetals( const { coursier, javaHome } = await metalsLanguageClient.setupCoursier( javaVersion, + getJavaVersionOverride(), metalsDirPath, context.extensionPath, outputChannel, diff --git a/packages/metals-vscode/src/util.ts b/packages/metals-vscode/src/util.ts index 7e8ab080..ca09c97a 100644 --- a/packages/metals-vscode/src/util.ts +++ b/packages/metals-vscode/src/util.ts @@ -115,6 +115,13 @@ export function getJavaVersionFromConfig() { return undefined; } +export function getJavaVersionOverride(): string | undefined { + return workspace + .getConfiguration("metals") + .get(UserConfiguration.MetalsJavaHome) + ?.trim(); +} + export async function fetchFrom( url: string, options?: http.RequestOptions