Getting the pom for a dependency in Gradle - gradle

In resolving a dependency from a Maven-repository, Gradle has to download the corresponding pom-file. I would like to access this file from within the Gradle-script and save it somewhere. How can I do this?

Take a look at Artifact Query API. Here is the sample code (Groovy):
def componentIds = configurations.compileClasspath.incoming.resolutionResult.allDependencies.collect { it.selected.id }
def result = project.dependencies.createArtifactResolutionQuery()
.forComponents(componentIds)
.withArtifacts(MavenModule, MavenPomArtifact)
.execute()
for (component in result.resolvedComponents) {
component.getArtifacts(MavenPomArtifact).each { println "POM file for ${component.id}: ${it.file}" }
}
I'm using the same API in my plugin in Kotlin.

You could simply declare a dependency on the POM itself.
configurations {
pom
}
dependencies {
pom 'org.foo:some-lib:1.0.0#pom'
}
task copyPom(type: Copy) {
into "${buildDir}/poms"
from configurations.pom
}

Related

gradle publish custom pom

I have written a gradle task which writes a custom pom to "build/libs/pom.xml"
I want to publish above custom pom.xml , so I defined :
def pomXml = artifacts.add('archives', file("$buildDir/libs/pom.xml")) {
builtBy('writePoms') // writePoms is my custom task to create custom pom.xml
}
publishing {
publications {
maven(MavenPublication) {
artifact pomXml
artifactId "myartifact"
groupId 'com.xyz'
version project.version
}
}
repositories {
// Task for manually publishing the maven image. When CI works, setup CI_TOKEN auth.
maven {
url <url>
name "GitLab"
credentials(HttpHeaderCredentials) {
name = System.getenv("CI_JOB_TOKEN") ? "Job-Token" : "Private-Token"
value = System.getenv("CI_JOB_TOKEN") ? System.getenv("CI_JOB_TOKEN") : gitLabPrivateToken
}
authentication {
header(HttpHeaderAuthentication)
}
}
}
When I run ./gradlew publish it publishes pom from "build/publications/maven/pom-default.xml" instead of "build/libs/pom.xml"
Can someone help how can I achieve it?
I had a similar issue (aggregate build of multiple external repositories with their own build systems and then publishing the results of those builds to a local artifactory).
I was able to effectively replace the generated POM for the "artifacts" publication with the content of an external POM via withXml:
pluginManager.withPlugin("maven-publish") {
extensions.configure(PublishingExtension::class.java) {
publications.register<MavenPublication>("artifacts") {
groupId = "com.example"
artifactId = "external"
version = "1.0.0"
artifact("external.jar")
pom.withXml {
asNode().setValue(XmlParser().parse("some/external/pom.xml").value())
}
}
}
}
This leaves the <xml ...> and <project ...> nodes intact (acceptable for my case).

Gradle 7.2 Version Catalog specify library build type

I'm refactoring a multi module project with version catalogs and I have to add a dependency that is currently like this:
implementation com.mygroup:my-artifact:1.0.0:debug#aar
Since version catalogs doesn't allow to specify the aar type, a workaround would be to specify it directly in the gradle file like this:
implementation(libs.myDependency) { artifact { type = 'aar' } }
This works, but there's an extra complexity: I need to also specify the build type, in the example from above is debug, I cannot find a way to add it.
What I've tried is:
TOML
[libraries]
myDependency = { module = "com.mygroup:my-artifact", version = "1.0.0:debug" }
Gradle
implementation(libs.myDependency) { artifact { type = 'aar' } }
For some reason this doesn't work, how can I also specify the build type?
Found a way to do this! Need to add the classifier into the artifact.
So for the given regular declaration:
build.gradle
dependencies {
implementation com.mygroup:my-artifact:1.0.0:debug#aar
}
The version catalogs way would be:
TOML
[libraries]
myDependency = { module = "com.mygroup:my-artifact", version = "1.0.0" }
build.gradle
dependencies {
implementation(libs.myDependency) { artifact { classifier = 'debug'; type = 'aar' } }
}
or (multiline)
build.gradle
dependencies {
implementation(libs.myDependency) {
artifact {
classifier = 'debug'
type = 'aar'
}
}
}

Gradle dependency resolution strategy with maven deployer

I am working on an android project. We are using the DependencyResoultionStrategy to swap some dependency versions. The code looks like this:
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
final version = getVersionForDependency(project, details.requested.group, details.requested.name)
if (version != null) {
details.useVersion(version)
}
}
So for example, the project requests the dependency group:name:1.1.2 but it is swapped so the dependency group:name:1.2.0 is used. This works perfectly and the project is built with the right dependency (the second one).
We also have a publish task, which deploys the project to a local maven repository. We use the maven plugin for this, the code looks like this:
apply plugin: 'maven'
task publish(dependsOn: uploadArchives)
uploadArchives {
configurations {
deployerFTP
}
repositories {
mavenDeployer {
configuration = configurations.deployerFTP
repository(URL) {
authentication(USERNAME, PASSWORD)
}
}
}
dependencies {
deployerFTP "org.apache.maven.wagon:wagon-ftp:2.4"
}
}
The problem is, if I publish the library, in the resulting .pom file, the dependency group:name:1.1.2 is entered, not the one which is actually used. How can I change this behavior, so the pom contains the right dependency?
I have found an answer, simply add this code block:
mavenDeployer {
// ...
pom.whenConfigured { pom ->
pom.dependencies = pom.dependencies.collect { dep ->
def version = getVersionForDependency(project, dep.groupId, dep.artifactId)
if (version != null) {
dep.version = version
}
return dep
}
}
}

