IDEA 插件与 配置缓存 不兼容。 |
IDEA 插件生成 IntelliJ IDEA 使用的文件,从而可以从 IDEA 打开项目 (File
- Open Project
)。外部依赖(包括相关的源代码和 Javadoc 文件)和项目依赖都会被考虑在内。
IDEA 插件具体生成什么文件取决于使用的其他插件
- 始终
-
生成 IDEA 模块文件。如果项目是根项目,还会生成 IDEA 项目和工作区文件。
- Java 插件
-
此外,还会将 Java 配置添加到 IDEA 模块和项目文件中。
IDEA 插件的一个重点是保持自定义的开放性。该插件提供了一组标准化的钩子,用于从生成的文件中添加和删除内容。
用法
要使用 IDEA 插件,请在您的构建脚本中包含以下内容
plugins {
idea
}
plugins {
id 'idea'
}
IDEA 插件为您的项目添加了许多 tasks。idea
task 为项目生成 IDEA 模块文件。当项目是根项目时,idea
task 还会生成 IDEA 项目和工作区。IDEA 项目包含 Gradle 构建中每个项目的模块。
当项目是根项目时,IDEA 插件还会添加一个 openIdea
task。此 task 生成 IDEA 配置文件并在 IDEA 中打开结果。这意味着您只需从根项目运行 ./gradlew openIdea
即可在一个便捷的步骤中生成并打开 IDEA 项目。
IDEA 插件还向项目添加了一个 cleanIdea
task。此 task 删除生成的文件(如果存在)。
Tasks
IDEA 插件将下面显示的 tasks 添加到项目中。请注意,clean
task 不依赖于 cleanIdeaWorkspace
task。这是因为工作区通常包含大量用户特定的临时数据,不希望在 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
文件。此 task 仅添加到根项目。 ideaModule
— GenerateIdeaModule-
生成
.iml
文件 ideaWorkspace
— GenerateIdeaWorkspace-
生成
.iws
文件。此 task 仅添加到根项目。
配置
该插件添加了一些配置选项,允许自定义其生成的 IDEA 项目和模块文件。这些选项以模型属性和直接修改生成文件的底层机制的形式存在。例如,您可以添加源代码和资源目录,以及注入您自己的 XML 片段。前一种配置类型受到 IDEA 导入功能的尊重,而后一种则不然。
以下是可以使用的配置属性
idea
— IdeaModel-
顶级元素,以 DSL 友好的方式启用 idea 插件的配置
idea.project
IdeaProject-
允许配置项目信息
idea.module
IdeaModule-
允许配置模块信息
idea.workspace
IdeaWorkspace-
允许配置工作区 XML
点击链接查看这些配置属性的使用示例。
自定义生成的文件
IDEA 插件提供了用于以更受控和更详细的方式自定义生成内容的钩子和行为。此外,withXml
钩子是修改工作区文件的唯一实用方法,因为其对应的域对象本质上是空的。
我们在本节中讨论的技术不适用于 IDEA 的导入功能 |
Tasks 识别现有的 IDEA 文件,并将其与生成的内容合并。
合并
现有 IDEA 文件中也是生成内容目标的 sections 将根据具体 section 进行修改或覆盖。其余 sections 将保持原样。
禁用合并并完全覆盖
要完全重写现有的 IDEA 文件,请执行 clean task 及其对应的生成 task,例如 “gradle cleanIdea idea”(按此顺序)。如果您想将其设为默认行为,请将 “tasks.idea.dependsOn(cleanIdea)” 添加到您的构建脚本中。这样就不必显式执行 clean task。
此策略也适用于插件将生成的单个文件。例如,可以使用 “gradle cleanIdeaModule ideaModule” 对 “.iml” 文件执行此操作。
Hooking 到生成生命周期
该插件提供了对 Gradle 生成的元数据文件 sections 进行建模的对象。生成生命周期如下
-
读取文件;或者,如果文件不存在,则使用 Gradle 提供的默认版本
-
使用表示现有文件的域对象执行
beforeMerged
钩子 -
现有内容与从 Gradle 构建推断或在 eclipse DSL 中显式定义的配置合并
-
使用表示要持久化的文件内容的域对象执行
whenMerged
钩子 -
使用将要持久化的 XML 的原始表示执行
withXml
钩子 -
最终的 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 生成的依赖项条目,而不包含原始文件中可能存在的任何其他依赖项条目。(在依赖项条目的情况下,这也是默认行为。)模块文件的其他 sections 将保持原样或合并。对项目文件中的模块路径也可以执行相同的操作
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 的扩展函数弥补了很多不足,但这种方法不如操作域对象方便。作为回报,您可以完全控制生成的文件,包括域对象未建模的 sections。
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” 属性配置此路径变量,以便它可以进行适当的合并而不会创建重复项。