How Map gradle 'compileOnly' to 'provided' in generated pom (generatePom...) - maven

I am using gradle 4.3.1 I have dependencies in scope compileOnly when I publish to maven I see that these dependencies are not in the pom file.
I would like to map them to provided scope of maven.
How can I do that?

I'm not aware of any clean solution (maven-publish plugin is still incubating), so I took inspiration from https://stackoverflow.com/a/25201395/2838501 and have a dirty solution:
publications {
mavenJava(MavenPublication) {
from components.java
pom.withXml {
project.configurations.compileOnly.allDependencies.each { dep ->
asNode().dependencies[0].appendNode('dependency').with {
it.appendNode('groupId', dep.group)
it.appendNode('artifactId', dep.name)
it.appendNode('version', dep.version)
it.appendNode('scope', 'provided')
}
}
}
}
}

Related

publish groovy doc with gradle

I have a project with about 50% Java code and 50% Groovy that i try to publish to Sonatype ossrh. Publishing snapshots goes well but the docs jar is missing (both when publishing locally and publishing to Sonatype Nexus). I can create the combined groovy/java docs by defining:
groovydoc {
use = true
groovyClasspath = configurations.compile // http://issues.gradle.org/browse/GRADLE-1391
}
task groovydocJar(type: Jar, dependsOn: groovydoc ) {
classifier 'javadoc' // must use javadoc classifier to be able to deploy to Sonatype
from groovydoc.destinationDir
}
and running ./gradlew groovydocJar produces the intended -javadoc.jar without problems.
My issue is that this docs jar is not included the publish task.
I tried the following
publishing {
publications {
maven(MavenPublication) {
from components.java
artifacts {
archives sourcesJar
archives groovydocJar
}
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
// omitted for brevity
}
}
}
}
... but e.g. `./gradlew publishToMavenLocal` publishes only the classes jar, the pom, a module and the sources jar.
No sign of a javadoc jar. I thought this was the idea of the artifacts section but maybe something is missing.
How can i tell the publishing task to include publishing of the groovydocs jar?
Gradle version is 6.8.3, jvm version is 1.8 and i depend on `compile 'org.codehaus.groovy:groovy-all:3.0.7'`
The complete build script is available here:
https://github.com/perNyfelt/ProjectDeployer/blob/main/build.gradle
I figured it out:
That artifacts.archives way was not working.
The syntax for adding the groovy doc is like this:
publishing {
publications {
maven(MavenPublication) {
from components.java
artifact(groovydocJar) {
classifier = 'javadoc'
}
// etc...
}
}
}

Gradle single-project pluginManagement block not working (Kotlin DSL)

I need to change a multi-project build to a single-project build, as there is and only ever will be one project in this repo. Currently, in settings.gradle, I have a custom plugin repo that currently uses a pluginManagement block with resolutionStrategy and my list of repo's:
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'com.meanwhileinhell.plugin') {
useModule('com.meanwhileinhell:gradle-plugin:1.0.0-SNAPSHOT')
}
}
}
repositories {
mavenLocal()
maven { url "https://repo.spring.io/milestone" }
maven { url "https://plugins.gradle.org/m2/" }
// Meanwhileinhell repo
maven {
url "s3://mvn.meanwhileinhell.com/releases"
credentials(AwsCredentials) {
accessKey s3_access_key
secretKey s3_access_secret
}
}
}
plugins {
...
...
}
}
However, deleting settings.gradle and moving this block into my build.gradle.kts (Kotlin DSL) seems to do nothing. I've tried wrapping in a
configurations {
all {
resolutionStrategy {
eachPlugin {
...
}
}
}
}
and also
settings {
pluginManagement {
resolutionStrategy {
eachPlugin {
...
}
}
}
}
I found a SO answer that used settingsEvaluated in order to get the settings object, but again this was a no go.
Currently my build.gradle.kts looks like this, without pulling any plugin in from my repo:
val springBootVersion: String by project
group = "com.meanwhileinhell.myapp"
version = "$version"
repositories {
mavenCentral()
mavenLocal()
maven ("https://repo.spring.io/snapshot")
maven ("https://repo.spring.io/milestone")
maven ("https://plugins.gradle.org/m2/")
maven {
url = uri("s3://mvn.meanwhileinhell.com/releases")
credentials(AwsCredentials::class) {
accessKey = (project.property("s3_access_key") as String)
secretKey = (project.property("s3_access_secret") as String)
}
}
}
plugins {
base
eclipse
idea
java
id("io.spring.dependency-management") version "1.0.9.RELEASE"
// Load but don't apply to root project
id("org.springframework.boot") version "1.5.14.RELEASE" apply false
}
dependencies {
...
}
Whenever I try to add a plugin id like id("com.meanwhileinhell.plugin.hell2java") version "1.0.0-SNAPSHOT" I get an error that looks like it isn't even looking in my S3 location:
* What went wrong:
Plugin [id: 'com.meanwhileinhell.plugin.hell2java', version: '1.0.0-SNAPSHOT'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'com.meanwhileinhell.plugin.hell2java:com.meanwhileinhell.plugin.hell2java.gradle.plugin:1.0.0-SNAPSHOT')
Searched in the following repositories:
Gradle Central Plugin Repository
Any help on this would be appreciated!
EDIT !!!! -----------------------
I've just found this in the Gradle docs:
https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management
The pluginManagement {} block may only appear in either the settings.gradle file....
Looks like I'm going down the wrong way entirely, so will look into the initialisation script route.
I think you may have missed something about the file structure.
In the Groovy DSL, you have the following files:
build.gradle
settings.gradle
init.gradle
In the Kotlin DSL, you have the same files but with the .kts extension:
build.gradle.kts
settings.gradle.kts
init.gradle.kts
The Kotlin DSL doesn't differ to the Groovy DSL in where to put things. pluginManagement need to go in to the settings file, so for Kotlin that would be settings.gradle.kts. If you are in doubt, look at the documentation. For almost all code examples, you can switch between Groovy and Kotlin DSL to see how to do it (and which files they are supposed go to into).

