【问题标题】:Can I call the Gradle properties task on all projects at once in a multi-project build?我可以在多项目构建中一次调用所有项目的 Gradle 属性任务吗?
【发布时间】:2021-03-22 10:22:43
【问题描述】:

我想查看 Gradle 项目的属性,以手动确保值正确。

当我从多项目构建的根目录调用properties 任务时,它会列出根项目的属性:

$ gradle -q properties

------------------------------------------------------------
Root project
------------------------------------------------------------

allprojects: [root project 'myapp', project ':api', project ':model', project ':ui']
ant: org.gradle.api.internal.project.DefaultAntBuilder@12345
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345
artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345
asDynamicObject: DynamicObject for root project 'myapp'
baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345
[...]

我还可以为每个单独的子项目请求属性:

$ gradle -q :api:properties

------------------------------------------------------------
Project :api - The shared API for the application
------------------------------------------------------------

allprojects: [project ':api']
ant: org.gradle.api.internal.project.DefaultAntBuilder@12345
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345
artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345
asDynamicObject: DynamicObject for project ':api'
baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345
[...]

但是,我真正想做的是一次列出给定项目及其所有子项目的属性。

我有点惊讶在根级别调用任务只提供根级别属性。这似乎与关于 executing tasks by name in a multi-project build 的 Gradle 文档相矛盾:

命令gradle test 将在具有该任务的任何子项目中执行test 任务,相对于当前工作目录。如果从项目根目录运行命令,您将在 apisharedservices:shared 中运行 test >服务:网络服务。如果从 services 项目目录运行命令,则只会在 services:shared 和 services:webservice 中执行任务。

Gradle 行为背后的基本规则是:执行层次结构中具有此名称的所有任务。仅在遍历的任何子项目中没有找到此类任务时才抱怨。

如何一次列出项目及其子项目的所有属性?作为奖励,为什么在根级别运行的properties 任务不也为子项目运行?我正在使用当前最新版本的 Gradle (6.7.1)。

【问题讨论】:

    标签: gradle gradle-task gradle-multi-project-build


    【解决方案1】:

    根据this Gradle Forum response,属性任务未针对子项目运行,因为属性任务的impliesSubProjects 属性在属性implementation 中为true

    HelpTasksPlugin 使用内部 API 将任务配置为忽略子项目任务

    […]

    如果impliesSubProjectstrue,则TaskNameResolver 不会查看任务的子项目。

    实验表明impliesSubProjects属性可以在构建文件中配置,允许为父项目及其所有子项目运行任务:

    properties {
        impliesSubProjects = false
    }
    

    输出

    $ gradle -q properties
    
    ------------------------------------------------------------
    Root project
    ------------------------------------------------------------
    
    allprojects: [root project 'myapp', project ':api', project ':model', project ':ui']
    ant: org.gradle.api.internal.project.DefaultAntBuilder@12345
    antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345
    artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345
    asDynamicObject: DynamicObject for root project 'myapp'
    baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345
    [...]
    
    ------------------------------------------------------------
    Project :api - The shared API for the application
    ------------------------------------------------------------
    
    allprojects: [project ':api']
    ant: org.gradle.api.internal.project.DefaultAntBuilder@12345
    antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@12345
    artifacts: org.gradle.api.internal.artifacts.dsl.DefaultArtifactHandler_Decorated@12345
    asDynamicObject: DynamicObject for project ':api'
    baseClassLoaderScope: org.gradle.api.internal.initialization.DefaultClassLoaderScope@12345
    [...]
    
    ------------------------------------------------------------
    Project :model - Shared object model
    ------------------------------------------------------------
    [...]
    

    但是请注意,impliesSubProjects 属性是在内部 API 中定义的(org.gradle.api.internal.AbstractTask 并且不是公共 Task API 的一部分(有关内部 API 的更多详细信息,请参阅 Avoid using internal Gradle APIs)。因此,如在链接的论坛回复中提到,这不适用于构建:

    请记住,这是一个内部实现细节,不打算由构建使用,并且不能保证它会在未来的 Gradle 版本中继续工作。

    但是,对于不是构建的持久部分的一次性属性比较,这种意外使用可能是可以接受的。

    【讨论】:

      【解决方案2】:

      可能是我理解错了你的问题。如果要列出所有属性,包括所有子项目以及根项目,则可以按如下方式创建构建文件:

      import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
      
      allprojects {
          repositories {
              mavenCentral()
          }
      
          group = "com.nononsensecode"
          version = "0.0.1"
      
      }
      
      plugins {
          kotlin("jvm") version "1.4.20" apply false
          base
      }
      
      configure(subprojects) {
          apply {
              plugin("org.jetbrains.kotlin.jvm")
          }
      
          configure<JavaPluginExtension> {
              sourceCompatibility = org.gradle.api.JavaVersion.VERSION_1_8
              targetCompatibility = org.gradle.api.JavaVersion.VERSION_1_8
          }
      
          tasks.withType<KotlinCompile>().configureEach {
              kotlinOptions {
                  jvmTarget = "1.8"
                  freeCompilerArgs = listOf("-Xjsr305=strict")
              }
          }
      
          dependencies {
              val implementation by configurations
      
              implementation(kotlin("stdlib-jdk8"))
              implementation(kotlin("reflect"))
          }
      
          task("listAllProperties") {
              val subProjectPropertiesMap = mutableMapOf<String, Map.Entry<String, Any?>>()
              subprojects.forEach { subProject ->
                  subProject.properties.forEach { property ->
                      subProjectPropertiesMap[subProject.name] = property
                  }
              }
      
              val allProperties = AllProperties(properties, subProjectPropertiesMap)
              println(allProperties)
          }
      }
      
      data class AllProperties(
          val properties: Map<String, Any?>,
          val subProjectProperties: MutableMap<String, Map.Entry<String, Any?>>
      )
      

      然后运行任务gradlew listAllProperties。如果你愿意,你可以创建一个toString 方法以漂亮的方式打印所有属性。

      【讨论】:

        猜你喜欢
        • 2015-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-08
        • 1970-01-01
        • 1970-01-01
        • 2015-08-11
        相关资源
        最近更新 更多