Как объединить импортированные плагины в пользовательский плагин в Gradle, используя Kotlin - PullRequest
2 голосов
/ 07 октября 2019

У меня есть микросервисы, которые будут использовать одну и ту же конфигурацию для всех из них, в основном Jib, publish и release. Не уверен, что можно сделать то же самое для зависимостей, но было бы полезно включить в каждую актуатор и log4j2. Вот build.gradle.kts для одного из моих проектов.

import net.researchgate.release.BaseScmAdapter
import net.researchgate.release.GitAdapter
import net.researchgate.release.ReleaseExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("com.gorylenko.gradle-git-properties") version "1.5.1"
    id("com.google.cloud.tools.jib") version "1.6.1"
    id("io.spring.dependency-management") version "1.0.7.RELEASE"
    id("net.researchgate.release") version "2.8.1"
    id("org.sonarqube") version "2.7.1"
    id("org.springframework.boot") version "2.1.6.RELEASE"
    kotlin("jvm") version "1.2.71"
    kotlin("plugin.spring") version "1.2.71"
    jacoco
    `maven-publish`
}

java.sourceCompatibility = JavaVersion.VERSION_1_8

springBoot {
    buildInfo {
        group = project.properties["group"].toString()
        version = project.properties["version"].toString()
        description = project.properties["description"].toString()
    }
}

repositories {
    maven(url = uri(project.properties["nexus.url.gateway"].toString()))
    mavenCentral()
}

dependencies {
    // Kotlin
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // Spring
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.springframework.boot:spring-boot-starter-log4j2")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.cloud:spring-cloud-config-server")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:Greenwich.SR3")
    }
}

configurations.all {
    exclude(group = "ch.qos.logback", module = "logback-classic")
    exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}

tasks {
    withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "1.8"
        }
    }

    build { dependsOn(clean) }
    afterReleaseBuild { dependsOn(publish) }
    publish { dependsOn(build) }
    jibDockerBuild { dependsOn(build) }
    jacocoTestReport {
        reports {
            html.isEnabled = false
            xml.isEnabled = true
        }
    }
}

publishing {
    publications {
        create<MavenPublication>(project.name) {
            from(components["java"])
            pom {
                scm {
                    connection.set("scm:git:git@github.com:company/${project.name}.git")
                    developerConnection.set("scm:git:git@github.com:company/${project.name}.git")
                    url.set("https://github.com/company/${project.name}/")
                }
            }
            versionMapping {
                usage("java-api") {
                    fromResolutionOf("runtimeClasspath")
                }
                usage("java-runtime") {
                    fromResolutionResult()
                }
            }
        }
    }
    repositories {
        maven {
            val releasesRepoUrl = "${project.properties["nexus.url.publish"].toString()}/releases"
            val snapshotsRepoUrl = "${project.properties["nexus.url.publish"].toString()}/snapshots"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
            credentials {
                username = project.properties["nexus.user"].toString()
                password = project.properties["nexus.password"].toString()
            }
        }
    }
}

fun ReleaseExtension.git(configureFn : GitAdapter.GitConfig.() -> Unit) {
    (propertyMissing("git") as GitAdapter.GitConfig).configureFn()
}

release {
    scmAdapters = mutableListOf<Class<out BaseScmAdapter>> ( GitAdapter::class.java )

    git {
        requireBranch = "develop"
        pushToRemote = project.properties["release.git.remote"].toString()
        pushReleaseVersionBranch = "master"
        tagTemplate = "${project.name}.${project.version}"
    }
}

jib {
    from {
        image = "openjdk:8-jdk-alpine"
    }
    to {
        image = "host:port/${project.name}:${project.version}"
        auth {
            username = project.properties["nexus.user"].toString()
            password = project.properties["nexus.password"].toString()
        }
    }
    container {
        workingDirectory = "/"
        ports = listOf("8080")
        environment = mapOf(
                "SPRING_OUTPUT_ANSI_ENABLED" to "ALWAYS",
                "SPRING_CLOUD_BOOTSTRAP_LOCATION" to "/path/to/bootstrap.yml"
        )
        useCurrentTimestamp = true
    }
    setAllowInsecureRegistries(true)
}

Мне удалось получить собственный плагин, созданный и добавленный в этот проект, используя git@github.com: klg71 / kotlintestplugin.git и git@github.com: klg71 / kotlintestpluginproject.git , но я не знаю, как реализовать эти существующие плагины и их конфигурации. В основном классе Plugin в функции apply я могу вызвать project.pluginManager.apply (PublishingPlugin :: class.java), который заставляет задачу отображаться в проекте, ссылающемся на пользовательский плагин, но я не могу понять, какнастроить его, и он не может успешно опубликовать на сервере Nexus. Я могу опубликовать сам плагин на сервере Nexus и ссылаться на него в микросервисе, но он пропускает выполнение задачи, что, как я полагаю, вызвано отсутствием конфигурации. Кроме того, при попытке применить / настроить плагин Jib все классы не отображаются при попытке импорта.