Creating a maven wrapper pom.xml from gradle: can't create the <build> element

How do I set the sourceDirectory, testSourceDirectory and build plugins in a pom.xml that I'm creating using the gradle maven-plugin's pom DSL?
When I add build without a Closure to my DSL section, it's ok.. but when I add build { /* anything else, like actual compile plugins */} it gives me this error:
Execution failed for task ':mavenWrapper'.
> No such property: _SCRIPT_CLASS_NAME_ for class: org.apache.maven.model.Model
I'm guessing that gradle is treating build as the task rather than the DSL verb generated by org.sonatype.maven.polyglot.groovy.builder.ModelBuilder.
Is there a way to force build to be treated as part of the DSL? Can it be cast or something?
Right now I'm working around this by using .withXml but it's massively verbose and much less maintainable.
Here's an abbreviated version of what I've got working:
task mavenWrapper {
doLast {
delete 'pom.xml', 'mvnw', 'mvnw.cmd'
pom {
project {
packaging 'pom'
repositories {
repository {
id 'spring-milestones'
name 'Spring Milestones'
url 'https://repo.spring.io/libs-milestone'
snapshots {
enabled 'false'
}
}
}
properties {
'kotlin.compiler.incremental' 'true'
}
/* ******** Problem is here
build {
plugins {
plugin {
// ... etc. etc.
}
}
}
******* */
dependencyManagement {
dependencies {
dependency {
groupId 'org.jetbrains.kotlin'
artifactId 'kotlin-stdlib-jre8'
version "${kotlin_version}"
scope 'compile'
}
}
}
}
}.withXml {
// Workaround for the missing build { ... } section above.
asNode().appendNode('build').appendNode('plugins')
// etc. etc.
}.writeTo("${projectDir}/pom.xml")
exec {
commandLine 'mvn', '-N', 'io.takari:maven:wrapper', '-Dmaven=3.5.0'
}
}
}

Gradle - generate pom without dependencies

I want to generate a pom file that does not include dependencies. I have tried clearing the dependencies using the code below, however the dependencies are still listed in the generated pom.
install.doFirst {
repositories.mavenInstaller {
pom.dependencies.clear()
}
}
Why I need this: I need a pom file to be included with my jar when I upload it to a "home brewed" service, however the service blows up when it reads '+' as the version for the dependencies (I am using dynamic dependencies).
uploadArchives {
repositories {
mavenDeployer {
// Do not write any dependencies into the POM
pom*.whenConfigured { pom -> pom.dependencies.clear() }
}
}
}
I ended up using the solution below calling gradle cleanPom. Basically I use an XML parser to edit the generated POM.
apply plugin: 'maven'
pomFileLocation="build/poms/noDeps.pom"
/**
* Creates pom with dependencies
*/
task writeNewPom << {
pom {}.writeTo(pomFileLocation)
}
/**
* Reads and Overwrites POM file removing dependencies
*/
task cleanPom(dependsOn: writeNewPom) << {
def xml = new XmlParser().parse(pomFileLocation)
def nodes = []
xml.dependencies[0].each {
nodes.add(it)
}
def parrent = nodes.first().parent()
nodes.each {
parrent.remove(it)
}
new XmlNodePrinter(new PrintWriter(new FileWriter(pomFileLocation))).print(xml)
}

Resources