在Gradle中,如何以编程方式排除然后强制依赖?

在Gradle中,如何以编程方式排除然后强制依赖?,gradle,Gradle,最终目标是用不同的版本替换可传递依赖项的版本。需要注意的是,替换应该由那些依赖于正在构建的库的人来选择(我不知道它是标准Gradle还是插件,但是如果我们排除了一个可传递的依赖项,那么生成的ivy.xml文件将包含该信息) 实现最终目标的一种可能方法是排除所讨论的依赖项,然后在以后强制该依赖项 排除依赖项的方法如下所示: dependencies { compile 'org:name:version' { exclude(group: 'group', module:

最终目标是用不同的版本替换可传递依赖项的版本。需要注意的是,替换应该由那些依赖于正在构建的库的人来选择(我不知道它是标准Gradle还是插件,但是如果我们
排除了一个可传递的依赖项,那么生成的
ivy.xml
文件将包含该信息)

实现最终目标的一种可能方法是
排除所讨论的依赖项,然后在以后强制该依赖项

排除依赖项的方法如下所示:

dependencies {
    compile 'org:name:version' {
        exclude(group: 'group', module: 'module')
    }
}
configurations.all {
    resolutionStrategy {
        eachDependency { DependencyResolveDetails dependencyResolveDetails ->
            final requestedDependency = dependencyResolveDetails.requested
            if (requestedDependency.group == 'org' && requestedDependency.name == 'name') {
                force 'group:module:good_version'
            }
        }
    }
}
dependencies {
    compile dep('org:name')
}
强制执行依赖项的方法如下所示:

dependencies {
    compile 'org:name:version' {
        exclude(group: 'group', module: 'module')
    }
}
configurations.all {
    resolutionStrategy {
        eachDependency { DependencyResolveDetails dependencyResolveDetails ->
            final requestedDependency = dependencyResolveDetails.requested
            if (requestedDependency.group == 'org' && requestedDependency.name == 'name') {
                force 'group:module:good_version'
            }
        }
    }
}
dependencies {
    compile dep('org:name')
}

为了将两者联系在一起,
resolutionStrategy
必须知道哪些依赖项实际上
排除了以后将成为
force
d的可传递依赖项。如何以通用的方式实现这一点(假设有一种通用的方式来执行
排除
)?如果没有办法将两者联系在一起,是否有不同的方法来实现最终目标?

首先,对依赖项进行抽象,使其看起来像:

dependencies {
    compile 'org:name:version' {
        exclude(group: 'group', module: 'module')
    }
}
configurations.all {
    resolutionStrategy {
        eachDependency { DependencyResolveDetails dependencyResolveDetails ->
            final requestedDependency = dependencyResolveDetails.requested
            if (requestedDependency.group == 'org' && requestedDependency.name == 'name') {
                force 'group:module:good_version'
            }
        }
    }
}
dependencies {
    compile dep('org:name')
}
dep
功能的定义方式将考虑自动排除:

final rev = [
    'group:module': 'good_version'
    'org:name': 'version']

ext.rev = { m ->
    rev[m]
}

final dep = { m ->
    "${m}:${ext.rev(m)}"
}

final forcedTransitiveDeps = [
        'org:name': [
            dep('group:module')]].withDefault({[]})

ext.forcedTransitiveDeps = { m ->
    forcedTransitiveDeps[m]
}

ext.dep = { m ->
    if (!forcedTransitiveDeps.containsKey(m)) {
        project.dependencies.create(dep(m))
    } else {
        project.configure(
                project.dependencies.create(dep(m)),
                {
                    forcedTransitiveDeps[m].each { dependency ->
                        final dependencyParts = dependency.split(':')
                        exclude(group: dependencyParts[0], module: dependencyParts[1])
                    }
                })
    }
}
最后,要重新引入和强制依赖项:

subprojects { subproject ->
    subproject.afterEvaluate {
        subproject.configurations.all { Configuration configuration ->
            final dependencies = configuration.getDependencies()
            final forcedDependencies = (dependencies.collect { dependency ->
                forcedTransitiveDeps("${dependency.group}:${dependency.name}")
            }).flatten()
            if (!forcedDependencies.isEmpty()) {
                logger.info("Forcing ${subproject} dependencies on ${forcedDependencies} as per `ext.forcedTransitiveDeps`.")
                dependencies.addAll(forcedDependencies.collect { forcedDependency ->
                    subproject.dependencies.create(forcedDependency)
                })
            }
        }
    }
}

compile('com.lib:library:X.Y.Z){exclude group:'other library:project'}\n compile“other library:project:X.Y.Z”如果您的库在项目中是可传递的,并且需要将其带到父项目(即记录器库),请使用提供的而不是已编译的。这带来了一个虚拟版本的库,需要稍后由父项目编译。@MLCIM程序员,我想以编程方式进行,因为它是一个多模块项目,我想保持干燥。天才和疯狂之间有一条细微的界限,不是我画的。您的解决方案看起来很棒(tho:)