*.gradle.kts: get java home from build environment instead of execution settings
Note that getting GradleExecutionSettings may lead to write action because it link javaHome with existing sdks ^KT-39317
This commit is contained in:
+21
-15
@@ -46,7 +46,7 @@ import kotlin.script.templates.standard.ScriptTemplateWithArgs
|
||||
|
||||
class GradleScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionSourceAsContributor {
|
||||
companion object {
|
||||
fun getDefinitions(project: Project, workingDir: String, gradleHome: String?): List<ScriptDefinition>? {
|
||||
fun getDefinitions(project: Project, workingDir: String, gradleHome: String?, javaHome: String?): List<ScriptDefinition>? {
|
||||
val contributor = ScriptDefinitionContributor.EP_NAME.getExtensions(project)
|
||||
.filterIsInstance<GradleScriptDefinitionsContributor>()
|
||||
.singleOrNull()
|
||||
@@ -63,7 +63,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
return null
|
||||
}
|
||||
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome)
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome, javaHome)
|
||||
val definitions = contributor.definitionsByRoots[root]
|
||||
if (definitions == null) {
|
||||
scriptingInfoLog(
|
||||
@@ -128,7 +128,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
|
||||
override val id: String = "Gradle Kotlin DSL"
|
||||
|
||||
private data class LightGradleBuildRoot(val workingDir: String, val gradleHome: String?)
|
||||
private data class LightGradleBuildRoot(val workingDir: String, val gradleHome: String?, val javaHome: String?)
|
||||
|
||||
private val definitionsByRoots = ConcurrentHashMap<LightGradleBuildRoot, List<ScriptDefinition>>()
|
||||
|
||||
@@ -148,8 +148,8 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
}
|
||||
|
||||
// TODO: remove old roots
|
||||
fun reloadIfNeeded(workingDir: String, gradleHome: String?) {
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome)
|
||||
fun reloadIfNeeded(workingDir: String, gradleHome: String?, javaHome: String?) {
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome, javaHome)
|
||||
val value = definitionsByRoots[root]
|
||||
if (value != null) {
|
||||
if (root.isError()) {
|
||||
@@ -177,15 +177,17 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
loadGradleTemplates(
|
||||
projectPath,
|
||||
templateClass = "org.gradle.kotlin.dsl.KotlinInitScript",
|
||||
root.gradleHome,
|
||||
templateClasspath,
|
||||
additionalClassPath
|
||||
gradleHome = root.gradleHome,
|
||||
javaHome = root.javaHome,
|
||||
templateClasspath = templateClasspath,
|
||||
additionalClassPath = additionalClassPath
|
||||
).let { kotlinDslTemplates.addAll(it) }
|
||||
|
||||
loadGradleTemplates(
|
||||
projectPath,
|
||||
templateClass = "org.gradle.kotlin.dsl.KotlinSettingsScript",
|
||||
gradleHome = root.gradleHome,
|
||||
javaHome = root.javaHome,
|
||||
templateClasspath = templateClasspath,
|
||||
additionalClassPath = additionalClassPath
|
||||
).let { kotlinDslTemplates.addAll(it) }
|
||||
@@ -195,6 +197,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
projectPath,
|
||||
templateClass = "org.gradle.kotlin.dsl.KotlinBuildScript",
|
||||
gradleHome = root.gradleHome,
|
||||
javaHome = root.javaHome,
|
||||
templateClasspath = templateClasspath,
|
||||
additionalClassPath = additionalClassPath
|
||||
).let { kotlinDslTemplates.addAll(it) }
|
||||
@@ -223,6 +226,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
projectPath: String,
|
||||
templateClass: String,
|
||||
gradleHome: String?,
|
||||
javaHome: String?,
|
||||
templateClasspath: List<File>,
|
||||
additionalClassPath: List<File>
|
||||
): List<ScriptDefinition> {
|
||||
@@ -231,7 +235,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
projectPath,
|
||||
GradleConstants.SYSTEM_ID
|
||||
)
|
||||
val hostConfiguration = createHostConfiguration(projectPath, gradleHome, gradleExeSettings)
|
||||
val hostConfiguration = createHostConfiguration(projectPath, gradleHome, javaHome, gradleExeSettings)
|
||||
return loadDefinitionsFromTemplates(
|
||||
listOf(templateClass),
|
||||
templateClasspath,
|
||||
@@ -253,6 +257,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
private fun createHostConfiguration(
|
||||
projectPath: String,
|
||||
gradleHome: String?,
|
||||
javaHome: String?,
|
||||
gradleExeSettings: GradleExecutionSettings
|
||||
): ScriptingHostConfiguration {
|
||||
val gradleJvmOptions = gradleExeSettings.daemonVmOptions?.let { vmOptions ->
|
||||
@@ -264,7 +269,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
|
||||
val environment = mapOf(
|
||||
"gradleHome" to gradleHome?.let(::File),
|
||||
"gradleJavaHome" to gradleExeSettings.javaHome, // TODO: should be taken from information from gradle sync
|
||||
"gradleJavaHome" to javaHome,
|
||||
|
||||
"projectRoot" to projectPath.let(::File),
|
||||
|
||||
@@ -317,19 +322,20 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
// otherwise KotlinDslSyncListener should run reloadIfNeeded for valid roots
|
||||
GradleBuildRootsManager.getInstance(project).getAllRoots().forEach {
|
||||
val workingDir = it.pathPrefix
|
||||
val gradleHome = when (it) {
|
||||
val (gradleHome, javaHome) = when (it) {
|
||||
is Imported -> {
|
||||
it.data.gradleHome
|
||||
it.data.gradleHome to it.data.javaHome
|
||||
}
|
||||
is WithoutScriptModels -> {
|
||||
ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(
|
||||
val settings = ExternalSystemApiUtil.getExecutionSettings<GradleExecutionSettings>(
|
||||
project,
|
||||
workingDir,
|
||||
GradleConstants.SYSTEM_ID
|
||||
).gradleHome
|
||||
)
|
||||
settings.gradleHome to settings.javaHome
|
||||
}
|
||||
}
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome)
|
||||
val root = LightGradleBuildRoot(workingDir, gradleHome, javaHome)
|
||||
definitionsByRoots[root] = loadGradleDefinitions(root)
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.getGradleScriptInputsStamp
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||
import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel
|
||||
import org.jetbrains.plugins.gradle.service.project.DefaultProjectResolverContext
|
||||
import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext
|
||||
import java.io.File
|
||||
|
||||
@@ -28,6 +29,10 @@ fun saveGradleBuildEnvironment(resolverCtx: ProjectResolverContext) {
|
||||
?: resolverCtx.settings?.gradleHome
|
||||
synchronized(sync) {
|
||||
sync.gradleVersion = resolverCtx.projectGradleVersion
|
||||
sync.javaHome = (resolverCtx as? DefaultProjectResolverContext)
|
||||
?.buildEnvironment
|
||||
?.java?.javaHome?.canonicalPath
|
||||
?.let { toSystemIndependentName(it) }
|
||||
|
||||
if (gradleHome != null) {
|
||||
sync.gradleHome = toSystemIndependentName(gradleHome)
|
||||
@@ -125,6 +130,7 @@ class KotlinDslGradleBuildSync(val workingDir: String, val taskId: ExternalSyste
|
||||
var project: Project? = null
|
||||
var gradleVersion: String? = null
|
||||
var gradleHome: String? = null
|
||||
var javaHome: String? = null
|
||||
val projectRoots = mutableSetOf<String>()
|
||||
val models = mutableListOf<KotlinDslScriptModel>()
|
||||
var failed = false
|
||||
|
||||
+13
-1
@@ -10,11 +10,15 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor
|
||||
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsContributor
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||
import org.jetbrains.plugins.gradle.service.GradleInstallationManager
|
||||
import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
class KotlinDslSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
|
||||
@@ -54,8 +58,16 @@ class KotlinDslSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
|
||||
?.canonicalPath
|
||||
}
|
||||
|
||||
if (sync.javaHome == null) {
|
||||
sync.javaHome = ExternalSystemApiUtil
|
||||
.getExecutionSettings<GradleExecutionSettings>(project, sync.workingDir, GradleConstants.SYSTEM_ID)
|
||||
.javaHome
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(project)?.reloadIfNeeded(sync.workingDir, sync.gradleHome)
|
||||
ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(project)?.reloadIfNeeded(
|
||||
sync.workingDir, sync.gradleHome, sync.javaHome
|
||||
)
|
||||
|
||||
saveScriptModels(project, sync)
|
||||
}
|
||||
|
||||
+3
-2
@@ -88,19 +88,20 @@ class New(
|
||||
*/
|
||||
class Imported(
|
||||
override val pathPrefix: String,
|
||||
val javaHome: File?,
|
||||
val data: GradleBuildRootData,
|
||||
lastModifiedFiles: LastModifiedFiles
|
||||
) : GradleBuildRoot(lastModifiedFiles) {
|
||||
override val projectRoots: Collection<String>
|
||||
get() = data.projectRoots
|
||||
|
||||
val javaHome = data.javaHome?.takeIf { it.isNotBlank() }?.let { File(it) }
|
||||
|
||||
fun collectConfigurations(builder: ScriptClassRootsBuilder) {
|
||||
if (javaHome != null) {
|
||||
builder.sdks.addSdk(javaHome)
|
||||
}
|
||||
|
||||
val definitions = GradleScriptDefinitionsContributor.getDefinitions(builder.project, pathPrefix, data.gradleHome)
|
||||
val definitions = GradleScriptDefinitionsContributor.getDefinitions(builder.project, pathPrefix, data.gradleHome, data.javaHome)
|
||||
if (definitions == null) {
|
||||
// needed to recreate classRoots if correct script definitions weren't loaded at this moment
|
||||
// in this case classRoots will be recreated after script definitions update
|
||||
|
||||
+1
@@ -11,5 +11,6 @@ data class GradleBuildRootData(
|
||||
val importTs: Long,
|
||||
val projectRoots: Collection<String>,
|
||||
val gradleHome: String,
|
||||
val javaHome: String?,
|
||||
val models: Collection<KotlinDslScriptModel>
|
||||
)
|
||||
+14
-6
@@ -19,7 +19,7 @@ import java.io.DataInputStream
|
||||
import java.io.DataOutput
|
||||
|
||||
internal object GradleBuildRootDataSerializer {
|
||||
private val attribute = FileAttribute("kotlin-dsl-script-models", 7, false)
|
||||
private val attribute = FileAttribute("kotlin-dsl-script-models", 8, false)
|
||||
|
||||
fun read(buildRoot: VirtualFile): GradleBuildRootData? {
|
||||
return attribute.readAttribute(buildRoot)?.use {
|
||||
@@ -47,6 +47,7 @@ internal fun writeKotlinDslScriptModels(output: DataOutput, data: GradleBuildRoo
|
||||
val strings = StringsPool.writer(output)
|
||||
strings.addStrings(data.projectRoots)
|
||||
strings.addString(data.gradleHome)
|
||||
strings.addString(data.javaHome)
|
||||
data.models.forEach {
|
||||
strings.addString(it.file)
|
||||
strings.addStrings(it.classPath)
|
||||
@@ -57,6 +58,7 @@ internal fun writeKotlinDslScriptModels(output: DataOutput, data: GradleBuildRoo
|
||||
output.writeLong(data.importTs)
|
||||
strings.writeStringIds(data.projectRoots)
|
||||
strings.writeStringId(data.gradleHome)
|
||||
strings.writeStringId(data.javaHome)
|
||||
output.writeList(data.models) {
|
||||
strings.writeStringId(it.file)
|
||||
output.writeString(it.inputs.sections)
|
||||
@@ -73,6 +75,7 @@ internal fun readKotlinDslScriptModels(input: DataInputStream, buildRoot: String
|
||||
val importTs = input.readLong()
|
||||
val projectRoots = strings.readStrings()
|
||||
val gradleHome = strings.readString()
|
||||
val javaHome = strings.readNullableString()
|
||||
val models = input.readList {
|
||||
KotlinDslScriptModel(
|
||||
strings.readString(),
|
||||
@@ -84,7 +87,7 @@ internal fun readKotlinDslScriptModels(input: DataInputStream, buildRoot: String
|
||||
)
|
||||
}
|
||||
|
||||
return GradleBuildRootData(importTs, projectRoots, gradleHome, models)
|
||||
return GradleBuildRootData(importTs, projectRoots, gradleHome, javaHome, models)
|
||||
}
|
||||
|
||||
private object StringsPool {
|
||||
@@ -99,8 +102,8 @@ private object StringsPool {
|
||||
ids.size
|
||||
}
|
||||
|
||||
fun addString(string: String) {
|
||||
getStringId(string)
|
||||
fun addString(string: String?) {
|
||||
getStringId(string ?: "null")
|
||||
}
|
||||
|
||||
fun addStrings(list: Collection<String>) {
|
||||
@@ -119,8 +122,8 @@ private object StringsPool {
|
||||
}
|
||||
}
|
||||
|
||||
fun writeStringId(it: String) {
|
||||
output.writeInt(getStringId(it))
|
||||
fun writeStringId(it: String?) {
|
||||
output.writeInt(getStringId(it ?: "null"))
|
||||
}
|
||||
|
||||
fun writeStringIds(strings: Collection<String>) {
|
||||
@@ -140,6 +143,11 @@ private object StringsPool {
|
||||
fun getString(id: Int) = strings[id]
|
||||
|
||||
fun readString() = getString(input.readInt())
|
||||
fun readNullableString(): String? {
|
||||
val string = getString(input.readInt())
|
||||
if (string == "null") return null
|
||||
return string
|
||||
}
|
||||
|
||||
fun readStrings(): List<String> = input.readList { readString() }
|
||||
}
|
||||
|
||||
+6
-7
@@ -161,7 +161,10 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
return
|
||||
}
|
||||
|
||||
val newData = GradleBuildRootData(sync.ts, sync.projectRoots, gradleHome, sync.models)
|
||||
|
||||
val newData = GradleBuildRootData(
|
||||
sync.ts, sync.projectRoots, gradleHome, sync.javaHome, sync.models
|
||||
)
|
||||
val mergedData = if (sync.failed && oldRoot is Imported) merge(oldRoot.data, newData) else newData
|
||||
|
||||
val lastModifiedFilesReset = LastModifiedFiles()
|
||||
@@ -183,7 +186,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
val models = old.models.associateByTo(mutableMapOf()) { it.file }
|
||||
new.models.associateByTo(models) { it.file }
|
||||
|
||||
return GradleBuildRootData(new.importTs, roots, new.gradleHome, models.values)
|
||||
return GradleBuildRootData(new.importTs, roots, new.gradleHome, new.javaHome, models.values)
|
||||
}
|
||||
|
||||
private val modifiedFilesCheckScheduled = AtomicBoolean()
|
||||
@@ -345,12 +348,8 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
): Imported? {
|
||||
val buildRoot = VfsUtil.findFile(Paths.get(externalProjectPath), true) ?: return null
|
||||
val data = dataProvider(buildRoot) ?: return null
|
||||
// TODO: can be outdated, should be taken from sync
|
||||
val javaHome = ExternalSystemApiUtil
|
||||
.getExecutionSettings<GradleExecutionSettings>(project, externalProjectPath, GradleConstants.SYSTEM_ID)
|
||||
.javaHome?.let { File(it) }
|
||||
|
||||
return Imported(externalProjectPath, javaHome, data, lastModifiedFiles)
|
||||
return Imported(externalProjectPath, data, lastModifiedFiles)
|
||||
}
|
||||
|
||||
private fun add(newRoot: GradleBuildRoot) {
|
||||
|
||||
+22
-3
@@ -22,10 +22,11 @@ class GradleBuildRootDataSerializerTest {
|
||||
val data = GradleBuildRootData(
|
||||
123,
|
||||
listOf("a", "b", "c"),
|
||||
"a",
|
||||
"gradleHome",
|
||||
"javaHome",
|
||||
listOf(
|
||||
KotlinDslScriptModel(
|
||||
"a",
|
||||
"gradleHome",
|
||||
GradleKotlinScriptConfigurationInputs("b", 1, "a"),
|
||||
listOf("c", "a", "b"),
|
||||
listOf("b", "c", "a"),
|
||||
@@ -33,7 +34,7 @@ class GradleBuildRootDataSerializerTest {
|
||||
listOf()
|
||||
),
|
||||
KotlinDslScriptModel(
|
||||
"a",
|
||||
"gradleHome",
|
||||
GradleKotlinScriptConfigurationInputs("b", 1, "a"),
|
||||
listOf("c", "a", "b"),
|
||||
listOf("b", "c", "a"),
|
||||
@@ -50,4 +51,22 @@ class GradleBuildRootDataSerializerTest {
|
||||
|
||||
assertEquals(data.toString(), restored.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writeNullable() {
|
||||
val data = GradleBuildRootData(
|
||||
0,
|
||||
listOf(),
|
||||
"null",
|
||||
null,
|
||||
listOf()
|
||||
)
|
||||
|
||||
val buffer = ByteArrayOutputStream()
|
||||
writeKotlinDslScriptModels(DataOutputStream(buffer), data)
|
||||
|
||||
val restored = readKotlinDslScriptModels(DataInputStream(ByteArrayInputStream(buffer.toByteArray())), "a")
|
||||
|
||||
assertEquals(data.toString(), restored.toString())
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -35,11 +35,11 @@ open class AbstractGradleBuildRootsLocatorTest {
|
||||
val pathPrefix = "$dir/"
|
||||
val root = Imported(
|
||||
dir,
|
||||
null,
|
||||
GradleBuildRootData(
|
||||
ts,
|
||||
relativeProjectRoots.map { (pathPrefix + it).removeSuffix("/") },
|
||||
"",
|
||||
"gradleHome",
|
||||
"javaHome",
|
||||
listOf()
|
||||
),
|
||||
LastModifiedFiles()
|
||||
|
||||
Reference in New Issue
Block a user