Generate local maven repository with all dependencies using Gradle

What I currently have
dependencies {
compile ...
}
task copyDependencies(type:Copy) {
from configurations.compile
into 'build/dependencies/'
}
This task copies all the required dependencies to the build/dependencies/ directory. Inside the directory, it looks as follows:
/dep1-1.0.jar
/dep2-1.0.aar
...
So essentially what is known as flatDir in gradle terms.
What I'd like to have
It's a local maven repository with all these dependencies, instead of a flatDir.
If I understand your question correctly, you just want to publish to a local directory as if it were mavenLocal() but in a location you specify.
In that case, I believe you just need:
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url "/path/to/wherever"
}
}
}
See the Maven Publish plugin docs

How to exclude dependencies in the POM file generated by the Gradle

I'm using the "maven" plugin to upload the artifacts created by Gradle build to Maven central repository. I'm using a task similar to the following one:
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
pom.project {
name 'Example Application'
packaging 'jar'
url 'http://www.example.com/example-application'
scm {
connection 'scm:svn:http://foo.googlecode.com/svn/trunk/'
url 'http://foo.googlecode.com/svn/trunk/'
}
licenses {
license {
name 'The Apache License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
}
}
}
}
However the POM file created by this task does not report correctly the dependencies that have been excluded in my Gradle build file. For example:
dependencies {
compile('org.eclipse.jgit:org.eclipse.jgit.java7:3.5.2.201411120430-r') { exclude module: 'commons-logging' }
compile('com.upplication:s3fs:0.2.8') { exclude module: 'commons-logging' }
}
How to have excluded dependencies managed correctly in the resulting POM file?
You can simply override the dependencies of the pom by filtering out the unwanted dependencies, e.g. to exclude junit you can add the following lines to the mavenDeployer configuration:
pom.whenConfigured {
p -> p.dependencies = p.dependencies.findAll {
dep -> dep.artifactId != "junit"
}
}
The problem was that in the exclude definition was not specified the group but only the module.
Adding the both of them the exclusions are added correctly in the POM file. For example:
compile('org.eclipse.jgit:org.eclipse.jgit.java7:3.5.2.201411120430-r') {
exclude group: 'commons-logging', module: 'commons-logging'
}
compile('com.upplication:s3fs:0.2.8') {
exclude group: 'commons-logging', module: 'commons-logging'
}
Using 'exclude' on a Gradle dependency is normally the correct answer, but I still needed to remove some of my "runtimeOnly" dependencies from the POM that led me to this StackOverflow page. My testing using Gradle 4.7 seems to show that using "compileOnly" leaves the dependency out of the pom entirely, but "runtimeOnly" adds a "runtime" dependency in the pom, which in my case, is not what I wanted. I couldn't figure out a "standard" Gradle way of leaving runtime dependencies out of the POM.
The pom.whenConfigured method shown in another answer works for legacy "maven" plugin publishing, but doesn't work for the newer "maven-publish" plugin. My experimentation led to this for "maven-publish":
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom.withXml {
asNode().dependencies.dependency.each { dep ->
if(dep.artifactId.last().value().last() in ["log4j", "slf4j-log4j12"]) {
assert dep.parent().remove(dep)
}
}
}
}
}
}

Why do we need repositories/dependencies in buildscript task for gradle

In the post Using gradle/clojuresq to build clojure, and the answer https://stackoverflow.com/a/29018574/260127, there are (or seems) duplication of repositories and dependencies.
Why is this? Why do we need another set with the same setup?
buildscript { <- first
repositories {
maven { url "http://clojars.org/repo" }
mavenCentral()
}
dependencies {
classpath "clojuresque:clojuresque:1.7.0"
}
}
...
-> Same set again!
repositories {
maven { url "http://clojars.org/repo" }
mavenCentral()
}
dependencies {
compile "org.clojure:clojure:1.6.0"
}
...
The first is a dependency required for the build script itself. The dependency you are declaring in this case is clojuresque, which contains the Clojure Gradle plugin (apply plugin: 'clojure'). The second is the dependencies for you project, in this case, the Clojure library itself.
Simply, the first is needed by Gradle, the second by your code.

Resources