Ответы [ 3 ]

1 голос
/ 04 ноября 2019

Мне удалось успешно использовать примеры репозитория github, упомянутые выше, чтобы выполнить то, что мне было нужно в задаче публикации. Вот мой пользовательский плагин build.gradle.kts .

plugins {
    id("com.google.cloud.tools.jib") version "1.6.1"
    id("org.sonarqube") version "2.7.1"
    kotlin("jvm") version "1.3.0"
    `maven-publish`
}

dependencies {
    compile(kotlin("stdlib"))
    compile(kotlin("reflect"))
    implementation(gradleApi())
}

repositories {
    jcenter()
}

publishing {
    publications {
        create<MavenPublication>(project.name) {
            from(components["java"])
            pom {
                scm {
                    connection.set("scm:git:git@github.com:company/${project.name}.git")
                    developerConnection.set("scm:git:git@github.com:company/${project.name}.git")
                    url.set("https://github.com/company/${project.name}/")
                }
            }
        }
    }
    repositories {
        maven {
            val baseUrl = "https://${project.properties["nexus.host"].toString()}:${project.properties["nexus.port.jar"].toString()}/repository"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) "$baseUrl/maven-snapshots" else "$baseUrl/maven-releases")
            credentials {
                username = project.properties["nexus.user"].toString()
                password = project.properties["nexus.password"].toString()
            }
        }
    }
}

Вот класс CustomPlugin.kt.

package com.company.gradlemicroserviceplugin

//import com.google.cloud.tools.jib.gradle.JibExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.plugins.PublishingPlugin
import org.gradle.testing.jacoco.tasks.JacocoReport
import java.net.URI

open class CustomPlugin : Plugin<Project> {
    override fun apply(project: Project) {
//        applySonar(project)
        applyPublish(project)
//        applyJib(project)
    }

//    private fun applySonar(project: Project) {
//        project.pluginManager.apply("sonarqube")
//        val task = project.task("jacocoTestReport") as JacocoReport
//        task.reports = JacocoReport()
//        jacocoTestReport { This was nested in the tasks declaration in build.gradle.kts so the fields below are the fields I'm trying to set in task.reports
//            reports {
//                html.isEnabled = false
//                xml.isEnabled = true
//            }
//        }
//    }

    private fun applyPublish(project: Project) {
        project.pluginManager.apply(PublishingPlugin::class.java)

        val publishingExtension = project.extensions.findByType(PublishingExtension::class.java)
        val mavenPublication = publishingExtension?.publications?.create(project.name, MavenPublication::class.java)

        publishingExtension?.repositories?.maven {
            val baseUrl = "https://${project.properties["nexus.host"].toString()}:${project.properties["nexus.port.jar"].toString()}/repository"
            it.url = URI(if (project.version.toString().endsWith("SNAPSHOT")) "$baseUrl/maven-snapshots" else "$baseUrl/maven-releases")
            it.credentials { cred ->
                cred.username = project.properties["nexus.user"].toString()
                cred.password = project.properties["nexus.password"].toString()
            }
        }

        mavenPublication?.from(project.components.findByName("java"))
        mavenPublication?.pom?.scm {
            it.connection.set("scm:git:git@github.com:company/${project.name}.git")
            it.developerConnection.set("scm:git:git@github.com:company/${project.name}.git")
            it.url.set("https://github.com/company/${project.name}/")
        }
    }

//    private fun applyJib(project: Project) {
//        project.pluginManager.apply(JibPlugin::class.java)
//
//    }
}

Тамбезусловно, это области, где есть улучшения, но, по крайней мере, у меня есть кое-что, что работает здесь. Существует логика maven-publish в обоих build.gradle.kts , потому что я нажимаю на пользовательский плагин для nexus и maven-publish логика находится в классе CustomPlugin.kt , поэтому микросервис, который ссылается на этот плагин, может использовать его. Однако я не могу успешно настроить Jib и Sonar . Jib не дает мне доступа к чему-либо в com.google.cloud.tools.jib.gradle, не позволяя мне использовать тот же подход, который я использовал в maven-publish . enter image description here Для Сонар Я думаю, что я на правильном пути с получением задачи по ее имени, но я не могу установить поля, которые принадлежат task.reports, потому что онивсе являются окончательными, и это необходимо для сонара для правильного анализа Kotlin .

1 голос
/ 12 ноября 2019

Таким образом, приведенный выше ответ не является слишком длинным, и для сохранения проблем, с которыми я столкнулся, я публикую новый ответ.

PLUGIN

Эта частьОтвет будет обсуждать фактический проект пользовательского плагина. Поскольку оболочка плагинов в build.gradle.kts является средой выполнения, CustomPlugin.kt не имеет доступа к ней во время компиляции. Мой босс, который намного умнее меня, был достаточно любезен, чтобы указать мне на это, хотя он никогда не работал с gradle. Несмотря на то, что я выглядел довольно глупо перед ним, он все же заставил меня начать работать, в основном следуя «старому» способу применения плагинов в Gradle.

