预编译脚本插件通常是 Kotlin 脚本,已编译并作为打包在库中的 Java 类文件分发。这些脚本旨在作为二进制 Gradle 插件使用,并建议用作约定插件。

约定插件是通常使用您自己的约定(即默认值)配置现有核心和社区插件的插件,例如使用java.toolchain.languageVersion = JavaLanguageVersion.of(17).约定插件还用于执行项目标准并帮助简化构建过程。他们可以应用和配置插件、创建新任务和扩展、设置依赖项等等。

设置插件ID

预编译脚本的插件 ID 源自其文件名和可选包声明。

例如,code-quality.gradle(.kts)位于src/main/groovy(或src/main/kotlin) 中但没有包声明的名为的脚本将作为code-quality插件公开:

plugins {
    id("code-quality")
}

另一方面,code-quality.gradle(.kts)位于src/main/groovy/my(或src/main/kotlin/my) 中且带有包声明的名为的脚本my将作为my.code-quality插件公开:

plugins {
    id("my.code-quality")
}

处理文件

您应该使用 Gradle 的托管属性。这将启用延迟配置,以便仅在需要文件时才会解析实际位置,并且可以在构建配置期间随时重新配置。

让我们首先创建一个名为的约定插件greetings

buildSrc/src/main/kotlin/greetings.gradle.kts
// Create extension object
interface GreetingPluginExtension {
    val message: Property<String>
}
buildSrc/src/main/groovy/greetings.gradle
// Create extension object
interface GreetingPluginExtension {
    Property<String> getMessage()
}

您可以在使用文件中找到有关延迟处理文件的更多信息。

使用扩展使插件可配置

扩展对象通常在插件中用于公开配置选项和附加功能来构建脚本。

当您应用定义扩展的插件时,您可以访问扩展对象并配置其属性或调用其方法来自定义插件的行为或插件提供的任务。

项目有一个关联的ExtensionContainer对象其中包含已应用于项目的插件的所有设置和属性。您可以通过向此容器添加扩展对象来为您的插件提供配置。

让我们更新我们的greetings示例:

buildSrc/src/main/kotlin/greetings.gradle.kts
// Create extension object
interface GreetingPluginExtension {
    val message: Property<String>
}

// Add the 'greeting' extension object to project
val extension = project.extensions.create<GreetingPluginExtension>("greeting")
buildSrc/src/main/groovy/greetings.gradle
// Create extension object
interface GreetingPluginExtension {
    Property<String> getMessage()
}

// Add the 'greeting' extension object to project
def extension = project.extensions.create("greeting", GreetingPluginExtension)

message您可以直接使用 来设置属性的值extension.message.set("Hi from Gradle,")

但是,该GreetingPluginExtension对象可用作与扩展对象同名的项目属性。您现在可以message像这样访问:

buildSrc/src/main/kotlin/greetings.gradle.kts
// Where the<GreetingPluginExtension>() is equivalent to project.extensions.getByType(GreetingPluginExtension::class.java)
the<GreetingPluginExtension>().message.set("Hi from Gradle")
buildSrc/src/main/groovy/greetings.gradle
extensions.findByType(GreetingPluginExtension).message.set("Hi from Gradle")

如果您应用该greetings插件,您可以在构建脚本中设置约定:

app/build.gradle.kts
plugins {
    application
    id("greetings")
}

greeting {
    message = "Hello from Gradle"
}
app/build.gradle
plugins {
    id 'application'
    id('greetings')
}

configure(greeting) {
    message = "Hello from Gradle"
}

添加默认配置作为约定

在插件中,您可以使用对象定义默认值,也称为约定project

约定属性是使用默认值初始化但可以覆盖的属性:

buildSrc/src/main/kotlin/greetings.gradle.kts
// Create extension object
interface GreetingPluginExtension {
    val message: Property<String>
}

// Add the 'greeting' extension object to project
val extension = project.extensions.create<GreetingPluginExtension>("greeting")

// Set a default value for 'message'
extension.message.convention("Hello from Gradle")
buildSrc/src/main/groovy/greetings.gradle
// Create extension object
interface GreetingPluginExtension {
    Property<String> getMessage()
}

// Add the 'greeting' extension object to project
def extension = project.extensions.create("greeting", GreetingPluginExtension)

// Set a default value for 'message'
extension.message.convention("Hello from Gradle")

extension.message.convention(…​)message为扩展的属性设置约定。此约定指定 的值应默认为位于项目构建目录中的message名为的文件的内容。defaultGreeting.txt

如果message未显式设置该属性,则其值将自动设置为 的内容defaultGreeting.txt

将扩展属性映射到任务属性

使用扩展并将其映射到自定义任务的输入/输出属性在插件中很常见。

在此示例中, 的 message 属性GreetingPluginExtension映射到GreetingTask作为输入的 的 message 属性:

buildSrc/src/main/kotlin/greetings.gradle.kts
// Create extension object
interface GreetingPluginExtension {
    val message: Property<String>
}

// Add the 'greeting' extension object to project
val extension = project.extensions.create<GreetingPluginExtension>("greeting")

// Set a default value for 'message'
extension.message.convention("Hello from Gradle")

// Create a greeting task
abstract class GreetingTask : DefaultTask() {
    @Input
    val message = project.objects.property<String>()

    @TaskAction
    fun greet() {
        println("Message: ${message.get()}")
    }
}

// Register the task and set the convention
tasks.register<GreetingTask>("hello") {
    message.convention(extension.message)
}
buildSrc/src/main/groovy/greetings.gradle
// Create extension object
interface GreetingPluginExtension {
    Property<String> getMessage()
}

// Add the 'greeting' extension object to project
def extension = project.extensions.create("greeting", GreetingPluginExtension)

// Set a default value for 'message'
extension.message.convention("Hello from Gradle")

// Create a greeting task
abstract class GreetingTask extends DefaultTask {
    @Input
    abstract Property<String> getMessage()

    @TaskAction
    void greet() {
        println("Message: ${message.get()}")
    }
}

// Register the task and set the convention
tasks.register("hello", GreetingTask) {
    message.convention(extension.message)
}
$ gradle -q hello
Message: Hello from Gradle

这意味着对扩展message属性的更改将触发任务被视为过期,从而确保使用新消息重新执行任务。

您可以在延迟配置中找到有关可在任务实现和扩展中使用的类型的更多信息。

应用外部插件

为了在预编译脚本插件中应用外部插件,必须将其添加到插件构建文件中插件项目的实现类路径中:

buildSrc/build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.bmuschko:gradle-docker-plugin:6.4.0")
}
buildSrc/build.gradle
plugins {
    id 'groovy-gradle-plugin'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'com.bmuschko:gradle-docker-plugin:6.4.0'
}

然后可以将其应用到预编译脚本插件中:

buildSrc/src/main/kotlin/my-plugin.gradle.kts
plugins {
    id("com.bmuschko.docker-remote-api")
}
buildSrc/src/main/groovy/my-plugin.gradle
plugins {
    id 'com.bmuschko.docker-remote-api'
}

这种情况下的插件版本是在依赖声明中定义的。