我有一个 gradle 插件来实现自定义版本控制方案,几乎与 gradle 文档第 49.8.2.2 节中的建议相同。使用 gradle 的公司项目应用插件,然后按照建议声明依赖项: compile 'group:name:{default}' 其中 {default} 是一个字符串,表示实际版本应由插件提供。该插件在配置时将 {default} 替换为由插件中的逻辑确定的正确版本。这一切都很好。
问题是,当我运行使用 mavenDeployer 的 uploadArchives 任务时,生成的 pom 文件中生成的依赖项会获得 {default} 的版本,即指示符字符串而不是实际的依赖项版本。当我们的 Maven 项目尝试将这个 pom 作为依赖项引入时,他们无法解决它的依赖项。
环顾网络并自己弄乱它,似乎在运行 uploadArchives 任务时,gradle首先转储了所有其他构建的配置。因此,即使项目配置是在配置阶段由具有正确依赖版本的插件构建的,在生成 pom 文件时,uploadArchives 任务也不会使用具有这些版本的配置。
如何让 uploadArchives 任务使用自定义版本插件在配置时解析的依赖版本生成 pom 文件?
这是我的 build.gradle 文件:
buildscript {
repositories {
maven {url "somewhere/overtherainbow/releases/"}
}
dependencies {
classpath 'com.overtherainbow:custom-dependency-resolution-plugin:1.0-SNAPSHOT'
}
}
subprojects {
apply plugin: 'custom-dependency-resolution'
apply plugin: 'java'
apply plugin: 'maven'
group = "com.overtherainbow"
version ="1.0-SNAPSHOT"
repositories {
maven {url "somewhere/overtherainbow/releases/"}
mavenCentral()
}
dependencies {
compile 'javax.servlet:servlet-api:default'
compile 'log4j:log4j:default'
}
uploadArchives {
repositories {
mavenDeployer {
uniqueVersion = false
repository(url: "somewhere/overtherainbow/releases)
snapshotRepository(url: "somewhere/overtherainbow/snapshots")
}
}
}
}
project(':bar') {
dependencies {
compile project(':common')
compile project(':foo')
}
}
project(':foo') {
dependencies {
compile project(':common')
}
}
这是插件代码:
package com.overtherainbow
import org.gradle.api.Project
import org.gradle.api.Plugin
import org.gradle.api.artifacts.DependencyResolveDetails
class DefaultVersionPlugin implements Plugin<Project> {
// This is where dependency versions are defined
def defaultVersionsMap = [
'javax.servlet:servlet-api' : '2.5',
'log4j:log4j' : '1.2.16']
void apply(Project project) {
project.configurations.all {
resolutionStrategy.eachDependency {
DependencyResolveDetails details -> resolveDependencyVersion(project, details)
}
}
}
def resolveDependencyVersion(Project project, DependencyResolveDetails details) {
if (details.requested.version == 'default') {
def version = resolveDefaultVersion(project, details.requested.group, details.requested.name)
details.useVersion version
}
}
def resolveDefaultVersion(Project project, String group, String name) {
project.logger.debug("Resolving default dependency for $group:$name")
println "Resolving default dependency for $group:$name"
defaultVersionsMap["$group:$name"]
}
}
以及运行uploadArchives 的输出,请注意插件在每个项目的第一个任务(compileJava)期间运行,而不是uploadArchives:
$ gradle uploadArchives
:common:compileJava
Resolving default dependency for javax.servlet:servlet-api
Resolving default dependency for log4j:log4j
:common:compileJava UP-TO-DATE
:common:processResources UP-TO-DATE
:common:classes UP-TO-DATE
:common:jar UP-TO-DATE
:foo:compileJava
Resolving default dependency for javax.servlet:servlet-api
Resolving default dependency for log4j:log4j
:foo:compileJava UP-TO-DATE
:foo:processResources UP-TO-DATE
:foo:classes UP-TO-DATE
:foo:jar UP-TO-DATE
:bar:compileJava
Resolving default dependency for javax.servlet:servlet-api
Resolving default dependency for log4j:log4j
:bar:compileJava UP-TO-DATE
:bar:processResources UP-TO-DATE
:bar:classes UP-TO-DATE
:bar:jar UP-TO-DATE
:bar:uploadArchives
Uploading: com/overtherainbow/bar/1.0-SNAPSHOT/bar-1.0-SNAPSHOT.jar to...
Transferring 19K from remote
Uploaded 19K
:common:uploadArchives
Uploading: com/overtherainbow/common/1.0-SNAPSHOT/common-1.0-SNAPSHOT.jar to...
Transferring 5K from remote
Uploaded 5K
:foo:uploadArchives
Uploading: com/overtherainbow/foo/1.0-SNAPSHOT/foo-1.0-SNAPSHOT.jar to...
Transferring 15K from remote
Uploaded 15K
下面是生成的 pom 文件的依赖项部分,注意版本设置为默认值:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>default</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>default</version>
<scope>compile</scope>
</dependency>
</dependencies>