当前位置: 首页 > 知识库问答 >
问题:

用Gradle Kotlin DSL在Gradle中进行样板工程配置

乜璞瑜
2023-03-14

我目前正在努力改进我们的项目共享配置的方式。我们有很多不同的多模块gradle项目用于我们所有的库和微服务(即许多git Repo)。

我的主要目标是:

  • 不要在每个项目中重复我的Nexus存储库配置(另外,我可以放心地假设URL不会更改)
  • 使我自定义的Gradle插件(发布到Nexus)能够以最少的样板/重复为每个项目所用(它们应该可以为每个项目所用,项目唯一关心的是它所使用的版本)
  • 没有魔力-对于开发人员来说,一切都是如何配置的应该是显而易见的
    null
/**
 * Gradle extension applied to all projects to allow automatic configuration of Corporate plugins.
 */
class CorporatePlugins {

    public static final String NEXUS_URL = "https://example.com/repository/maven-public"
    public static final String CORPORATE_PLUGINS = "com.example:corporate-gradle-plugins"

    def buildscript

    CorporatePlugins(buildscript) {
        this.buildscript = buildscript
    }

    void version(String corporatePluginsVersion) {
        buildscript.repositories {
            maven {
                url NEXUS_URL
            }
        }
        buildscript.dependencies {
            classpath "$CORPORATE_PLUGINS:$corporatePluginsVersion"
        }
    }

}

allprojects {
    extensions.create('corporatePlugins', CorporatePlugins, buildscript)
}

apply plugin: CorporateInitPlugin

class CorporateInitPlugin implements Plugin<Gradle> {

    void apply(Gradle gradle) {

        gradle.allprojects { project ->

            project.repositories {
                all { ArtifactRepository repo ->
                    if (!(repo instanceof MavenArtifactRepository)) {
                        project.logger.warn "Non-maven repository ${repo.name} detected in project ${project.name}. What are you doing???"
                    } else if(repo.url.toString() == CorporatePlugins.NEXUS_URL || repo.name == "MavenLocal") {
                        // Nexus and local maven are good!
                    } else if (repo.name.startsWith("MavenLocal") && repo.url.toString().startsWith("file:")){
                        // Duplicate local maven - remove it!
                        project.logger.warn("Duplicate mavenLocal() repo detected in project ${project.name} - the corporate gradle distribution has already configured it, so you should remove this!")
                        remove repo
                    } else {
                        project.logger.warn "External repository ${repo.url} detected in project ${project.name}. You should only be using Nexus!"
                    }
                }

                mavenLocal()

                // define Nexus repo for downloads
                maven {
                    name "CorporateNexus"
                    url CorporatePlugins.NEXUS_URL
                }
            }
        }

    }

}

然后,我通过向根build.gradle文件添加以下内容来配置每个新项目:

buildscript {
    // makes our plugins (and any others in Nexus) available to all build scripts in the project
    allprojects {
        corporatePlugins.version "1.2.3"
    }
}

allprojects  {
    // apply plugins relevant to all projects (other plugins are applied where required)
    apply plugin: 'corporate.project'

    group = 'com.example'

    // allows quickly updating the wrapper for our custom distribution
    task wrapper(type: Wrapper) {
        distributionUrl = 'https://com.example/repository/maven-public/com/example/corporate-gradle/3.5/corporate-gradle-3.5.zip'
    }
}

虽然这种方法可行,但它允许可复制的构建(与我们以前的设置不同,我们以前的设置是从URL应用构建脚本--当时这是不可缓存的),并允许脱机工作,但它确实让它变得有点神奇,我想知道我是否可以做得更好。

这一切都是由阅读Gradle dev Stefan Oehme在Github上的一篇评论引发的,该评论指出构建应该在不依赖init脚本的情况下工作,即init脚本应该只是装饰性的,并做一些类似于文档化示例的事情--防止未经授权的回购等。

因此,我在kotlin gradle项目中创建了扩展函数:

package com.example

import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.MavenArtifactRepository

fun RepositoryHandler.corporateNexus(): MavenArtifactRepository {
    return maven {
        with(it) {
            name = "Nexus"
            setUrl("https://example.com/repository/maven-public")
        }
    }
}

fun DependencyHandler.corporatePlugins(version: String) : Any {
    return "com.example:corporate-gradle-plugins:$version"
}

计划在我的项目的build.gradle.kts中使用它们,如下所示:

