gradle 等级:独立依赖的互斥

kh212irz  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(100)

我正在处理一个等级项目,我有两个完全独立的项目(称之为A和B)。我想设置项目A的gradle配置,以便如果它包含在其他库/应用程序C中,如果C也依赖于项目B,则构建将失败。
例如,如果我有一个项目C,它看起来像这样:

dependencies {
   implementation("A")
}

字符串
或本

dependencies {
   implementation("B")
}


项目C可以很好地构建。但是如果项目C看起来像这样:

dependencies {
  implementation("A")
  implementation("B")
}


它将无法建成。
这个问题有几个限制,使它更具挑战性:

  • 由于太复杂的原因,这里无法深入研究,项目C无法真正了解这种互斥。
  • 项目A和B中的代码彼此不知道。

等级有什么特征可以支持我在这里要做的吗?

k2arahey

k2arahey1#

有两种方法可以尝试:

1.声明项目A提供与项目B相同的功能(假设您有权更新项目A)

# A/build.gradle

configurations {
    apiElements {
        outgoing {
            // format: groupId:name:version

            // default capability for project A
            capability("gradle.mutual.exclusion.a:A:1.0.0")

            // new capability which is the same as default capability in project B
            capability("gradle.mutual.exclusion.b:B:1.0.0")
        }
    }
}

字符串
因此,当您发布项目A的工件时,gradle将发布模块元数据以及给定存储库(Maven或Ivy)的普通描述符。该模块元数据包括上面设置的功能。
在项目C中,如果你尝试同时使用依赖项A和B,如下所示:

# C/build.gradle

dependencies {
    implementation 'gradle.mutual.exclusion.b:B:1.0.0'
    implementation 'gradle.mutual.exclusion.a:A:1.0.0'
}


它应该失败,因为两个依赖项都提供了相同的功能gradle.mutual.exclusion.b:B:1.0.0,而gradle不允许这样做:

> Could not resolve all files for configuration ':C:compileClasspath'.
   > Could not resolve gradle.mutual.exclusion.b:B:1.0.0.
     Required by:
         project :C
      > Module 'gradle.mutual.exclusion.b:B' has been rejected:
           Cannot select module with conflict on capability 'gradle.mutual.exclusion.b:B:1.0.0' also provided by [gradle.mutual.exclusion.a:A:1.0.0(apiElements)]
   > Could not resolve gradle.mutual.exclusion.a:A:1.0.0.
     Required by:
         project :C
      > Module 'gradle.mutual.exclusion.a:A' has been rejected:
           Cannot select module with conflict on capability 'gradle.mutual.exclusion.b:B:1.0.0' also provided by [gradle.mutual.exclusion.b:B:1.0.0(apiElements)]


注意:项目B可能有一个不同的版本,这也是罚款,应该工作。

2.在项目C中设置能力规则(假设您有更新项目C的权限)

# C/build.gradle

import groovy.transform.CompileStatic

@CompileStatic
class ABCapability implements ComponentMetadataRule {
    final static Set<String> AB_MODULES = ["A", "B"] as Set<String>

    void execute(ComponentMetadataContext context) {
        context.details.with {
            if (AB_MODULES.contains(id.name)) {
                allVariants {
                    it.withCapabilities {
                        // Declare that both A and B provide the same capability
                        it.addCapability("AB", "AB", id.version)
                    }
                }
            }
        }
    }
}

dependencies {
    components.all(ABCapability)

    implementation 'gradle.mutual.exclusion.b:B:1.0.0'
    implementation 'gradle.mutual.exclusion.a:A:1.0.0'
}


这是非常相似的逻辑,它依赖于对项目A和B使用相同的功能。这种情况下的失败如下所示:

> Could not resolve all files for configuration ':C:compileClasspath'.
   > Could not resolve gradle.mutual.exclusion.b:B:1.0.0.
     Required by:
         project :C
      > Module 'gradle.mutual.exclusion.b:B' has been rejected:
           Cannot select module with conflict on capability 'AB:AB:1.0.0' also provided by [gradle.mutual.exclusion.a:A:1.0.0(apiElements)]
   > Could not resolve gradle.mutual.exclusion.a:A:1.0.0.
     Required by:
         project :C
      > Module 'gradle.mutual.exclusion.a:A' has been rejected:
           Cannot select module with conflict on capability 'AB:AB:1.0.0' also provided by [gradle.mutual.exclusion.b:B:1.0.0(apiElements)]

相关问题