plugins { // This is a runtime script preventing plugins declared here to be accessible in CustomPlugin.kt but is used to actually publish/release this plugin itself
    id("net.researchgate.release") version "2.8.1"
    kotlin("jvm") version "1.3.0"
    `maven-publish`
}

repositories {
    maven { url = uri("https://plugins.gradle.org/m2/") } // This is required to be able to import plugins below in the dependencies
    jcenter()
}

dependencies {
    compile(kotlin("stdlib"))
    compile(kotlin("reflect"))

    // These must be declared here (at compile-time) in order to access in CustomPlugin.kt
    compile(group = "gradle.plugin.com.gorylenko.gradle-git-properties", name = "gradle-git-properties", version = "2.2.0")
    compile(group = "gradle.plugin.com.google.cloud.tools", name = "jib-gradle-plugin", version = "1.7.0")
    compile(group = "net.researchgate", name = "gradle-release", version = "2.8.1")
    compile(group = "org.asciidoctor", name = "asciidoctor-gradle-plugin", version = "1.5.9.2")
    compile(group = "org.jetbrains.dokka", name = "dokka-gradle-plugin", version = "0.9.18")
    compile(group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version = "2.8")

    implementation(gradleApi()) // This exposes the gradle API to CustomPlugin.kt
}

Это позволило мне иметь доступ к Jib и всему остальномув CustomPlugin.kt . Плагины jacoco и maven-publish автоматически доступны в проекте плагина, но все еще должны быть добавлены в проект микросервиса со ссылкой на плагин. К сожалению, я не смог найти обходной путь для этого.

Я включил типичный плагин maven-publish в build.gradle.kts , чтобы перейти на нексус с конфигурациями задач публикации в build.gradle.kts , чтобы я мог извлечь это из нексуса в микросервисе, который хотел использовать плагин.

publishing {
    publications {
        create<MavenPublication>(project.name) {
            from(components["java"])
            pom {
                scm {
                    connection.set("scm:git:git@github.com:diendanyoi54/${project.name}.git")
                    developerConnection .set("scm:git:git@github.com:diendanyoi54/${project.name}.git")
                    url.set("https://github.com/diendanyoi54/${project.name}/")
                }
            }
        }
    }
    repositories {
        maven {
            val baseUrl = "https://${project.properties["nexus.host"].toString()}:${project.properties["nexus.port.jar"].toString()}/repository"
            url = uri(if (version.toString().endsWith("SNAPSHOT")) "$baseUrl/maven-snapshots" else "$baseUrl/maven-releases")
            credentials {
                username = project.properties["nexus.user"].toString()
                password = project.properties["nexus.password"].toString()
            }
        }
    }
}

Наконец, вы хотите убедиться, что вы включили файл свойствэто скажет микросервисам, где находится класс плагина. В IDEA Intellij при вводе пути к классу реализации он автоматически заполняется для меня. enter image description here Имя этого файла должно отражать apply (plugin = "string") в build.gradle.kts микросервиса .

РЕАЛИЗАЦИЯ

Эта часть ответа будет отражать проект микросервиса, который будет ссылаться на плагин. Как указывалось выше, jacoco и maven-publish все еще необходимо добавить в блок плагинов в build.gradle.kts по какой-то причине (я думаю, потому что они являются официальными плагинами gradle). enter image description here

Чтобы ссылаться на плагин с сервера nexus, на котором он был опубликован, микросервис должен ссылаться на него в сценарии сборки.

buildscript { // Custom plugin must be accessed by this buildscript
    repositories {
        maven {
            url = uri("https://${project.properties["nexus.host"].toString()}:${project.properties["nexus.port.jar"].toString()}/repository/maven-public")
            credentials {
                username = project.properties["nexus.user"].toString()
                password = project.properties["nexus.password"].toString()
            }
        }
    }
    dependencies { classpath("com.company:kotlin-consolidated-plugin:1.0.0-SNAPSHOT") }
}

Наконец, плагиннеобходимо применить, используя имя файла свойств, указанное выше.

apply(plugin = "com.company.kotlinconsolidatedplugin") // Custom plugin cannot reside in plugin declaration above

Я создал образцы проектов и разместил их на Github, поэтому не стесняйтесь клонировать или просматривать: git@github.com:diendanyoi54 / kotlin-consolidated-plugin.git

git@github.com: diendanyoi54 / kotlin-consolidated-plugin-реализация.git

0 голосов
/ 30 октября 2019

Применение встроенных плагинов

plugins {
java
id("jacoco")
}

Вы также можете использовать более старый синтаксис применения:

apply(plugin = "checkstyle")

Применение внешних плагинов

plugins {
    id("org.springframework.boot") version "2.0.1.RELEASE"
}

Я не очень хорош в kotlin, но вот ссылка на лучшее понимание Отсутствует руководство по миграции на Gradle Kotlin DSL

...