Trouble injecting the build block while exporting a Maven pom.xml file from gradle - maven

task writeNewPom {
pom {
project {
/*
build {
plugins {
plugin {
groupId 'GROUP_ID'
artifactId 'maven-ipcentral-plugin'
version '4.7'
executions {}
configuration {
url "http://CENTRAL_REPORTING_SERVER"
logfileprefix "test"
ipcProject = true
businessUnit "FOUR_DIGIT_CODE"
componentEditorsGrouper "ccp-dev"
assetEditorsGrouper "ccp-dev"
username "USERNAME"
}
}
}
}
*/
pluginRepositories {
pluginRepository {
id 'ipcentral-snapshots'
name 'IPCentral Snapshot Repository'
url 'http://PLUGIN_SOURCE/'
snapshots {
enabled = false
}
releases {
enabled = true
}
}
}
profiles {
profile {
id 'inject-cec-credentials'
activation {
activeByDefault = true
}
properties {
username = "USERNAME"
}
}
}
}
}.writeTo("ipcentral/pom.xml")
}
I am attempting to create a pom.xml file using the gradle maven plugin. It must reference a maven plugin designed for central dependency reporting. As it is right now it successfully creates the pom.xml file containing all dependencies, plugin repository info, and profile info. However if the build section is un-commented the I get an error along the lines of:
> No such property: _SCRIPT_CLASS_NAME_ for class: org.apache.maven.model.
If I try something simple like
task writeNewPom {
pom {
project {
build {
}
}
}
}
then I get the same error. It seems that gradle does not recognize build as a valid identifier. I am just hoping for a more elegant solution than manually editing xml through groovy. The only documentation on this that I can find is Gradle docs Chap 53

This is due to the fact that the project {...} closure is delegating to an instance of ModelBuilder which extends Groovy's FactoryBuilderSupport class that already defines a method named build. So instead of configuring the build property of the Maven Model object, the preexisting build method is being called.
To get around this I'd use withXml {...} to configure that portion of your pom.
pom {
project {
// other non-<build> configuration
}
}.withXml {
asNode().appendNode('build').appendNode('plugins').appendNode('plugin').with {
appendNode('groupId', 'GROUP_ID')
}
}.writeTo('pom.xml')

Here is a more detailed example:
.withXml
{
asNode().appendNode('build').appendNode('plugins').with
{
with
{
appendNode('plugin')
.with
{
appendNode('groupId', 'groupId1')
appendNode('artifactId', 'artifactId1')
appendNode('version', 'version1')
}
}
with
{
appendNode('plugin')
.with{
appendNode('groupId', 'groupId2')
appendNode('artifactId', 'artifactId2')
appendNode('version', 'version2')
}
}
}
}
.writeTo("pom.xml")

Related

How to access PlaginManager repositories from custom gradle plugin

My problem is that I develop a custom Gradle plugin and I need to get access to repositories which belongs to Settings object, particular PluginManagement object.
settings.gradle file of project which I connect my custom plugin looks like this:
pluginManagement {
resolutionStrategy {
}
repositories {
maven {
credentials {
username = System.getenv("USERNAME")
password = System.getenv("PASSWORD")
}
url = uri("${System.getenv("nexusUrl")}/repository/***")
}
}
}
There is my code I want to just list url of all repositories:
project.afterEvaluate {
val gradle = project.rootProject.gradle as org.gradle.invocation.DefaultGradle
val settings = gradle.settings as org.gradle.initialization.DefaultSettings
settings.pluginManagement.repositories.forEach { repo ->
run {
repo as MavenArtifactRepository
println(repo.url)
}
}
}
I expect the following output result:
https://nexus_url/repository/***
But instead I get 'null' in output.
But when I run this code from custom task I get expected result:
tasks.create("abc") {
project.afterEvaluate {
val gradle = project.rootProject.gradle as org.gradle.invocation.DefaultGradle
val settings = gradle.settings as org.gradle.initialization.DefaultSettings
settings.pluginManagement.repositories.forEach { repo ->
run {
repo as MavenArtifactRepository
println(repo.url)
}
}
}
}
Why are in execution time this repositories not empty and what is the best way to access them from Project object?

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'
}
}
}

Custom publication plugin in gradle

I'd like to implement custom publication plugin for gradle.
My goal is to support syntax like this:
publishing {
publications {
custom(CustomPublication) {
artifact fooDistZip
artifact foo2DistZip
}
}
repositories {
custom {
url 'http://192.168.1.100:80'
}
}
}
I've checked the MavenPublication, but the implementation seems to be rather complicated.
Any reference for simple custom publisher in gradle would be much appreciated.
Sounds like you'll want to create a CustomPublisher that extends the Publisher thats consumed by a PublicationContainer
Update:
I’ve added a code snippet from gradles documentation about configuration of the upload task
repositories {
flatDir {
name "fileRepo"
dirs "repo"
}
}
uploadArchives {
repositories {
add project.repositories.fileRepo
ivy {
credentials {
username "username"
password "pw"
}
url "http://repo.mycompany.com"
}
}
}

Using Gradle to build a jar with dependencies with Kotlin-DSL

There is already an answer to the question: how to include all the dependencies in a jar file though it's for Groovy
I'm using gradle with kotlin-dsl and the code is not compatible. I tried to make it work using a few ways including:
tasks.withType<Jar> {
configurations["compileClasspath"].forEach { file: File ->
copy {
from(zipTree(file.absoluteFile))
}
}
}
Though this doesn't work. So how to include the dependencies using kotlin-dsl in gradle?
This will work:
tasks.withType<Jar>() {
configurations["compileClasspath"].forEach { file: File ->
from(zipTree(file.absoluteFile))
}
}
There's no need in copy { ... }, you should call from on the JAR task itself.
Note: Gradle does not allow changing the dependencies after they have been resolved. It means that the block above should be executed only after the dependencies { ... } are configured.
my case
withType<Jar> {
enabled = true
isZip64 = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveFileName.set("$project.jar")
from(sourceSets.main.get().output)
dependsOn(configurations.compileClasspath)
from({
configurations.compileClasspath.get().filter {
it.name.endsWith("jar")
}.map { zipTree(it) }
}) {
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
}
}

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'
}
}
}

Resources