有没有一种方法可以定义在gradle 6.0中用于settings.gradle.kts和project / subprojects build.gradle.kts的属性?

我们有多模块android应用,其构建逻辑以gradle kotlin dsl编写。我们使用buildSrc提取诸如依赖项版本之类的通用逻辑。我们有类似的东西:

buildSrc/src/main/kotlin/Dependencies.kt

object Versions {
    const val fooVersion = "1.2.3"
    const val barVersion = "4.5.6"
}

object libraries {
    val foo = "com.example.foo:foo:$fooVersion"
    val bar = "com.example.bar:bar:$barVersion"
}

object Modules {
    const val app = ":app"
    const val base = ":base"
    const val baz = ":baz"
}

然后我们可以在模块的dependencies块中使用它们,以避免硬编码/重复的值:

app/build.gradle.kts

dependencies {
    implementation(Libs.foo)
    implementation(Libs.bar)

    implementation(project(Modules.base))
    implementation(project(Modules.baz))
}

我们也在settings.gradle.kts中使用它:

settings.gradle.kts

include(
    Modules.app,Modules.base,Modules.baz
)

使用gradle 5.6可以正常工作。升级到6.0时,我在settings.gradle.kts文件中得到Unresolved reference: Modules。我发现它在migration guide中提到:

  

以前,buildSrc项目是在应用项目的设置脚本之前构建的,并且其类在脚本中可见。现在,在设置脚本及其类对它不可见之后,将构建buildSrc。 buildSrc类对于项目构建脚本和脚本插件仍然可见。

     

可以通过声明外部依赖项从设置脚本中使用自定义逻辑。

所以我知道是什么破坏了构建,并且可以通过使用settings.gradle.kts中的硬编码值来修复构建:

include(
    ":app",":base",":baz"
)

是否可以使用gradle 6.0避免这种重复?

lusia_123 回答:有没有一种方法可以定义在gradle 6.0中用于settings.gradle.kts和project / subprojects build.gradle.kts的属性?

请参见ticket #11090 "Definitions from buildSrc/ not found in settings.gradle.kts using gradle 6.0-rc-1"

您已经注意到最近发生了变化:

在6.0中已更改,在5.6中已弃用。请参阅:https://docs.gradle.org/current/userguide/upgrading_version_5.html#buildsrc_usage_in_gradle_settings

-https://github.com/gradle/gradle/issues/11090#issuecomment-544473179

One of the maintainers描述了做出此决定的原因:

不幸的是,这两种安排(settings-then-buildSrcbuildSrc-then-settings)各有利弊,我们在考虑后选择了前者。

(...)

迫使我们做出改变的专家:

  1. 设置插件可以影响buildSrc和主构建(即,将构建插件同时应用于两者)
  2. 将构建缓存配置应用于buildSrc
  3. buildSrc的行为更类似于常规包含的构建

-https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

最后是一些坏消息:

我们不会将行为更改回Gradle 6之前的版本。请让我们知道,如果您想了解更多有关如何在设置脚本中使用一种使用复杂逻辑的替代机制的信息。

-https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

解决方法

在上述文章中,作者提出了一些解决方法:

这恰恰是您所遇到的问题。现在,在设置脚本中使用复杂的逻辑变得不那么方便了。现在,您必须:

  1. 将逻辑内联到设置文件中
  2. 将逻辑移动到可以在需要的地方使用的共享脚本
  3. 将逻辑移至您在设置文件(即设置插件)中加载的预构建二进制文件

-https://github.com/gradle/gradle/issues/11090#issuecomment-545697268

#1非常简单,但是我只能假设#2和#3是什么意思。我来自Groovy世界,直到最近才开始与Kotlin DSL交朋友。话虽如此,让我们尝试一下。

在#3中,作者可能正在谈论开发外部插件并将其应用于两个脚本中。我不太确定这是否可以实现(尽管它可以为您提供强类型的输入)。

“#2将逻辑移动到可以在需要的地方使用的共享脚本”

我认为这是关于拥有一个公用的script plugin并将其同时包含在settings.gradlebuild.gradle文件中。该插件会将静态信息放入范围为ExtraPropertiesExtensionExtensionAware的范围内(如果是settings.gradle脚本插件,则为Settings;如果是{{ {1}})。 Project中对此进行了描述:

如何仅通过使用springBootVersion或Constants.springBootVersion之类的东西进行编译时检查,将所有公共常数(例如依赖项版本)放入单独的文件中?

目前尚无好的方法。您可以使用其他属性,但不能保证编译时检查。像这样的东西:

build.gradle

您可以像这样使用它:

// $rootDir/dependencies.gradle.kts

// this will try to take configuration from existing ones
val compile by configurations
val api by configurations
dependencies {
  compile("commons-io:commons-io:1.2.3")
  api("some.dep")
}

// This will put your version into extra extension
extra["springBootVersion"] = "1.2.3"

在您的模块中:

// $rootDir/build.gradle.kts
subprojects {
  apply {
    plugin<JavaLibraryPlugin>()
    from("$rootDir/dependencies.gradle.kts")
  }

-this answer to "Include scripts with Gradle Kotlin DSL"

,

AFAIK-不,这就是上述迁移指南所说的:settings.gradle是第一个要评估的,因此在那个阶段,buildSrc中定义的对象甚至还不存在。

可以想象一些骇人听闻的解决方法-仅出于科学目的,但是在实际项目中,它闻起来很难闻,以至于IMO,都不值得。

P。 S .:我想您可以反转它,并尝试通过buildSrc代码中的子模块来创建一些枚举的实例。但同样,实现这一目标的方法可能还很陌生,仅应用于证明其可行的唯一目的

本文链接:https://www.f2er.com/3022986.html

大家都在问