IDEA 插件与配置缓存不兼容。 |
IDEA 插件生成由IntelliJ IDEA使用的文件,从而可以在 IDEA 中打开项目(File
- Open Project
)。外部依赖项(包括相关的源文件和 Javadoc 文件)和项目依赖项都会被考虑。
IDEA 插件具体生成哪些文件取决于使用了哪些其他插件
- 始终
-
生成 IDEA 模块文件。如果项目是根项目,还会生成 IDEA 项目文件和工作区文件。
- Java 插件
-
此外,将 Java 配置添加到 IDEA 模块文件和项目文件中。
IDEA 插件的一个重点是允许自定义。该插件提供了一套标准化的钩子,用于添加和移除生成文件中的内容。
用法
要使用 IDEA 插件,请在您的构建脚本中包含以下内容
plugins {
idea
}
plugins {
id 'idea'
}
IDEA 插件会向您的项目添加一些任务。idea
任务会为项目生成一个 IDEA 模块文件。当项目是根项目时,idea
任务还会生成 IDEA 项目文件和工作区文件。IDEA 项目包括 Gradle 构建中每个项目的模块。
当项目是根项目时,IDEA 插件还会添加一个 openIdea
任务。此任务生成 IDEA 配置文件并在 IDEA 中打开结果。这意味着您可以简单地从根项目运行 ./gradlew openIdea
,一步到位生成并在 IDEA 中打开 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)”。这样就不需要显式执行清理任务了。
此策略也可用于插件将生成的单个文件。例如,对于“.iml”文件,可以使用“gradle cleanIdeaModule ideaModule”来完成。
钩入生成生命周期
该插件提供对象,用于建模由 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 Test Suite 插件时,测试源将自动正确识别。 |
进一步考虑的事项
生成的 IDEA 文件中的依赖项路径是绝对路径。如果您手动定义一个指向 Gradle 依赖项缓存的路径变量,IDEA 将自动用此路径变量替换绝对依赖项路径。您可以通过“idea.pathVariables”属性配置此路径变量,以便能够进行适当的合并而不会创建重复项。