IDEA 插件与配置缓存不完全兼容。应用后,配置缓存会自动禁用。 |
IDEA 插件生成供 IntelliJ IDEA 使用的文件,从而可以在 IDEA 中打开项目(File
- Open Project
)。它会考虑外部依赖(包括相关的源代码和 Javadoc 文件)和项目依赖。
IDEA 插件具体生成什么取决于使用了哪些其他插件
- 始终
-
生成一个 IDEA 模块文件。如果项目是根项目,还会生成一个 IDEA 项目和工作区文件。
- Java 插件
-
额外向 IDEA 模块和项目文件添加 Java 配置。
IDEA 插件的一个重点是开放定制。该插件提供了一套标准化的钩子,用于从生成的文件中添加和删除内容。
用法
要使用 IDEA 插件,请在构建脚本中包含以下内容
plugins {
idea
}
plugins {
id 'idea'
}
IDEA 插件向您的项目添加了许多任务。idea
任务为项目生成一个 IDEA 模块文件。当项目是根项目时,idea
任务还会生成一个 IDEA 项目和工作区。IDEA 项目包括 Gradle 构建中每个项目的模块。
当项目是根项目时,IDEA 插件还会添加一个 openIdea
任务。此任务生成 IDEA 配置文件并在 IDEA 中打开结果。这意味着您只需从根项目运行 ./gradlew openIdea
,即可在一个方便的步骤中生成并打开 IDEA 项目。
IDEA 插件还会向项目添加一个 cleanIdea
任务。此任务会删除已生成的 文件(如果存在)。
任务
IDEA 插件向项目添加了以下任务。请注意,clean
任务不依赖于 cleanIdeaWorkspace
任务。这是因为工作区通常包含大量用户特定的临时数据,并且不希望在 IDEA 外部对其进行操作。
idea
-
依赖于:
ideaProject
,ideaModule
,ideaWorkspace
生成所有 IDEA 配置文件
openIdea
-
依赖于:
idea
生成所有 IDEA 配置文件并在 IDEA 中打开项目
cleanIdea
— Delete-
依赖于:
cleanIdeaProject
,cleanIdeaModule
删除所有 IDEA 配置文件
cleanIdeaProject
— Delete-
删除 IDEA 项目文件
cleanIdeaModule
— Delete-
删除 IDEA 模块文件
cleanIdeaWorkspace
— Delete-
删除 IDEA 工作区文件
ideaProject
— GenerateIdeaProject-
生成
.ipr
文件。此任务仅添加到根项目。 ideaModule
— GenerateIdeaModule-
生成
.iml
文件 ideaWorkspace
— GenerateIdeaWorkspace-
生成
.iws
文件。此任务仅添加到根项目。
配置
该插件添加了一些配置选项,允许自定义其生成的 IDEA 项目和模块文件。这些选项以模型属性和直接修改生成文件的低级机制的形式存在。例如,您可以添加源目录和资源目录,以及注入自己的 XML 片段。前一种配置类型被 IDEA 的导入工具所支持,而后一种则不支持。
以下是您可以使用的配置属性
idea
— IdeaModel-
顶层元素,以 DSL 友好的方式启用 IDEA 插件的配置
idea.project
IdeaProject-
允许配置项目信息
idea.module
IdeaModule-
允许配置模块信息
idea.workspace
IdeaWorkspace-
允许配置工作区 XML
请点击链接到类型,查看使用这些配置属性的示例。
自定义生成文件
IDEA 插件提供了钩子和行为,可以以更受控和更详细的方式自定义生成的内容。此外,withXml
钩子是修改工作区文件的唯一实用方法,因为其对应的域对象本质上是空的。
本节讨论的技术不适用于 IDEA 的导入功能 |
这些任务识别现有的 IDEA 文件并将其与生成的内容合并。
合并
现有 IDEA 文件中作为生成内容目标的区段将被修改或覆盖,具体取决于特定区段。其余区段将保持不变。
通过完全覆盖禁用合并
要完全重写现有的 IDEA 文件,请执行清除任务及其相应的生成任务,如“gradle cleanIdea idea”(按此顺序)。如果您想将其设置为默认行为,请将“tasks.idea.dependsOn(cleanIdea)”添加到您的构建脚本中。这样就不需要显式执行清除任务。
此策略也可用于插件将生成的单个文件。例如,可以使用“gradle cleanIdeaModule ideaModule”来处理“.iml”文件。
挂钩生成生命周期
该插件提供了建模 Gradle 生成的元数据文件部分的 对象。生成生命周期如下:
-
读取文件;如果文件不存在,则使用 Gradle 提供的默认版本
-
beforeMerged
钩子以表示现有文件的域对象执行 -
将现有内容与从 Gradle 构建推断或在 eclipse DSL 中显式定义的配置合并
-
whenMerged
钩子以表示将要持久化的文件内容的域对象执行 -
withXml
钩子以将要持久化的 XML 的原始表示执行 -
最终的 XML 被持久化
以下是每种模型类型使用的域对象:
- IdeaProject
-
-
beforeMerged { Project arg -> … }
-
whenMerged { Project arg -> … }
-
withXml { XmlProvider arg -> … }
-
- IdeaModule
-
-
beforeMerged { Module arg -> … }
-
whenMerged { Module arg -> … }
-
withXml { XmlProvider arg -> … }
-
- IdeaWorkspace
-
-
beforeMerged { Workspace arg -> … }
-
whenMerged { Workspace arg -> … }
-
withXml { XmlProvider arg -> … }
-
部分重写现有内容
“完全重写”会导致所有现有内容被丢弃,从而丢失直接在 IDE 中所做的任何更改。beforeMerged
钩子使得只覆盖现有内容的某些部分成为可能。以下示例从 Module
域对象中删除所有现有依赖项:
import org.gradle.plugins.ide.idea.model.Module
idea.module.iml {
beforeMerged(Action<Module> {
dependencies.clear()
})
}
idea.module.iml {
beforeMerged { module ->
module.dependencies.clear()
}
}
生成的模块文件将只包含 Gradle 生成的依赖项条目,而不包含原始文件中可能存在的任何其他依赖项条目。(对于依赖项条目,这也是默认行为。)模块文件的其他部分将保持不变或合并。项目文件中的模块路径也可以进行同样的操作
import org.gradle.plugins.ide.idea.model.Project
idea.project.ipr {
beforeMerged(Action<Project> {
modulePaths.clear()
})
}
idea.project.ipr {
beforeMerged { project ->
project.modulePaths.clear()
}
}
修改完全填充的域对象
whenMerged
钩子允许您操作完全填充的域对象。通常,这是自定义 IDEA 文件的首选方式。以下是如何导出 IDEA 模块的所有依赖项:
import org.gradle.plugins.ide.idea.model.Module
import org.gradle.plugins.ide.idea.model.ModuleDependency
idea.module.iml {
whenMerged(Action<Module> {
dependencies.forEach {
(it as ModuleDependency).isExported = true
}
})
}
idea.module.iml {
whenMerged { module ->
module.dependencies*.exported = true
}
}
修改 XML 表示
withXml
钩子允许您在文件写入磁盘之前操作内存中的 XML 表示。尽管 Groovy 的 XML 支持和 Kotlin 的扩展函数弥补了很多不足,但这种方法不如操作域对象方便。作为回报,您可以完全控制生成的文件,包括域对象未建模的部分。
import org.w3c.dom.Element
idea.project.ipr {
withXml(Action<XmlProvider> {
fun Element.firstElement(predicate: (Element.() -> Boolean)) =
childNodes
.run { (0 until length).map(::item) }
.filterIsInstance<Element>()
.first { it.predicate() }
asElement()
.firstElement { tagName == "component" && getAttribute("name") == "VcsDirectoryMappings" }
.firstElement { tagName == "mapping" }
.setAttribute("vcs", "Git")
})
}
idea.project.ipr {
withXml { provider ->
provider.node.component
.find { it.@name == 'VcsDirectoryMappings' }
.mapping.@vcs = 'Git'
}
}
识别其他测试目录
将此插件与 Java 插件一起使用时,在添加额外的源集后,您可能希望告知 IDEA 它们何时包含测试源而不是生产源,以便 IDE 可以适当处理这些目录。这可以通过使用此插件的 Module
块来实现。
sourceSets {
create("intTest") {
java {
setSrcDirs(listOf("src/integration"))
}
}
}
idea {
module {
testSources.from(sourceSets["intTest"].java.srcDirs)
}
}
sourceSets {
intTest {
java {
srcDirs = ['src/integration']
}
}
}
idea {
module {
testSources.from(sourceSets.intTest.java.srcDirs)
}
}
使用 JVM 测试套件插件时,测试源将自动正确识别。 |
其他注意事项
生成的 IDEA 文件中的依赖项路径是绝对的。如果您手动定义指向 Gradle 依赖项缓存的路径变量,IDEA 将自动用此路径变量替换绝对依赖项路径。您可以通过“idea.pathVariables”属性配置此路径变量,以便进行正确的合并而不会创建重复项。