创建自己的 Gradle Scala 插件
完成基本设置示例后,你可能会发现自己在每个 Scala Gradle 项目中都重复了大部分内容。闻起来像样板代码……
如果不使用 Gradle 提供的 Scala 插件 ,你可以应用自己的 Scala 插件,该插件将负责处理所有常见的构建逻辑,同时扩展已有的插件。
这个例子将把以前的构建逻辑转换为可重用的 Gradle 插件。
幸运的是,在 Gradle 中,你可以在 Gradle API 的帮助下轻松编写自定义插件,如文档中所述。作为实现语言,你可以使用 Scala 本身甚至 Java。但是,你可以在整个文档中找到的大多数示例都是用 Groovy 编写的。例如,如果你需要更多代码示例或想了解 Scala 插件背后的内容,可以查看 gradle github repo 。
编写插件
要求
自定义插件在应用于项目时将添加以下功能:
scalaVersion
属性对象,它将具有两个可覆盖的默认属性- major =“2.12”
- minor =
0
- 应用于依赖项名称的
withScalaVersion
函数将添加 scala 主要版本以确保二进制兼容性(sbt%%
运算符可能响铃,否则在继续之前转到此处 ) - 创建必要目录树的
createDirs
任务,与前面的示例完全相同
实施指南
-
创建一个新的 gradle 项目并将以下内容添加到
build.gradle
apply plugin: ‘scala’ apply plugin: ‘maven’
repositories {
mavenLocal()
mavenCentral()
}dependencies { compile
gradleApi()
compile “org.scala-lang:scala-library:2.12.0” }
备注 :
- 插件实现是用 Scala 编写的,因此我们需要 Gradle Scala 插件
- 为了使用其他项目的插件,使用 Gradle Maven 插件; 这增加了用于将项目 jar 保存到 Maven Local Repository 的
install
任务 compile gradleApi()
将gradle-api-<gradle_version>.jar
添加到类路径中
- 为插件实现创建一个新的 Scala 类
package com.btesila.gradle.plugins
import org.gradle.api.{Plugin, Project}
class ScalaCustomPlugin extends Plugin[Project] {
override def apply(project: Project): Unit = {
project.getPlugins.apply("scala")
}
}
备注 :
- 为了实现插件,只需扩展
Project
类型的Plugin
特性并覆盖apply
方法 - 在 apply 方法中,你可以访问插件所应用的
Project
实例,你可以使用它来为其添加构建逻辑 - 这个插件什么都不做,只是应用现有的 Gradle Scala 插件
- 添加
scalaVersion
对象属性
首先,我们创建一个 ScalaVersion
类,它将保存两个版本属性
class ScalaVersion {
var major: String = "2.12"
var minor: String = "0"
}
Gradle 插件的一个很酷的事实是,你始终可以添加或覆盖特定属性。插件通过连接到 gradle Project
实例的 ExtensionContainer
接收这种用户输入。有关详细信息,请查看此信息。
通过在 apply
方法中添加以下内容,我们基本上是这样做的:
-
如果项目中没有定义
scalaVersion
属性,我们添加一个默认值 -
否则,我们将现有的一个作为
ScalaVersion
的实例,以进一步使用它var scalaVersion = new ScalaVersion if (!project.getExtensions.getExtraProperties.has(“scalaVersion”)) project.getExtensions.getExtraProperties.set(“scalaVersion”, scalaVersion) else scalaVersion = project.getExtensions.getExtraProperties.get(“scalaVersion”).asInstanceOf[ScalaVersion]
这相当于将以下内容写入应用插件的项目的构建文件:
ext {
scalaVersion.major = "2.12"
scalaVersion.minor = "0"
}
-
使用
scalaVersion
将 tihuan20 库添加到项目依赖项中project.getDependencies.add(“compile”, s"org.scala-lang:scala-library:${scalaVersion.major}.${scalaVersion.minor}")
这相当于将以下内容写入应用插件的项目的构建文件:
compile "org.scala-lang:scala-library:2.12.0"
-
添加
withScalaVersion
功能val withScalaVersion = (lib: String) => { val libComp = lib.split(":") libComp.update(1, s"${
libComp(1)
}_${scalaVersion.major}") libComp.mkString(":") } project.getExtensions.getExtraProperties.set(“withScalaVersion”, withScalaVersion) -
最后,创建
createDirs
任务并
通过扩展DefaultTask
将其添加到项目实现 Gradle 任务:class CreateDirs extends DefaultTask { @TaskAction def
createDirs()
: Unit = { val sourceSetContainer = this.getProject.getConvention.getPlugin(classOf[JavaPluginConvention]).getSourceSetssourceSetContainer forEach { sourceSet => sourceSet.getAllSource.getSrcDirs.forEach(file => if (!file.getName.contains("java")) `file.mkdirs()`) }
} }
注意 :SourceSetContainer
包含有关项目中存在的所有源目录的信息。Gradle Scala 插件的作用是将额外的源集添加到 Java 库中,如插件文档中所示 。
通过将此附加到 apply
方法,将 createDir
任务添加到项目中:
project.getTasks.create("createDirs", classOf[CreateDirs])
最后,你的 ScalaCustomPlugin
类应该是这样的:
class ScalaCustomPlugin extends Plugin[Project] {
override def apply(project: Project): Unit = {
project.getPlugins.apply("scala")
var scalaVersion = new ScalaVersion
if (!project.getExtensions.getExtraProperties.has("scalaVersion"))
project.getExtensions.getExtraProperties.set("scalaVersion", scalaVersion)
else
scalaVersion = project.getExtensions.getExtraProperties.get("scalaVersion").asInstanceOf[ScalaVersion]
project.getDependencies.add("compile", s"org.scala-lang:scala-library:${scalaVersion.major}.${scalaVersion.minor}")
val withScalaVersion = (lib: String) => {
val libComp = lib.split(":")
libComp.update(1, s"${`libComp(1)`}_${scalaVersion.major}")
libComp.mkString(":")
}
project.getExtensions.getExtraProperties.set("withScalaVersion", withScalaVersion)
project.getTasks.create("createDirs", classOf[CreateDirs])
}
}
将插件项目安装到本地 Maven 存储库
通过运行 tihuan 29
可以轻松完成此操作你可以通过访问本地存储库目录来检查安装,通常位于~/.m2/repository
Gradle 如何找到我们的新插件?
每个 Gradle 插件都有一个 id
,用于 apply
语句。例如,通过将以下内容写入构建文件,它将转换为 Gradle 的触发器,以查找并应用 id 为 scala
的插件。
apply plugin: 'scala'
以同样的方式,我们希望以下列方式应用我们的新插件,
apply plugin: "com.btesila.scala.plugin"
这意味着我们的插件将具有 com.btesila.scala.plugin
id。
要设置此 ID,请添加以下文件:
src / main / resources / META-INF / gradle-plugin / com.btesil.scala.plugin.properties
implementation-class=com.btesila.gradle.plugins.ScalaCustomPlugin
之后,再次运行 gradle install
。
使用插件
-
创建一个新的空 Gradle 项目,并将以下内容添加到构建文件中
buildscript { repositories {
mavenLocal()
mavenCentral()
}dependencies { //modify this path to match the installed plugin project in your local repository classpath 'com.btesila:working-with-gradle:1.0-SNAPSHOT' }
}
repositories {
mavenLocal()
mavenCentral()
}apply plugin: “com.btesila.scala.plugin”
-
运行
gradle createDirs
- 你现在应该生成所有源目录 -
通过将其添加到构建文件来覆盖 scala 版本:
ext { scalaVersion.major = “2.11” scalaVersion.minor = “8”
}
println(project.ext.scalaVersion.major)
println(project.ext.scalaVersion.minor)
-
添加与 Scala 版本二进制兼容的依赖库
dependencies { compile withScalaVersion(“com.typesafe.scala-logging:scala-logging:3.5.0”) }
而已! 你现在可以在所有项目中使用此插件,而无需重复相同的旧样板。