If I understand correctly, Gradle's compileOnly dependency corresponds to Gradle's older provided, and at the same time, Maven POM's provided. It works perfectly in the Gradle world.
But, compileOnly does not generate any provided dependency in pom.xml generated by maven-publish.
We are publishing a Maven artifact to Maven Central, using Gradle. We would like to declare provided explicitly in the published pom.xml from Gradle's compileOnly.
Does anyone know if there is any simple way to do that? Or, do we need to write our own Gradle scripting in :
publishing {
publications {
maven(MavenPublication) {
pom {
/* Our own Gradle scripting to declare provided dependencies. */
}
}
}
}
I know we can tweak it by scripting dirty like below, but we basically don't want to "script" in build.gradle as far as possible.
publishing {
publications {
maven(MavenPublication) {
pom {
withXml {
project.configurations.compileOnly.allDependencies.each { dependency ->
asNode().dependencies[0].appendNode("dependency").with {
it.appendNode("groupId", dependency.group)
it.appendNode("artifactId", dependency.name)
it.appendNode("version", dependency.version)
it.appendNode("scope", "provided")
}
}
}
}
}
}
}
I think scripting is the way to go... you can create a method och pass the pom e.g
publishing {
publications {
mavenDependencyList(MavenPublication) {
fixDependencyScope(pom)
}
}
}
void fixDependencyScope(pom) {
pom.withXml {
asNode().dependencies.'*'.findAll() {
it.scope.text() == 'compileOnly' && project.configurations.compile.allDependencies.find { dep ->
dep.name == it.artifactId.text()
}
}.each() {
it.scope*.value = 'provided'
}
}
}
Related
I want to run QueryDsl Q-type generation in a separate task. I want that Q-type classes not to be created in a regular compileJava task, but the compiler sees the AnnotationProcessor in the classpath and creates them itself. I tried nulling the annotationProcessorPath, but then I couldn't restore its configuration in a separate task.
May be is it possible to exclude somehow dependencies of subtasks from the classpath?
compileJava {
options.annotationProcessorPath = null
}
tasks.register('generateQTypes'){
group 'build'
description 'Generate Q-Type classes with QueryDsl library'
dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
compileJava {
options.annotationProcessorPath = classpath
}
}
What is the best way to solve this problem?Thanks in advance!
I made the following solution
class QTypeGenerator extends DefaultTask {
#TaskAction
addDependencies() {
project.dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
}
}
tasks.register("generateQTypeClasses", QTypeGenerator) {
group('build')
description('Generate Q-type classes by queryDsl in build directory with default path')
finalizedBy('compileJava')
doLast {
println("Q-types classes will gererated and stored in ${compileJava.options.annotationProcessorGeneratedSourcesDirectory}")
}
}
I have a distributes projects with different sub-projects and I want to accomplish the following:
(root)
client
module A
module B
module C
model
I want to put
protoc {
artifact = 'com.google.protobuf:protoc:3.5.0'
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:1.7.0"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
} }
dependencies {
compile "com.google.api.grpc:proto-google-common-protos:1.0.0"
compile "io.grpc:grpc-netty:1.7.0"
compile "io.grpc:grpc-protobuf:1.7.0"
compile "io.grpc:grpc-stub:1.7.0"
}
for module A, B and C.
For now I have the following in my root build.gradle
subprojects{
apply plugin: 'java'
sourceCompatibility = 1.8
group 'project'
version '0.0.1-SNAPSHOT'
jar {
manifest {
attributes 'Main-Class': "com.project.${project.name}.App"
}
doFirst {
from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
}
}
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
}
}
So every sub-project use java plugin, and has the defines dependencies and jar task.
How can I only put the first block for some sub-projects ?
I tried using a variable like in Multi-project Builds - Gradle but I couldn't access it in subprojects block.
Thank you in advance. I'm really interested in using Gradle correctly and it's a bit hard to get into it outside of simple Android/Java projects. Feel free to include any documentations I should read :)
Edit:
Thank you. I wouldn't have posted here if I hadn't search before. Apparently I was missing the keyword "subset" who would have gave me the solution you linked.
A solution is described here: https://discuss.gradle.org/t/configure-only-subset-of-subprojects/5379/3
You can run configure() with a list of projects.
project.ext {
subprojectList = subprojects.findAll{
it.name == 'subprojectA' ||
it.name == 'subprojectB' ||
it.name == 'subprojectC'
}
}
configure(project.subprojectList) {
// insert your custom configuration code
}
or
configure([project(':a'), project(':b'), project(':c')]) {
// configuration
}
What option would be preferable, if we have to generate a java library using maven-publish plugin
Option 1:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
Option 2:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
versionMapping {
allVariants {
fromResolutionResult()
}
}
}
}
}
What is the role of versionMapping in maven-publish plugin
Per the docs:
Two strategies are supported for publishing dependencies:
-- snip
This is done by using the versionMapping DSL method
What option would be preferable
That is entirely dependent on your use case/needs. As mentioned in the docs, there are two strategies for dependencies: declared versions and resolved versions. Which one you use is entirely dependent on your use case or needs.
The shadow plugin documentation has an example for groovy but I do not understand how to translate this to Kotlin.
Groovy example from https://imperceptiblethoughts.com/shadow/publishing :
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
}
}
}
My best attempt at the Kotlin version:
publishing {
publications {
create<MavenPublication>("pluginMaven") {
artifact(tasks["shadowJar"])
project.shadow.component(this)
}
}
}
With the above Kotlin version, shadowed dependencies show up in the resulting pom as runtime dependencies, which defies of purpose of shadowing.
The solution is
tasks {
shadowJar {
archiveClassifier.set("")
minimize()
}
}
Some background in this github issue.
Below is a example where, in order to add a custom-plugin to the application, we need to specify it dependency in resolution strategy and by using useModule, to add it in classpath
-------build.gradle----------
plugins {
id 'custom-plugin'
}
-------settings.gradle----------
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'custom-plugin') {
useModule('org.gradle.sample:custom-plugins:1.0.0')
}
}
}
repositories {
maven { url 'maven-repo' }
}
}
Is there any simpler/better way to add the dependency (useModule section)?
I don't want to add if condition and check the namespace requested.id.namespace every time for any new custom plugin I add.
Is there a way to avoid this just like in the old way of adding plugin in the application, wherein buildscript block we just have to add that dependency using classpath.
buildscript {
repositories {
maven { url "https://privaterepo.myemployer.com" }
}
dependencies {
classpath "org.gradle.sample:custom-plugins:1.0.0"
}
This depends, if the repository knows the requested requested.id.id, with the default .gradle.plugin suffix added. Your question led to another answer - and the example which I provide there, probably shows when it's required to use resolutionStrategy and when not.