gradle.kts: standalone scripts support (without ui and persistence)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
action.text.standalone=Add as standalone script
|
||||
action.label.text.load.script.configuration=Load related Gradle project
|
||||
action.text.install=Install
|
||||
action.text.show.kotlin.gradle.dsl.logs.in=Show Kotlin Gradle DSL Logs in {0}
|
||||
@@ -37,7 +38,7 @@ text.couldn.t.configure.kotlin.gradle.plugin.automatically=Couldn't configure ko
|
||||
text.default.kotlin.gradle.script=Default Kotlin Gradle Script
|
||||
text.gradle.dsl.logs.cannot.be.found.automatically.see.how.to.find.logs=Gradle DSL Logs cannot be found automatically.<br/>See how to find logs <a href="{0}">here</a>.
|
||||
text.see.manual.installation.instructions=See manual installation instructions <a href="https://kotlinlang.org/docs/reference/using-gradle.html">here</a>.
|
||||
text.the.associated.gradle.project.isn.t.imported=The associated Gradle Project isn't imported.
|
||||
text.the.associated.gradle.project.isn.t.imported=Cannot find related Gradle project. Kotlin DSL Code insight unavailable.
|
||||
text.was.modified={0} was modified
|
||||
title.configure.kotlin.gradle.plugin=Configure Kotlin-Gradle Plugin
|
||||
title.kotlin.build.script=Gradle Kotlin DSL Scripts errors
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
|
||||
const val disableNotificationForProjectImport = true
|
||||
|
||||
fun runPartialGradleImport(project: Project) {
|
||||
getGradleProjectSettings(project).forEach {
|
||||
ExternalSystemUtil.refreshProject(
|
||||
@@ -51,6 +53,8 @@ private var Project.notificationPanel: ScriptConfigurationChangedNotification?
|
||||
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(Key.create("load.script.configuration.panel"))
|
||||
|
||||
fun scriptConfigurationsNeedToBeUpdated(project: Project) {
|
||||
if (disableNotificationForProjectImport) return
|
||||
|
||||
if (autoReloadScriptConfigurations(project)) {
|
||||
// import should be run automatically by Gradle plugin
|
||||
return
|
||||
|
||||
+1
-8
@@ -50,13 +50,6 @@ class GradleScriptListener(project: Project) : ScriptChangeListener(project) {
|
||||
}
|
||||
|
||||
private fun checkUpToDate(vFile: VirtualFile) {
|
||||
val upToDate = GradleBuildRootsManager.getInstance(project)
|
||||
.getScriptInfo(vFile)?.model?.inputs?.isUpToDate(project, vFile) ?: return
|
||||
|
||||
if (upToDate) {
|
||||
scriptConfigurationsAreUpToDate(project)
|
||||
} else {
|
||||
scriptConfigurationsNeedToBeUpdated(project)
|
||||
}
|
||||
GradleBuildRootsManager.getInstance(project).checkUpToDate(vFile)
|
||||
}
|
||||
}
|
||||
+9
-33
@@ -6,8 +6,6 @@
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
@@ -16,11 +14,7 @@ import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.legacy.GradleLegacyScriptConfigurationLoaderForOutOfProjectScripts
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRoot
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
|
||||
class MissingGradleScriptConfigurationNotificationProvider(private val project: Project) :
|
||||
EditorNotifications.Provider<EditorNotificationPanel>() {
|
||||
@@ -35,30 +29,18 @@ class MissingGradleScriptConfigurationNotificationProvider(private val project:
|
||||
scriptUnderRoot.isUnrelatedScript -> EditorNotificationPanel().apply {
|
||||
text(KotlinIdeaGradleBundle.message("text.the.associated.gradle.project.isn.t.imported"))
|
||||
|
||||
val linkProjectText = KotlinIdeaGradleBundle.message("action.label.text.load.script.configuration")
|
||||
createActionLabel(linkProjectText) {
|
||||
val newProjectSettings = GradleProjectSettings()
|
||||
newProjectSettings.externalProjectPath = file.parent.path
|
||||
ExternalSystemUtil.linkExternalProject(
|
||||
GradleConstants.SYSTEM_ID,
|
||||
newProjectSettings,
|
||||
project,
|
||||
{
|
||||
|
||||
},
|
||||
false,
|
||||
ProgressExecutionMode.IN_BACKGROUND_ASYNC
|
||||
)
|
||||
createActionLabel(KotlinIdeaGradleBundle.message("action.text.standalone")) {
|
||||
GradleBuildRootsManager.getInstance(project).addStandaloneScript(file)
|
||||
}
|
||||
val link = createActionLabel("") {}
|
||||
link.setIcon(AllIcons.General.ContextHelp)
|
||||
link.setUseIconAsLink(true)
|
||||
link.toolTipText = KotlinIdeaGradleBundle.message(
|
||||
"tool.tip.text.the.external.gradle.project.needs.to.be.imported.to.get.this.script.analyzed",
|
||||
linkProjectText
|
||||
|
||||
val helpIcon = createActionLabel("") {}
|
||||
helpIcon.setIcon(AllIcons.General.ContextHelp)
|
||||
helpIcon.setUseIconAsLink(true)
|
||||
helpIcon.toolTipText = KotlinIdeaGradleBundle.message(
|
||||
"tool.tip.text.the.external.gradle.project.needs.to.be.imported.to.get.this.script.analyzed"
|
||||
)
|
||||
}
|
||||
scriptUnderRoot.isNewScript -> EditorNotificationPanel().apply {
|
||||
scriptUnderRoot.importRequired -> EditorNotificationPanel().apply {
|
||||
text(getMissingConfigurationNotificationText())
|
||||
createActionLabel(getMissingConfigurationActionText()) {
|
||||
runPartialGradleImport(project)
|
||||
@@ -68,12 +50,6 @@ class MissingGradleScriptConfigurationNotificationProvider(private val project:
|
||||
}
|
||||
}
|
||||
|
||||
private val loaderForOutOfProjectScripts by lazy {
|
||||
GradleLegacyScriptConfigurationLoaderForOutOfProjectScripts(
|
||||
project
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KEY = Key.create<EditorNotificationPanel>("GradleScriptOutOfSourceNotification")
|
||||
}
|
||||
|
||||
+26
@@ -10,6 +10,8 @@ import com.intellij.openapi.diagnostic.logger
|
||||
class GradleBuildRootIndex {
|
||||
private val log = logger<GradleBuildRootIndex>()
|
||||
|
||||
private val standaloneScriptRoots = mutableMapOf<String, GradleBuildRoot.Linked?>()
|
||||
|
||||
private val byWorkingDir = HashMap<String, GradleBuildRoot.Linked>()
|
||||
private val byProjectDir = HashMap<String, GradleBuildRoot.Linked>()
|
||||
|
||||
@@ -24,6 +26,8 @@ class GradleBuildRootIndex {
|
||||
byProjectDir[it] = buildRoot
|
||||
}
|
||||
}
|
||||
|
||||
standaloneScriptRoots.keys.forEach(::computeStandaloneScriptRoot)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
@@ -43,6 +47,12 @@ class GradleBuildRootIndex {
|
||||
@Synchronized
|
||||
fun getBuildByProjectDir(projectDir: String) = byProjectDir[projectDir]
|
||||
|
||||
@Synchronized
|
||||
fun isStandaloneScript(path: String) = path in standaloneScriptRoots
|
||||
|
||||
@Synchronized
|
||||
fun getStandaloneScriptRoot(path: String) = standaloneScriptRoots[path]
|
||||
|
||||
@Synchronized
|
||||
fun add(value: GradleBuildRoot.Linked): GradleBuildRoot.Linked? {
|
||||
val prefix = value.pathPrefix
|
||||
@@ -57,4 +67,20 @@ class GradleBuildRootIndex {
|
||||
rebuildProjectRoots()
|
||||
log.info("$prefix: removed")
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun addStandaloneScript(path: String) {
|
||||
computeStandaloneScriptRoot(path)
|
||||
}
|
||||
|
||||
var standaloneScripts: Collection<String>
|
||||
@Synchronized get() = standaloneScriptRoots.keys
|
||||
@Synchronized set(value) {
|
||||
standaloneScriptRoots.clear()
|
||||
value.forEach(::computeStandaloneScriptRoot)
|
||||
}
|
||||
|
||||
private fun computeStandaloneScriptRoot(path: String) {
|
||||
standaloneScriptRoots[path] = findNearestRoot(path)
|
||||
}
|
||||
}
|
||||
+13
-7
@@ -32,12 +32,11 @@ abstract class GradleBuildRootsLocator {
|
||||
filePath.endsWith("/gradle.properties") ||
|
||||
filePath.endsWith("/gradle.local") ||
|
||||
filePath.endsWith("/gradle-wrapper.properties") ||
|
||||
filePath.endsWith("/build.gradle.kts") ||
|
||||
filePath.endsWith("/settings.gradle.kts") ||
|
||||
filePath.endsWith("/init.gradle.kts")
|
||||
filePath.endsWith(".gradle.kts")
|
||||
|
||||
fun isAffectedGradleProjectFile(filePath: String): Boolean =
|
||||
findAffectedFileRoot(filePath) != null
|
||||
findAffectedFileRoot(filePath) != null ||
|
||||
roots.isStandaloneScript(filePath)
|
||||
|
||||
fun findAffectedFileRoot(filePath: String): GradleBuildRoot.Linked? {
|
||||
if (filePath.endsWith("/gradle.properties") ||
|
||||
@@ -56,15 +55,17 @@ abstract class GradleBuildRootsLocator {
|
||||
|
||||
class ScriptUnderRoot(
|
||||
val root: GradleBuildRoot?,
|
||||
val script: GradleScriptInfo? = null
|
||||
val script: GradleScriptInfo? = null,
|
||||
val standalone: Boolean = false
|
||||
) {
|
||||
val isUnrelatedScript: Boolean
|
||||
get() = root is GradleBuildRoot.Unlinked
|
||||
|
||||
val isNewScript: Boolean
|
||||
val importRequired: Boolean
|
||||
get() = root is GradleBuildRoot.Linked &&
|
||||
!isImported &&
|
||||
!root.importing
|
||||
!root.importing &&
|
||||
!standalone
|
||||
|
||||
private val isImported: Boolean
|
||||
get() = script != null
|
||||
@@ -92,6 +93,11 @@ abstract class GradleBuildRootsLocator {
|
||||
// other scripts: "included", "precompiled" scripts, scripts in unlinked projects,
|
||||
// or just random files with ".gradle.kts" ending
|
||||
|
||||
val standaloneScriptRoot = roots.getStandaloneScriptRoot(filePath)
|
||||
if (standaloneScriptRoot != null) {
|
||||
return ScriptUnderRoot(standaloneScriptRoot, standalone = true)
|
||||
}
|
||||
|
||||
// todo(gradle6): remove, it is required only for projects with old gradle
|
||||
if (searchNearestLegacy) {
|
||||
val found = roots.findNearestRoot(filePath)
|
||||
|
||||
+27
-4
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.core.script.configuration.CompositeScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport
|
||||
import org.jetbrains.kotlin.idea.core.script.configuration.ScriptingSupport.Companion.EPN
|
||||
import org.jetbrains.kotlin.idea.core.script.configuration.utils.getKtFile
|
||||
import org.jetbrains.kotlin.idea.core.script.ucache.ScriptClassRootsBuilder
|
||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.*
|
||||
@@ -69,6 +70,7 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
override fun isApplicable(file: VirtualFile): Boolean {
|
||||
val scriptUnderRoot = findScriptBuildRoot(file) ?: return false
|
||||
if (scriptUnderRoot.root is GradleBuildRoot.Legacy) return false
|
||||
if (roots.isStandaloneScript(file.path)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -79,8 +81,16 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
}
|
||||
}
|
||||
|
||||
// used in 201
|
||||
@Suppress("UNUSED")
|
||||
@Suppress("MemberVisibilityCanBePrivate") // used in GradleImportHelper.kt.193
|
||||
fun checkUpToDate(file: VirtualFile) {
|
||||
if (isConfigurationOutOfDate(file)) {
|
||||
showNotificationForProjectImport(project)
|
||||
} else {
|
||||
hideNotificationForProjectImport(project)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate") // used in GradleImportHelper.kt.201
|
||||
fun isConfigurationOutOfDate(file: VirtualFile): Boolean {
|
||||
val script = getScriptInfo(file) ?: return false
|
||||
return !script.model.inputs.isUpToDate(project, file)
|
||||
@@ -158,6 +168,14 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
}
|
||||
}
|
||||
|
||||
fun addStandaloneScript(file: VirtualFile) {
|
||||
roots.addStandaloneScript(file.path)
|
||||
roots.rebuildProjectRoots()
|
||||
updateNotifications(file.path)
|
||||
val ktFile = project.getKtFile(file) ?: return
|
||||
ScriptConfigurationManager.getInstance(project).getConfiguration(ktFile)
|
||||
}
|
||||
|
||||
init {
|
||||
getGradleProjectSettings(project).forEach {
|
||||
// don't call this.add, as we are inside scripting manager initialization
|
||||
@@ -298,15 +316,20 @@ class GradleBuildRootsManager(val project: Project) : GradleBuildRootsLocator(),
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNotifications(dir1: String) {
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
private fun updateNotifications(dir: String) {
|
||||
if (!project.isOpen) return
|
||||
|
||||
val openedScripts = FileEditorManager.getInstance(project).openFiles.filter {
|
||||
it.path.startsWith(dir1) && isGradleKotlinScript(it)
|
||||
it.path.startsWith(dir) && maybeAffectedGradleProjectFile(it.path)
|
||||
}
|
||||
|
||||
if (openedScripts.isEmpty()) return
|
||||
|
||||
openedScripts.forEach {
|
||||
checkUpToDate(it)
|
||||
}
|
||||
|
||||
GlobalScope.launch(EDT(project)) {
|
||||
if (project.isDisposed) return@launch
|
||||
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ class GradleBuildRootsLocatorTest : AbstractGradleBuildRootsLocatorTest() {
|
||||
newImportedGradleProject("imported", relativeScripts = listOf())
|
||||
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
|
||||
assertNotNull(scriptUnderRoot)
|
||||
assertTrue(scriptUnderRoot.isNewScript)
|
||||
assertTrue(scriptUnderRoot.importRequired)
|
||||
assertFalse(scriptUnderRoot.isUnrelatedScript)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class GradleBuildRootsLocatorTest : AbstractGradleBuildRootsLocatorTest() {
|
||||
newImportedGradleProject("imported", relativeScripts = listOf("build.gradle.kts"))
|
||||
val scriptUnderRoot = findScriptBuildRoot("imported/build.gradle.kts")
|
||||
assertNotNull(scriptUnderRoot)
|
||||
assertFalse(scriptUnderRoot.isNewScript)
|
||||
assertFalse(scriptUnderRoot.importRequired)
|
||||
assertFalse(scriptUnderRoot.isUnrelatedScript)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user