当使用maven-publish
(incubating, I know) 发布时,compile
依赖项被添加到生成 POM(在runtime
范围内),但testCompile
依赖项被忽略。
如何将testCompile
依赖项作为test
作用域放入生成的 POM 中?
当使用maven-publish
(incubating, I know) 发布时,compile
依赖项被添加到生成 POM(在runtime
范围内),但testCompile
依赖项被忽略。
如何将testCompile
依赖项作为test
作用域放入生成的 POM 中?
我用了几个小时来找到一种很好的方法来选择工件或出版物应该使用的构建配置,但没有运气。我的发现是,实现它的唯一方法是修改生成的 POM XML,如下所示:
// build.gradle
publishing {
repositories { /* skipped for brevity */ }
publications {
core(MavenPublication) {
from components.java
artifactId project.name
artifact sourcesJar {
classifier 'sources'
}
}
generators(MavenPublication) {
from components.java
artifactId "${project.name}-generators"
artifacts = [ generatorsJar ]
artifact generatorsSourcesJar {
classifier 'sources'
}
pom.withXml { pomXml -> replaceDependenciesWith('generatorsBase', pomXml) }
}
}
}
void replaceDependenciesWith(String configurationName, XmlProvider pomXml) {
Node configurationDependencies = new Node(null, 'dependencies')
project.configurations.getByName(configurationName).allDependencies.each { dep ->
Node dependency = new Node(null, 'dependency')
dependency.appendNode('groupId', dep.group)
dependency.appendNode('artifactId', dep.name)
dependency.appendNode('version', dep.version)
dependency.appendNode('scope', 'compile')
configurationDependencies.append(dependency)
}
pomXml.asNode().dependencies*.replaceNode(configurationDependencies)
}
以上在 Gradle 3.3 上工作
我还尝试使用 Groovy 的类似 XML 构建器的语法,但不幸的是,错误的上下文附加到传递给replaceNode
方法的闭包,因此它不起作用。内联时,它获得与publications {}
闭包相同的上下文,而当提取到方法时,version dep.version
没有按预期工作)。
// Does not work!
void replaceDependenciesWith(String configurationName, Node pomXmlNode) {
pomXmlNode.dependencies*.replaceNode {
dependencies {
project.configurations.getByName(configurationName).allDependencies.each { dep ->
dependency {
groupId dep.group
artifactId dep.name
version dep.version
scope 'compile'
}
}
}
}
}
POM 仅在发布工件时使用;它与工件一起上传到 Maven 存储库。因此,POM 只需要运行时依赖。
Gradle 执行独立于您的部署插件的测试,因此它不使用 POM 文件。
假设您使用的是 Java 插件,它会添加test
源集。这反过来又创建了 testCompile 任务。
现在,Gradle 假设您的运行时依赖项将与您的编译时依赖项相同,如果您不进行其他配置。但是,它只考虑main
源集。这就是为什么您的 POM 不包含 test
依赖项的原因。
因此,总而言之,配置您的测试依赖项类似于以下内容。然后,快乐地生活,知道发布的工件不会包含您的测试代码或其依赖项。
dependencies {
testCompile 'org.springframework:spring-test:4.+'
}
如果您遇到特殊情况,即在无法访问测试源代码的机器上执行测试,请更详细地描述您的要求。应该可以为测试代码设置一个单独的输出工件,以便它可以发布,但我仍然认为您不应该将它发布在与main
源集相同的包(或 POM)中。
当我需要修改 POM xml 时,我无法使用 groovy 语言的任何功能。而且我不得不像krzychu 的回答一样直接依赖 API 。
否则 xml 闭包没有像我预期的那样应用,构建失败并带有一些警告,或者没有正确应用闭包导致无效的 pom.xml 。
但是最近,在仔细阅读了groovy 的闭包文档后,我注意到可以将 aresolutionStrategy
应用于闭包,以帮助运行时找到正确的上下文(隐含的 this)。
默认的解决策略是Closure.OWNER_FIRST
,这解释了为什么我publications
在一些试验中遇到了关于应用闭包的错误。从他们的文档中,我尝试将策略设置为Closure.DELEGATE_FIRST
,事实证明这按预期工作。
但是请注意,闭包必须应用于 a Node
,因此.children()
返回一个列表,.last()
返回一个Node
您可以通过.plus(...)
方法或其别名添加另一个节点的 a +
。
publishing {
publications {
core(MavenPublication) {
pom.withXml {
def dependenciesNode =
asNode().dependencyManagement
.first()
.dependencies
.first()
dependenciesNode.children().last().plus( {
resolveStrategy = Closure.DELEGATE_FIRST
dependency {
'groupId'('org.springframework.boot')
'artifactId'('spring-boot-dependencies')
'version'(rootProject.'spring-boot.version')
'type'('pom')
'scope'('import')
}
})
}
}
}
}