import com.example.corporateNexus
import com.example.corporatePlugins

buildscript {

    repositories {
        corporateNexus()
    }

    dependencies {
        classpath(corporatePlugins(version = "1.2.3"))
    }
}

但是,当在buildscript块中使用时,Gradle无法看到我的函数(无法编译脚本)。但是,在正常的项目中使用它们,回购/依赖关系运行良好(它们是可见的,并按预期工作)。

    null
  • 是我试图实现的可能(是否可以使自定义类/函数对buildscript块可见)?
  • 是否有更好的方法来配置公司Nexus repo并使自定义插件(发布到Nexus)在许多独立的项目(即完全不同的代码库)中可用,同时使用最少的样板配置?

共有1个答案

隆飞宇
2023-03-14

如果您想从Gradle Kotlin DSL的所有优点中获益,您应该努力使用plugins{}块应用所有插件。参见https://github.com/gradle/kotlin-dsl/blob/master/doc/getting-start/configuring-plugins.md

您可以在您的设置文件中管理插件存储库和解决策略(例如,它们的版本)。从Gradle4.4开始,可以使用Kotlin DSL编写该文件,也就是settings.Gradle.kts。参见https://docs.gradle.org/4.4-rc-1/release-notes.html。

考虑到这一点,您就可以拥有一个集中式的settings.gradle.kts脚本插件,用于设置并将其应用到构建settings.gradle.kts文件中:

// corporate-settings.gradle.kts
pluginManagement {
    repositories {
        maven {
            name = "Corporate Nexus"
            url = uri("https://example.com/repository/maven-public")
        }
        gradlePluginPortal()
    }
}

和:

// settings.gradle.kts
apply(from = "https://url.to/corporate-settings.gradle.kts")

然后,在您的项目构建脚本中,您可以简单地从公司存储库中请求插件:

// build.gradle.kts
plugins {
    id("my-corporate-plugin") version "1.2.3"
}

如果您希望多项目构建中的项目构建脚本不重复插件版本,可以通过在根项目中声明版本来使用Gradle4.3。请注意,如果需要所有构建使用相同的插件版本,您还可以使用pluginmanagement.resolutionStrategysettings.gradle.kts中设置版本。

 类似资料:
  • 使用HiberNate ant任务从Gradle我能够生成实体类从数据库使用留档在http://docs.jboss.org/tools/latest/en/hibernatetools/html_single/index.html#d0e5102 当我更改和时,HiberNate找不到我的自定义模板。可以肯定的是,我直接从hiberNate jars复制了模板,并在Pojo.ftl.中添加了一个

  • Gradle项目中典型的静态编程语言配置是非常样板的,我正在寻找一种将其抽象成外部构建脚本的方法,以便可以重用。 我有一个可行的解决方案(见下文),但它感觉有点像黑客,因为kotlin gradle插件不是这样开箱即用的。 从外部脚本应用任何非标准插件都很麻烦,因为您无法通过id应用插件,即。 将导致找不到id为'kotlin'的 应用),您就可以开始运行kotlin开发了。 它是有效的,我还没有

  • Boilerpipe是一个基本上从网页中提取主要内容的库。对于新闻网站来说,提取内容尤其困难,因为不同网站的格式不同。所以我试着整合样板管库-https://code.google.com/p/boilerpipe/wiki/QuickStart 根据安装指南,我已经将以下内容添加到我的Java类路径-boilerpipe版本中。jar,nekohtml-1.9.13。jar和xerces-2.9

  • 使用 Groovy 模板引擎框架简化报表视图 视图是 MVC 编程的一个重要部分,而 MVC 编程本身又是企业应用程序开发的一个重要组件。在这篇实战 Groovy 的文章中,Andrew Glover 向您介绍了 Groovy 的模板引擎框架是如何用来简化视图编程的,并如何使您的代码更加经久容易维护。 在最近的 实战 Groovy系列中,我们已经介绍过 Groovy 是构建报表统计程序的一个非常好

  • 简介 在之前的章节我们实现了一个简单但是功能齐全的web项目、学习了如何使用Gradle来构建和运行这个项目。测试代码是软件开发周期中非常重要的一环,能够确保软件的行为能符合预期。这一章我将讲述如何使用Gradle来组织、配置和执行测试代码,学习如何写单元测试、集成测试和功能测试并把他们集成到项目构建中。 Gradle集成了很多Java和Groovy测试框架,在本章的最后你会用JUnit、Test