热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GradlewithGradleKotlinDSL中的Boilerplate项目配置

如何解决《GradlewithGradleKotlinDSL中的Boilerplate项目配置》经验,为你挑选了1个好方法。

我目前正在努力改进项目共享配置的方式.我们为所有库和微服务(即许多git repos)提供了许多不同的多模块gradle项目.

我的主要目标是:

不要在每个项目中复制我的Nexus存储库配置(同样,我可以放心地假设URL不会更改)

为了使我的自定义Gradle插件(发布到Nexus)可用于每个项目,只需极少的样板/复制(它们应该可用于每个项目,项目唯一关心的是它使用的版本)

没有魔力 - 开发人员应该明白如何配置所有内容

我目前的解决方案是使用init脚本的自定义gradle分发:

添加mavenLocal()和我们的Nexus存储库到项目repos(非常类似于Gradle init脚本文档示例,除了它添加repos以及验证它们)

配置一个扩展,允许我们的gradle插件添加到buildscript类路径(使用此解决方法).它还添加了我们的Nexus repo作为buildcript repo,因为它是托管插件的地方.我们有很多插件(基于Netflix优秀的星云插件)用于各种样板:标准项目设置(kotlin设置,测试设置等),发布,发布,文档等,这意味着我们的项目build.gradle文件几乎只用于依赖.

这是init脚本(已清理):

/**
 * 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 {

    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脚本应该是装饰性的并且做一些类似于记录的示例 - 防止未经授权的回购等.

我的想法是写一些扩展功能,让我对我们的Nexus回购和插件添加到构建的方式,看起来好像他们是建成gradle这个(类似扩展函数gradleScriptKotlin()kotlin-dsl()由摇篮科特林DSL提供.

所以我在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"))
    }
}

但是,Gradle在buildscript块中使用时无法看到我的函数(无法编译脚本).在正常的项目repos/dependencies中使用它们工作正常(它们是可见的并按预期工作).

如果这有效,我希望将jar捆绑到我的自定义发行版中,这意味着我的init脚本可以只进行简单的验证,而不是隐藏神奇的插件和repo配置.扩展函数不需要更改,因此在插件更改时不需要释放新的Gradle分布.

我尝试了什么:

将我的jar添加到测试项目的buildscript类路径(即buildscript.dependencies) - 不起作用(可能这在设计上不起作用,因为buildscript在同一块中引用的依赖项似乎不正确)

将函数放入buildSrc(适用于普通的项目deps/repos但不是buildscript,但不是真正的解决方案,因为它只是移动样板)

将jar放在发行版的lib文件夹中

所以我的问题归结为:

我正在尝试实现的是什么(是否可以使buildScript块可见的自定义类/函数)?

是否有更好的方法来配置企业Nexus仓库并使用最少的样板配置在许多单独的项目(即完全不同的代码库)中提供自定义插件(发布到Nexus)?

eskatos.. 12

如果您想从所有Gradle Kotlin DSL中获益,您应该努力使用该plugins {}块应用所有插件.请参阅https://github.com/gradle/kotlin-dsl/blob/master/doc/getting-started/Configuring-Plugins.md

您可以在设置文件中管理插件存储库和解决方案策略(例如,他们的版本).从Gradle 4.4开始,可以使用Kotlin DSL编写此文件settings.gradle.kts.请参阅https://docs.gradle.org/4.4-rc-1/release-notes.html.

考虑到这一点,您可以拥有一个集中的Settings脚本插件,可以设置并在构建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"
}

如果您希望项目在多项目构建中构建脚本以不重复插件版本,则可以通过在根项目中声明版本来使用Gradle 4.3执行此操作.请注意,您也可以将它的版本中settings.gradle.kts使用pluginManagement.resolutionStrategy,如果让所有建立使用相同的插件版本是你所需要的.

另请注意,要使所有这些工作正常,必须使用插件标记工件发布插件.这可以通过使用java-gradle-plugin插件轻松完成.



1> eskatos..:

如果您想从所有Gradle Kotlin DSL中获益,您应该努力使用该plugins {}块应用所有插件.请参阅https://github.com/gradle/kotlin-dsl/blob/master/doc/getting-started/Configuring-Plugins.md

您可以在设置文件中管理插件存储库和解决方案策略(例如,他们的版本).从Gradle 4.4开始,可以使用Kotlin DSL编写此文件settings.gradle.kts.请参阅https://docs.gradle.org/4.4-rc-1/release-notes.html.

考虑到这一点,您可以拥有一个集中的Settings脚本插件,可以设置并在构建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"
}

如果您希望项目在多项目构建中构建脚本以不重复插件版本,则可以通过在根项目中声明版本来使用Gradle 4.3执行此操作.请注意,您也可以将它的版本中settings.gradle.kts使用pluginManagement.resolutionStrategy,如果让所有建立使用相同的插件版本是你所需要的.

另请注意,要使所有这些工作正常,必须使用插件标记工件发布插件.这可以通过使用java-gradle-plugin插件轻松完成.


推荐阅读
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
author-avatar
辣手夏兰荇德_云
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有